Удаление вложенных циклов в NumPy - PullRequest
2 голосов
/ 11 июля 2011

Я писал программу для грубой силы, проверяющую последовательность чисел для поиска кубов Эйлера, но метод, который я придумал, включает в себя тройной цикл. Поскольку вложенные циклы Python становятся очень медленными, мне было интересно, есть ли лучший способ использовать numpy для создания нужного мне массива значений.

#x=max side length of brick. User Input.    
for t in range(3,x):
    a=[];b=[];c=[];
    for u in range(2,t):
        for v in range(1,u):
                a.append(t)
                b.append(u)
                c.append(v)
    a=np.array(a)
    b=np.array(b)
    c=np.array(c)
    ...

Есть ли лучший способ для создания массива значений af с помощью команд numpy?

Спасибо.

Пример: Если х = 10, то при т = 3 я хочу получить:

a=[3]  
b=[2]     
c=[1]

первый раз через цикл. После этого, когда t = 4:

a=[4, 4, 4]
b=[2, 3, 3]
c=[1, 1, 2]

В третий раз (t = 5) я хочу:

a=[5, 5, 5, 5, 5, 5]
b=[2, 3, 3, 4, 4, 4]
c=[1, 1, 2, 1, 2, 3]

и т. Д., Вплоть до максимальной длины стороны около 5000 или около того.

РЕДАКТИРОВАТЬ: Решение

a=array(3)
b=array(2)
c=array(1)
for i in range(4,x): #Removing the (3,2,1) check from code does not affect results.
    foo=arange(1,i-1)
    foo2=empty(len(foo))
    foo2.fill(i-1)
    c=hstack((c,foo))
    b=hstack((b,foo2))
    a=empty(len(b))
    a.fill(i)
    ...

Теперь работает во много раз быстрее. Спасибо всем.

Ответы [ 2 ]

2 голосов
/ 11 июля 2011

Попробуйте использовать .empty и .fill (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.fill.html)

1 голос
/ 11 июля 2011

Есть пара вещей, которые могут помочь, но, вероятно, только для больших значений x.Для начала используйте xrange вместо range, это сохранит создание списка, который вам никогда не понадобится.Вы также можете создавать пустые массивы numpy правильной длины и заполнять их значениями по мере необходимости, вместо добавления в список и последующего преобразования его в массив numpy.в этот момент нет доступа к Python):

for t in xrange(3, x):
    size = (t - 2) * (t - 3)
    a = np.zeros(size)
    b = np.zeros(size)
    c = np.zeros(size)

    idx = 0
    for u in xrange(2,t):
        for v in xrange(1,u):
            a[idx] = t
            b[idx] = u
            c[idx] = v
            idx += 1
...