将具有多个维度的numpy数组转换为具有嵌套numpy数组的二维数组

将具有多个维度的numpy数组转换为具有嵌套numpy数组的二维数组,numpy,Numpy,我想将具有多个维度(多于2个维度)的数组转换为二维数组,其中其他维度将转换为嵌套的独立数组 因此,如果我有一个像numpy.arange(3*4*5*5*5)这样的数组。重塑((3,4,5,5,5)),我想把它转换成一个shape(3,4)数组,其中每个元素都是一个shape(5,5)数组。外部数组的数据类型将是object 例如,对于np.arange(8).重塑((1,1,2,2)),输出将等效于: a = np.ndarray(shape=(1,1), dtype=object) a[0,

我想将具有多个维度(多于2个维度)的数组转换为二维数组,其中其他维度将转换为嵌套的独立数组

因此,如果我有一个像
numpy.arange(3*4*5*5*5)这样的数组。重塑((3,4,5,5,5))
,我想把它转换成一个shape
(3,4)
数组,其中每个元素都是一个shape
(5,5)
数组。外部数组的数据类型将是
object

例如,对于
np.arange(8).重塑((1,1,2,2))
,输出将等效于:

a = np.ndarray(shape=(1,1), dtype=object)
a[0, 0] = np.arange(8).reshape((1, 1, 2, 2, 2))[0, 0, :, :, :]

我怎样才能有效地做到这一点呢?

谢谢你的提示。这是使用
dtype=np.object
数组时的外观:

outer_array = np.empty((x.shape[0], x.shape[1]), dtype=np.object)
for i in range(x.shape[0]):
    for j in range(x.shape[1]):
        outer_array[i, j] = x[i, j]
循环可能不是执行此任务的最有效方式,但此任务可能没有矢量化操作

(使用更多的整形,这应该比Divakar的解决方案更快:;)-->不,Divakar更快。。。。很好的解决方案

def advanced_reshape_solution(x):
    m, n = x.shape[:2]
    sub_arr_size = np.prod(x.shape[2:])
    out_array = np.empty((m * n), dtype=object)
    x_flat_view = x.reshape(-1)
    for i in range(m*n):
        out_array[i] = x_flat_view[i * sub_arr_size:(i + 1) * sub_arr_size].reshape(x.shape[2:])
    return out_array.reshape((m, n))

我们可以在一个循环中重塑规则数组中的元素并将其分配到输出对象dtype数组中,这个循环似乎比使用两个循环快一点,如下所示-

def reshape_approach(a):
    m,n = a.shape[:2]
    a.shape = (m*n,) + a.shape[2:]
    out = np.empty((m*n),dtype=object)
    for i in range(m*n):
        out[i] = a[i]
    out.shape = (m,n)
    a.shape = (m,n) + a.shape[1:]
    return out
运行时测试

其他方法-

时间安排-

In [154]: m,n = 300,400
     ...: a = np.arange(m * n * 5 * 5 * 5).reshape((m,n, 5, 5, 5))

In [155]: %timeit simply_assign(a)
10 loops, best of 3: 39.4 ms per loop

In [156]: %timeit reshape_approach(a)
10 loops, best of 3: 32.9 ms per loop
使用
7D
数据-

In [160]: m,n,p,q = 30,40,30,40
     ...: a = np.arange(m * n *p * q * 5 * 5 * 5).reshape((m,n,p,q, 5, 5, 5))

In [161]: %timeit simply_assign(a)
1000 loops, best of 3: 421 µs per loop

In [162]: %timeit reshape_approach(a)
1000 loops, best of 3: 316 µs per loop

请给出一个示例代码,其中显示了您已经尝试过的内容。您是否可以使用np.arange(8)。重塑((1,1,2,2,2))来显示预期的输出?您的示例太大了。添加了预期的输出示例。一个类似的SO问题,使用
frompyfunc
,您可以将numpy数组作为对象存储在具有dtype object的数组中。是这样吗?然后给我一点时间更新我的答案。这很有效。但仅限于5维数组。如何获得任意维数的子阵列?@Mitar更新了我的解决方案。哦,这看起来比预期的要简单。:-)很好的解决方案。但是,如果效率不是生存所必需的,那么对于一项简单的任务来说,这太复杂了。更快速的方法是执行
x.restrape(-1)
,然后使用步幅完全避免循环。稍后我将对此进行研究。@Scotty1-Well OP要求性能,所以我不明白为什么很少额外的步骤会有影响:)重塑循环可以被
out[:]=list(a)
替换,尽管时间基本相同。@hpaulj Yup,尝试过,但速度明显较慢。@Mitar分配给形状是什么意思?
In [160]: m,n,p,q = 30,40,30,40
     ...: a = np.arange(m * n *p * q * 5 * 5 * 5).reshape((m,n,p,q, 5, 5, 5))

In [161]: %timeit simply_assign(a)
1000 loops, best of 3: 421 µs per loop

In [162]: %timeit reshape_approach(a)
1000 loops, best of 3: 316 µs per loop