所有维度中的python numpy ndarray索引排列(可变维度编号)

所有维度中的python numpy ndarray索引排列(可变维度编号),python,numpy,multidimensional-array,indexing,permutation,Python,Numpy,Multidimensional Array,Indexing,Permutation,“M”是一个numpy ndarray,其中维度“dim”编号是可变的(以前生成的),但每个维度的大小都是相同的“size”。在我的代码中,它更像dim=5,size=7 例如:(尺寸=3,尺寸=4) 我有一个我自己的排列生成器“per”,它生成范围(大小)的特定排列(不是随机排列) 我的需要:变换M,根据我需要的排列移动它的元素。在示例中:21(1个排列用于第一维度,4个排列用于第二维度,16个排列用于第三维度-广义:大小**d表示范围内(dim)的d排列)。我的排列不是随机的,但它们是独立的

“M”是一个numpy ndarray,其中维度“dim”编号是可变的(以前生成的),但每个维度的大小都是相同的“size”。在我的代码中,它更像dim=5,size=7

例如:(尺寸=3,尺寸=4)

我有一个我自己的排列生成器“per”,它生成范围(大小)的特定排列(不是随机排列)

我的需要:变换M,根据我需要的排列移动它的元素。在示例中:21(1个排列用于第一维度,4个排列用于第二维度,16个排列用于第三维度-广义:大小**d表示范围内(dim)的d排列)。我的排列不是随机的,但它们是独立的,彼此不同

结果可能是:

[[[36 39 37 38]
  [33 34 32 35]
  [46 44 45 47]]
  [41 43 40 42]
 [[9  10 11 8]
  [2  1  3  0]
  [6  7  5  4]
  [13 12 14 15]]
 [[56 59 57 58]
  [63 61 62 60]
  [53 54 52 55]
  [51 50 49 48]]
 [[28 30 29 31]
  [27 25 24 26]
  [17 18 16 19]
  [23 21 20 22]]]

在代码保持动态的情况下,如何直接从M as numpy数组执行此操作?

这是一个广播练习:

>>> import numpy as np
>>> from itertools import islice
>>> 
>>> A = np.arange(27).reshape(3,3,3)
>>> def per(n):
...     while True:
...         yield np.random.permutation(n)
... 
>>> pg = per(3)
>>> 
>>> p0 = next(pg)[..., None, None]
>>> p1 = np.array([p for p in islice(pg, 3)])[..., None]
>>> p2 = np.array([[p for p in islice(pg, 3)] for _ in range(3)])
>>> 
>>> p0
array([[[2]],

       [[1]],

       [[0]]])
>>> p1
array([[[1],
        [0],
        [2]],

       [[1],
        [0],
        [2]],

       [[0],
        [2],
        [1]]])
>>> p2
array([[[1, 0, 2],
        [0, 2, 1],
        [0, 1, 2]],

       [[2, 1, 0],
        [1, 2, 0],
        [2, 1, 0]],

       [[1, 2, 0],
        [2, 1, 0],
        [2, 1, 0]]])
>>> A[p0, p1, p2]
array([[[22, 21, 23],
        [18, 20, 19],
        [24, 25, 26]],

       [[14, 13, 12],
        [10, 11,  9],
        [17, 16, 15]],

       [[ 1,  2,  0],
        [ 8,  7,  6],
        [ 5,  4,  3]]])
索恩将军:

import numpy as np
from itertools import islice

def per(n=None):
    while True:
        n = (yield n if n is None else np.random.permutation(n)) or n

def sweep(shp):
    pg = per()
    pg.send(None)
    redshp = len(shp)*[1]
    sz = 1
    for j, k in enumerate(shp):
        pg.send(k)
        redshp[j] = k
        yield np.reshape((*islice(pg, sz),), redshp)
        sz *= k

# example
a = np.arange(24).reshape((2,3,4))
idx = *sweep(a.shape),
for i in idx:
    print(i)
print(a[idx])

多亏了保罗·潘泽的精彩回答,我终于解决了这个问题。 Paul的最后一个答案很好,而且是完全广义的(即使是非平方矩阵!)。 我最初的问题不太一般,因为我的目标是让我的全维排列对平方矩阵起作用。我简化并缩短了代码,所以在这里分享:

import numpy as np
from itertools import islice,count

size,dim = 4,3

per = (np.random.permutation(size) for _ in count())
idx = *(np.reshape((*islice(per, size**d),),[size]*(d+1)+[1]*(dim-d-1)) for d in range(dim)),

a = np.arange(size**dim).reshape((size,)*dim)
print(a[idx])

你所说的“根据我需要的排列方式移动元素”是什么意思?输入数组、输出数组和使用的排列之间的确切关系是什么?如果您看到我的示例,每行内容都已排列,但每个4*4网格中的行也已排列,网格顺序也已排列。所有这些都需要根据我的生成器中的个人排列(pertmuted index)来完成。因为我是新来的,我想了解为什么我的问题被否决。有什么问题吗?@Cépagrave我只能猜测——但这里的一些人对问题应该是什么样子有非常强烈的意见——在帮助部分查找“mcve”。如果他们怀疑你懒惰,或者你自己不够努力,或者没有尽力解释你的问题,他们就会生气。例如,user2357112向您抛出的一行——虽然我从上下文中发现它足够清晰——有些人可能会觉得它有点傲慢。但正如我所说,只是猜测而已。
import numpy as np
from itertools import islice

def per(n=None):
    while True:
        n = (yield n if n is None else np.random.permutation(n)) or n

def sweep(shp):
    pg = per()
    pg.send(None)
    redshp = len(shp)*[1]
    sz = 1
    for j, k in enumerate(shp):
        pg.send(k)
        redshp[j] = k
        yield np.reshape((*islice(pg, sz),), redshp)
        sz *= k

# example
a = np.arange(24).reshape((2,3,4))
idx = *sweep(a.shape),
for i in idx:
    print(i)
print(a[idx])
import numpy as np
from itertools import islice,count

size,dim = 4,3

per = (np.random.permutation(size) for _ in count())
idx = *(np.reshape((*islice(per, size**d),),[size]*(d+1)+[1]*(dim-d-1)) for d in range(dim)),

a = np.arange(size**dim).reshape((size,)*dim)
print(a[idx])