在迭代器中重塑 numpy 数组

reshape numpy arrays in iterator

假设我有一个 numpy 数组列表。如何重塑列表中的数组?
这是一个例子,我想确保我所有的数组都有二维:

In [0]: import numpy as np
   ...: arr1 = np.array([1, 2, 3]) # Shape is (3,) --> Will need reshaping
   ...: arr2 = np.array([[1, 2, 3]]) # Shape is (1, 3) --> Shape ok
   ...: list_of_arrays = [arr1, arr2]
   ...: for i, arr in enumerate(list_of_arrays):
   ...:     print("\narray number {}, initial shape: {}".format(i, arr.shape))
   ...:     if len(arr.shape)==1:
   ...:         print("needs reshaping")
   ...:         arr = np.reshape(arr, (1, arr.shape[0]))
   ...:         print("new shape: {}".format(arr.shape))
   ...:     else:
   ...:         print("shape ok")

如预期的那样打印出来:

array number 0, initial shape: (3,)
needs reshaping
new shape: (1, 3)

array number 1, initial shape: (1, 3)
shape ok  

然而,结果被强制转换为arr,而不是我实际要修改的数组,arr1

In [1]: arr1.shape
Out[1]: (3,)

如何将结果转换为 arr1

请注意,我需要修改列表中的元素,而不是列表本身。换句话说,我希望能够直接修改 arr1 :它将作为参数作为 arr1 而不是 list_of_arrays[0].

传递

这是一个基本的数组迭代问题。

for i in alist:
   i = ...

在循环内重新分配 i,因此不会影响源列表。你必须改变 i 本身,或者索引列表。

In [552]: arr1 = np.array([1, 2, 3]) # Shape is (3,) --> Will need reshaping
     ...: arr2 = np.array([[1, 2, 3]]) # Shape is (1, 3) --> Shape ok
     ...: list_of_arrays = [arr1, arr2]
     ...: for i, arr in enumerate(list_of_arrays):
     ...:    if len(arr.shape)==1:
     ...:        list_of_arrays[i] = np.reshape(arr, (1, arr.shape[0])) 
In [553]: list_of_arrays
Out[553]: [array([[1, 2, 3]]), array([[1, 2, 3]])]

reshape 创建数组的新视图,但可以就地修改形状:

 In [554]: arr1 = np.array([1, 2, 3]) # Shape is (3,) --> Will need reshaping
     ...: arr2 = np.array([[1, 2, 3]]) # Shape is (1, 3) --> Shape ok
     ...: list_of_arrays = [arr1, arr2]
     ...: for arr in list_of_arrays:
     ...:    if len(arr.shape)==1:
     ...:        arr.shape = (1, arr.shape[0])

但创建新列表通常更容易,甚至更快。例如 np.vstack 使用

alist = [np.atleast_2d(arr) for arr in list_of_arrays]

确保所有的输入数组都是二维的。像这样的列表理解在 Python 中被广泛使用。 list(map(np.atleast_2d, list_arrays)) 是等价的,但我认为可读性不高。