N维NumPy数组的任意N维重复 [英] Arbitrary N-dimensional repeat of N-dimensional numpy array
问题描述
假设您具有以下 N 维数组
Say you have the following N-dimensional array
>>> import numpy as np
>>> Z = np.array(7*[6*[5*[4*[3*[range(2)]]]]])
>>> Z.ndim
6
请注意, N = 6,但我希望在讨论中保持任意性.
Note that N = 6, but I want to keep it arbitrary in the discussion.
然后,我执行多轴操作-当然主观上- 有问题 折叠"(如有)个维度,可以根据这些维度进行计算.
Then I perform multiple-axis operations which -- of course subjectively -- problematically "collapse" (as described here and there) dimensions along which those are computed.
说计算的轴是
>>> axes = (0,2,5)
因此,元组的长度属于[ 1 , N ].
Thus the tuple's length belongs to [1,N].
您可能已经猜到了,我想制作一个
np.mean
与其输入相同.例如
As you might have guessed, I want to make the shape of the output of a, say,
np.mean
be the same as that of its input. E.g.
>>> Y = np.mean(Z, axis=axes)
>>> Y.shape
(6L, 4L, 3L)
同时
>>> Z.shape
(7L, 6L, 5L, 4L, 3L, 2L)
我有一个自制的解决方案,如下所示
I have a homemade solution, as follows
def nd_repeat(arr, der, axes):
if not isinstance(axes, tuple):
axes = (axes,)
shape = list(arr.shape)
for axis in axes:
shape[axis] = 1
return np.zeros_like(arr) + der.reshape(shape)
偶然地der
代表派生".
>>> nd_repeat(Z, Y, axes).shape
(7L, 6L, 5L, 4L, 3L, 2L)
完成这种N维重复的 numpy内置方式 是什么?
What is the numpy-builtin manner to accomplish this N-dimensional repeat?
性能问题,
import timeit
Performance concerns,
import timeit
homemade_s = """\
nd_repeat(Z, np.nanpercentile(Z, 99.9, axis=axes), axes)
"""
homemade_t = timeit.Timer(homemade_s, "from __main__ import nd_repeat,Z,axes,np").timeit(10000)
npbuiltin_s = """\
np.broadcast_to(np.nanpercentile(Z, 99.9, axis=axes, keepdims=True), Z.shape)
"""
npbuiltin_t = timeit.Timer(npbuiltin_s, "from __main__ import Z,axes,np").timeit(10000)
可以预见
>>> np.log(homemade_t/npbuiltin_t)
0.024082885343423521
我的解决方案比hpaulj的解决方案慢约2.5%.
my solution is ~2.5% slower than hpaulj's.
推荐答案
mean
具有一个keepdims
参数,该参数保留压缩尺寸:
mean
has a keepdims
parameter the retains the compressed dimension:
In [139]: shape=(2,3,4,5)
In [140]: x=np.arange(np.prod(shape)).reshape(shape)
In [141]: m=x.mean(axis=2, keepdims=True)
In [142]: m.shape
Out[142]: (2, 3, 1, 5)
现在很容易沿该维度复制m
:
It's easy now to replicate m
along that dimension:
In [144]: m1=np.broadcast_to(m,shape)
In [145]: m1.shape
Out[145]: (2, 3, 4, 5)
repeat
和tile
也是沿维度复制数组的便捷方法.
repeat
and tile
are also handy means of replicating an array along a dimension.
broadcast_to
只需更改形状和步幅即可扩展数组而无需添加元素:
broadcast_to
expands the array without adding elements, just by changing shape and strides:
In [146]: m1.strides
Out[146]: (120, 40, 0, 8)
repeat
增加数组的大小:
In [148]: m2=np.repeat(m, shape[2], axis=2)
In [149]: m2.shape
Out[149]: (2, 3, 4, 5)
In [150]: m2.strides
Out[150]: (480, 160, 40, 8)
m
可以不使用任何一个,就像x-m
中一样. m
在此处以x
广播.
m
could be used without either, as in x-m
. m
broadcasts with x
here.
这篇关于N维NumPy数组的任意N维重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!