Я новичок в Python, я хотел бы перебрать массив для вычисления следующего элемента на основе предыдущих элементов. Я могу думать об этом в стиле C ++, но как этого добиться в Python, используя Numpy или Pandas? Я знаю, что подобный метод использует сдвиг, но этот путь кажется не очень эффективным.
Ниже приведен простой пример Фибоначчи:
int arr[10];
arr[0] = 1;
arr[1] = 1;
int* pt = &arr[2]; <--get a iterator like a moving pointer
int count = 8;
while (count > 0)
{
*pt = pt[-1] + pt[-2]; <--access previous k element based on current index
count--;
pt++; <--point to next element
}
for (int i = 0; i < 10; i++)
cout << arr[i] << endl;
Список:
L = [1, 1]
while len(L) != 10:
L.append(L[-1] + L[-2]) <--But I have to append element every time
print L
Прямой numpy
имитация вашего C ++
arr=np.ones((10,))
for i in range(2,arr.shape[0]):
arr[i]=arr[i-1]+arr[i-2]
производство:
array([ 1., 1., 2., 3., 5., 8., 13., 21., 34., 55.])
Это, вероятно, не самый эффективный способ сделать это в numpy
, но это начало обсуждения.
Самый быстрый numpy
В операциях используется скомпилированный код c, и результаты буферизируются, поэтому сложно выполнять быстрые последовательные операции. Лучше всего думать о параллельных операциях, выполняемых одновременно на всех терминах массива (без предпочтения какого-либо порядка). Исключения ufunc
cumsum
а также cumprod
— кумулятивные процессы и небуферизованные ufunc
называется at
, Мне пришлось бы поиграть, чтобы увидеть, есть ли способ расчета этой серии с помощью одного из этих инструментов.
Другой вариант — реализовать вычисления на C или C ++ и связать их. cython
это самый удобный инструмент для этого.
http://wiki.scipy.org/Cookbook/Ctypes#head-6a582bd7b101bca0df6e5631a06e2d1d76e35a95
это пример использования ctypes
а также c
код с numpy
рассчитать Фибоначчи.
http://numpy-discussion.10968.n7.nabble.com/vectorizing-recursive-sequences-td35532.html
описывает умный способ вычисления этой серии. Это зависит от ufunc
принимая out
массив. Автор признает, что это также зависит от деталей реализации, тем более что расчет не буферизуется.
arr=np.ones((10,))
np.add(arr[:-2], arr[1:-1], out=arr[2:])
Элементы первых 2-х аргументов добавляются элемент за элементом и сохраняются в out
массив.
arr[2:] = arr[:-2]+arr[1:-1]
не работает из-за буферизации
http://docs.cython.org/src/tutorial/cython_tutorial.html#fibonacci-fun
является примером Cython Фибоначчи. Он должен быть быстрым, но он просто печатает результаты, а не накапливает их в массиве. Тем не менее не должно быть трудностей в создании версии Cython / c, которая сохраняет результаты в массиве Cython или в памяти.
Вот cython
скрипт, который можно сохранить как pyx
, составлено и импортировано. Это может быть улучшено до полезности и скорости, но этого достаточно, чтобы проверить концепцию:
import numpy as np
narr = np.ones((10,), dtype=np.dtype("i"))
cdef int [:] narr_view = narr
cpdef void fib(int[:] arr):
I = arr.shape[0]
for i in range(2,I):
arr[i] = arr[i-2]+arr[i-1]
fib(narr_view)
print 'fib arr:', narr