python - 对 'N' 维 numpy 数组的操作

标签 python arrays numpy slice

我正在尝试概括一些 Python 代码以对任意维度的数组进行操作。这些运算应用于数组中的每个向量。因此,对于一维数组,只有一个操作,对于二维数组,它既是行操作又是列操作(线性的,所以顺序并不重要)。例如,一维数组 (a) 很简单:

b = operation(a)

其中“操作”需要一维数组。对于二维数组,操作可能如下进行

for ii in range(0,a.shape[0]):
    b[ii,:] = operation(a[ii,:])
for jj in range(0,b.shape[1]):
    c[:,ii] = operation(b[:,ii])

我想让这个通用化,我不需要事先知道数组的维度,也不需要为每个可能的维度设置大量的 if/elif 语句。 对于 1 维或 2 维通用的解决方案是可以的,但完全通用的解决方案将是首选。事实上,我不认为任何高于 2 的维度都需要这个,但如果我能看到一个一般的例子,我会学到一些东西!

额外信息: 我有一个 matlab 代码,它使用单元格来做类似的事情,但我不完全理解它是如何工作的。在这个例子中,每个向量都被重新排列(基本上与 numpy.fft 中的 fftshift 功能相同)。不确定这是否有帮助,但它对任意维度的数组进行操作。

function aout=foldfft(ain)
nd = ndims(ain);
for k = 1:nd
    nx = size(ain,k);
    kx = floor(nx/2);
    idx{k} = [kx:nx 1:kx-1];
end
aout = ain(idx{:});

最佳答案

在 Octave 中,您的 MATLAB 代码执行以下操作:

octave:19> size(ain)
ans =
   2   3   4
octave:20> idx
idx = 
{
  [1,1] =
     1   2
  [1,2] =
     1   2   3
  [1,3] =
     2   3   4   1
}

然后它使用idx元胞数组来索引ain。使用这些尺寸,它会“滚动”4 号尺寸。

对于 5 和 6,索引列表为:

 2   3   4   5   1
 3   4   5   6   1   2

numpy 中的等价物是:

In [161]: ain=np.arange(2*3*4).reshape(2,3,4)
In [162]: idx=np.ix_([0,1],[0,1,2],[1,2,3,0])
In [163]: idx
Out[163]: 
(array([[[0]],

        [[1]]]), array([[[0],
         [1],
         [2]]]), array([[[1, 2, 3, 0]]]))
In [164]: ain[idx]
Out[164]: 
array([[[ 1,  2,  3,  0],
        [ 5,  6,  7,  4],
        [ 9, 10, 11,  8]],

       [[13, 14, 15, 12],
        [17, 18, 19, 16],
        [21, 22, 23, 20]]])

除了基于 0 的索引之外,我还使用 np.ix_ 来 reshape 索引。 MATLAB 和 numpy 使用不同的语法来索引值 block 。

下一步是用代码构造[0,1],[0,1,2],[1,2,3,0],这是一个直接的翻译。

我可以使用 np.r_ 作为将 2 个切片转换为索引数组的快捷方式:

In [201]: idx=[]
In [202]: for nx in ain.shape:
    kx = int(np.floor(nx/2.))
    kx = kx-1;
    idx.append(np.r_[kx:nx, 0:kx])
   .....:     
In [203]: idx
Out[203]: [array([0, 1]), array([0, 1, 2]), array([1, 2, 3, 0])]

并将其传递给np.ix_以创建适当的索引元组:

In [204]: ain[np.ix_(*idx)]
Out[204]: 
array([[[ 1,  2,  3,  0],
        [ 5,  6,  7,  4],
        [ 9, 10, 11,  8]],

       [[13, 14, 15, 12],
        [17, 18, 19, 16],
        [21, 22, 23, 20]]])

在这种情况下,二维不滚动任何东西,slice(None) 可以替换它们:

In [210]: idx=(slice(None),slice(None),[1,2,3,0])
In [211]: ain[idx]

======================

np.roll 的作用:

indexes = concatenate((arange(n - shift, n), arange(n - shift)))
res = a.take(indexes, axis)

np.apply_along_axis 是另一个构造索引数组(并将其转换为索引元组)的函数。

关于python - 对 'N' 维 numpy 数组的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34005494/

相关文章:

python - 在 Pandas 中使用 .loc 会减慢计算速度

javascript - 获取数组中唯一序列的最短方法

C清除 double 数组的最佳方法

python - 来自 csv 的 Keras 文本分类自定义数据集

python - 尝试为 python 2.7.11 安装 mathplot.lib。但找不到合适的流程。尝试了Youtube教程中的各种方法,但没有成功

python - 如何将 ndarray 字符串列表转换为 float

python - 正确保存 numpy 数组

python - Pandas 在 2 个给定数字之间进行插值,给定步长并在 groupby 内

php - 按日期列对多维数组进行排序,如果日期相同,则使用其他列值

python - python 正确从文本文件中读取多个列表