AFo*_*lia 54 python loops numpy
是否有函数在numpy数组的任意维度上获取迭代器?
迭代第一维很容易......
In [63]: c = numpy.arange(24).reshape(2,3,4)
In [64]: for r in c :
....: print r
....:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
Run Code Online (Sandbox Code Playgroud)
但迭代其他维度更难.例如,最后一个维度:
In [73]: for r in c.swapaxes(2,0).swapaxes(1,2) :
....: print r
....:
[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]
Run Code Online (Sandbox Code Playgroud)
我自己做了一个生成器,但我很惊讶没有像numpy.ndarray.iterdim(axis = 0)这样的函数自动执行此操作.
Eri*_*got 50
你提出的建议是相当快的,但更清晰的形式可以提高易读性:
for i in range(c.shape[-1]):
print c[:,:,i]
Run Code Online (Sandbox Code Playgroud)
或者,更好(更快,更通用,更明确):
for i in range(c.shape[-1]):
print c[...,i]
Run Code Online (Sandbox Code Playgroud)
但是,上面的第一种方法看起来似乎是该swapaxes()方法的两倍:
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
'for r in c.swapaxes(2,0).swapaxes(1,2): u = r'
100000 loops, best of 3: 3.69 usec per loop
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
'for i in range(c.shape[-1]): u = c[:,:,i]'
100000 loops, best of 3: 6.08 usec per loop
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
'for r in numpy.rollaxis(c, 2): u = r'
100000 loops, best of 3: 6.46 usec per loop
Run Code Online (Sandbox Code Playgroud)
我猜这是因为swapaxes()不复制任何数据,并且因为处理c[:,:,i] 可能是通过通用代码完成的(处理:由更复杂的切片替换的情况).
但请注意,更明确的第二个解决方案c[...,i]既清晰又快速:
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \
'for i in range(c.shape[-1]): u = c[...,i]'
100000 loops, best of 3: 4.74 usec per loop
Run Code Online (Sandbox Code Playgroud)
Ery*_*Sun 26
我使用以下内容:
c = numpy.arange(2 * 3 * 4)
c.shape = (2, 3, 4)
for r in numpy.rollaxis(c, 2):
print(r)
Run Code Online (Sandbox Code Playgroud)
功能rollaxis在阵列上创建一个新视图.在这种情况下,它将轴2移动到前面,相当于操作c.transpose(2, 0, 1).
因此,正如您所示,可以轻松地迭代第一维.对任意维度执行此操作的另一种方法是使用numpy.rollaxis()将给定维度带到第一个(默认行为),然后使用返回的数组(这是一个视图,因此这很快)作为迭代器.
In [1]: array = numpy.arange(24).reshape(2,3,4)
In [2]: for array_slice in np.rollaxis(array, 1):
....: print array_slice.shape
....:
(2, 4)
(2, 4)
(2, 4)
Run Code Online (Sandbox Code Playgroud)
编辑:我会评论我提交了一个PR到numpy来解决这个问题:https: //github.com/numpy/numpy/pull/3262.一致认为,这还不足以增加numpy代码库.我认为使用np.rollaxis是最好的方法,如果你想要一个interator,请将它包装在iter()中.
估计是没有功能。当我编写函数时,我最终采用了也建议的迭代 EOL。对于未来的读者,这里是:
def iterdim(a, axis=0) :
a = numpy.asarray(a);
leading_indices = (slice(None),)*axis
for i in xrange(a.shape[axis]) :
yield a[leading_indices+(i,)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
39808 次 |
| 最近记录: |