如何在 Python 指针中有效地迭代数组?
Posted
技术标签:
【中文标题】如何在 Python 指针中有效地迭代数组?【英文标题】:How to iterate an array in Python pointer-likely and efficiently? 【发布时间】:2015-07-18 02:57:11 【问题描述】:我是 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
【问题讨论】:
你知道如何在 Python 中创建列表吗?您可以使用其append
方法附加到它,并将最后两个元素作为l[-1]
和l[-2]
。
您需要快速插入吗?也就是说,您是否特别需要链表结构?还是可以接受动态数组(连续内存)?如果你主要是迭代而不是插入(或者你所有的插入都在最后),那么 Python 的内置列表对象将是要走的路。
可以预分配底层数组:L = 10 * [0]; L[0] = L[1] = 1
如果列表原本是固定大小的怎么办?
这个 SO 中有很多 Python 选项,包括基于列表的选项。不过没有人使用指针:***.com/questions/494594/…
【参考方案1】:
直接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 代码,并且结果是缓冲的,因此执行快速顺序操作很棘手。最好考虑一下 numpy 操作同时在数组的所有项上并行执行(不考虑任何顺序)。例外是 ufunc
cumsum
和 cumprod
- 累积进程,以及称为 at
的无缓冲 ufunc
。我必须四处看看是否有办法使用这些工具之一来计算这个系列。
另一种选择是在 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 数组或 memoryview 中的 Cython/c 版本应该不难。
这是一个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
【讨论】:
非常感谢!这正是我想知道的。 我发现了一些其他的想法。以上是关于如何在 Python 指针中有效地迭代数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在python 3中有效地将原始字节写入numpy数组数据