重塑numpy数组列表,然后重新整形

时间:2015-11-11 06:52:09

标签: python arrays numpy

我有一个列表,其中包含几个具有不同形状的numpy数组。 我想将这个数组列表重新整形为一个numpy向量,然后更改向量中的每个元素,然后将其重新整形回原始的数组列表。

例如:

输入

[numpy.zeros((2,2)), numpy.ones((3,3))]
  • 第一

向量

[0,0,0,0,1,1,1,1,1,1,1,1,1]
  • 第二

每次只改变一个元素。例如,将第1个元素0更改为2

[0,2,0,0,1,1,1,1,1,1,1,1,1]
  • 最后

将其转换回

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

有快速实施吗?非常感谢。

2 个答案:

答案 0 :(得分:1)

似乎转换为列表并返回将是低效的。相反,为什么不弄清楚要索引哪个数组(以及在哪里)然后只更新该索引? e.g。

def change_element(arr1, arr2, ix, value):
    which = ix >= arr1.size
    arr = [arr1, arr2][which]
    ix = ix - arr1.size if which else ix
    arr.ravel()[ix] = value

以下是一些示例用法:

>>> arr1 = np.zeros((2, 2))
>>> arr2 = np.ones((3, 3))
>>> change_element(arr1, arr2, 1, 2)
>>> change_element(arr1, arr2, 6, 3.14)
>>> arr1
array([[ 0.,  2.],
       [ 0.,  0.]])
>>> arr2
array([[ 1.  ,  1.  ,  3.14],
       [ 1.  ,  1.  ,  1.  ],
       [ 1.  ,  1.  ,  1.  ]])
>>> change_element(arr1, arr2, 7, 3.14)
>>> arr1
array([[ 0.,  2.],
       [ 0.,  0.]])
>>> arr2
array([[ 1.  ,  1.  ,  3.14],
       [ 3.14,  1.  ,  1.  ],
       [ 1.  ,  1.  ,  1.  ]])

一些注意事项 - 这会更新阵列。它不会创建新数组。如果你真的需要创建新数组,我想你可以np.copy然后返回。此外,这依赖于ravel之前和之后的数组共享内存。我不记得ravel返回新数组而不是原始数组视图的确切情况。 。

推广到更多数组实际上非常简单。我们只需要沿着数组列表向下看,看看ix是否小于数组大小。如果是,我们找到了我们的阵列。如果不是,我们需要从ix中减去数组的大小,以表示到目前为止我们遍历的元素数量:

def change_element(arrays, ix, value):
    for arr in arrays:
        if ix < arr.size:
            arr.ravel()[ix] = value
            return
        ix -= arr.size

你可以这样称呼它:

change_element([arr1, arr2], 6, 3.14159)

答案 1 :(得分:0)

@mgilson对你来说可能是最好的答案,但如果你必须先转换成一个平面列表然后再回去(也许是因为你需要对平面列表做其他事情),那么你可以使用列表推导执行此操作:

lst = [numpy.zeros((2,4)), numpy.ones((3,3))]
tlist = [e for a in lst for e in a.ravel()]
tlist[1] = 2
i = 0
lst2 = []
dims = [a.shape for a in lst]
for n, m in dims:
    lst2.append(np.array(tlist[i:i+n*m]).reshape(n,m))
    i += n*m
lst2

[array([[ 0.,  2.],
    [ 0.,  0.]]), array([[ 1.,  1.,  1.],
    [ 1.,  1.,  1.],
    [ 1.,  1.,  1.]])]

当然,当您展平时,您会丢失有关阵列大小的信息,因此您需要将它们存储在某处(此处,dims)。