我正在初始化一个numpy数组,然后在某个任意位置插入循环值; 由于某种原因,似乎使用双括号进行索引的速度实际上是使用逗号表示法编制索引的两倍.
编辑:根据Mike的回答,我想了解多维索引如何作为单个操作实现,以及是否有使用第一个表示法的要点.
import numpy as np x = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5]]) def access(arr): for i in range(1000): arr[1][2] = i def access2(arr): for i in range(1000): arr[1,2] = i t1 = Timer('access(x)', 'from __main__ import access, x') print(t1.timeit(number = 1000)) 0.425940990448 t2 = Timer('access2(x)', 'from __main__ import access2, x') print(t2.timeit(number = 1000)) 0.217132806778
Mike Müller.. 5
这个:
nparray[i][j]
意味着两个索引操作.
这基本上是发生的事情:
tmp = nparray[i] tmp[j]
因此,您创建了一个tmp
以后不再需要的中间数组.这是额外的工作.
这个:
nparray[i, j]
只是一个索引操作.NumPy使用此方法更有效,因为它不需要在此创建任何中间数组.
这就是你做的事情nparray[i, j]
.该类ndarray
重写了特殊方法__getitem__
和 __setitem__
.例如:
>>> class A: ... def __getitem__(self, indices): ... print(indices) ... def __setitem__(self, indices, value): ... print(indices, value) ... >>> a = A() >>> a[1, 2] (1, 2) >>> a[1, 2] = 23 (1, 2) 23
你可以看到1, 2
in [1, 2]
作为一个元组到达那里.现在,NumPy可以在适当的情况下处理这些信息.在我们的例子中做一些2D索引.
使用此方法的次数不多:
nparray[i][j]
其中之一可能是当您使用2D结构的列表列表时(也出于某种原因)想要使用NumPy数组作为替代品.虽然速度较慢,但代码可以使用列表列表以及2D NumPy数组.
这个:
nparray[i][j]
意味着两个索引操作.
这基本上是发生的事情:
tmp = nparray[i] tmp[j]
因此,您创建了一个tmp
以后不再需要的中间数组.这是额外的工作.
这个:
nparray[i, j]
只是一个索引操作.NumPy使用此方法更有效,因为它不需要在此创建任何中间数组.
这就是你做的事情nparray[i, j]
.该类ndarray
重写了特殊方法__getitem__
和 __setitem__
.例如:
>>> class A: ... def __getitem__(self, indices): ... print(indices) ... def __setitem__(self, indices, value): ... print(indices, value) ... >>> a = A() >>> a[1, 2] (1, 2) >>> a[1, 2] = 23 (1, 2) 23
你可以看到1, 2
in [1, 2]
作为一个元组到达那里.现在,NumPy可以在适当的情况下处理这些信息.在我们的例子中做一些2D索引.
使用此方法的次数不多:
nparray[i][j]
其中之一可能是当您使用2D结构的列表列表时(也出于某种原因)想要使用NumPy数组作为替代品.虽然速度较慢,但代码可以使用列表列表以及2D NumPy数组.