假设你有以下 N - 维数组
>>> import numpy as np
>>> Z = np.array(7*[6*[5*[4*[3*[range(2)]]]]])
>>> Z.ndim
6
请注意 N = 6,但我想在讨论中保持随意。
<小时/> 然后我执行多轴操作 - 当然主观上 - 有问题 &#34;崩溃&#34; (如here和there所述)维度。
假设计算轴是
>>> axes = (0,2,5)
因此,元组的长度属于[ 1 , N ]。
<小时/> 正如您可能已经猜到的那样,我想使a的输出形状,例如
np.mean
与其输入的形状相同。例如
>>> Y = np.mean(Z, axis=axes)
>>> Y.shape
(6L, 4L, 3L)
,而
>>> Z.shape
(7L, 6L, 5L, 4L, 3L, 2L)
我有一个自制的解决方案,如下
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
代表&#34;派生&#34;。
>>> nd_repeat(Z, Y, axes).shape
(7L, 6L, 5L, 4L, 3L, 2L)
完成此N维重复的 numpy-builtin方式 是什么?
<小时/> 性能问题,
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%。
答案 0 :(得分:0)
mean
有一个keepdims
参数,用于保留压缩维度:
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
:
In [144]: m1=np.broadcast_to(m,shape)
In [145]: m1.shape
Out[145]: (2, 3, 4, 5)
repeat
和tile
也是沿着维度复制数组的便捷方式。
broadcast_to
扩展数组而不添加元素,只需更改形状和步幅:
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
与num + ".";
广播。