N维NumPy数组的任意N维重复 [英] Arbitrary N-dimensional repeat of N-dimensional numpy array

查看:111
本文介绍了N维NumPy数组的任意N维重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您具有以下 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)

repeattile也是沿维度复制数组的便捷方法.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆