【发布时间】:2017-08-26 01:19:24
【问题描述】:
我有不同长度的列表列表(例如[[1, 2, 3], [4, 5], [6, 7, 8, 9]]),并希望将其转换为numpy 整数数组。我了解numpy 多维数组中的“子”数组的长度必须相同。那么,将上面示例中的列表转换为像 [[1, 2, 3, 0], [4, 5, 0, 0], [6, 7, 8, 9]] 这样的 numpy 数组(即用零完成)的最有效方法是什么?
【问题讨论】:
我有不同长度的列表列表(例如[[1, 2, 3], [4, 5], [6, 7, 8, 9]]),并希望将其转换为numpy 整数数组。我了解numpy 多维数组中的“子”数组的长度必须相同。那么,将上面示例中的列表转换为像 [[1, 2, 3, 0], [4, 5, 0, 0], [6, 7, 8, 9]] 这样的 numpy 数组(即用零完成)的最有效方法是什么?
【问题讨论】:
你可以用 np.zeros 创建一个 numpy 数组,并用你的列表元素填充它们,如下所示。
a = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
import numpy as np
b = np.zeros([len(a),len(max(a,key = lambda x: len(x)))])
for i,j in enumerate(a):
b[i][0:len(j)] = j
结果
[[ 1. 2. 3. 0.]
[ 4. 5. 0. 0.]
[ 6. 7. 8. 9.]]
【讨论】:
在转换为 numpy 数组之前,通过填充较短的子列表对列表进行一些预处理:
>>> lst = [[1, 2, 3], [4, 5], [1, 7, 8, 9]]
>>> pad = len(max(lst, key=len))
>>> np.array([i + [0]*(pad-len(i)) for i in lst])
array([[1, 2, 3, 0],
[4, 5, 0, 0],
[1, 7, 8, 9]])
【讨论】:
np.array([np.pad(i, ((0,pad-len(i)),(0,0))) for i in lst]) 如果 lst 是二维数组的列表。因此,对于更多维数组,您需要为每个新轴添加 (0,0)。
这是@Divakar 类型的答案:
In [945]: ll = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
In [946]: lens = [len(l) for l in ll] # only iteration
In [947]: lens
Out[947]: [3, 2, 4]
In [948]: maxlen=max(lens)
In [949]: arr = np.zeros((len(ll),maxlen),int)
In [950]: mask = np.arange(maxlen) < np.array(lens)[:,None] # key line
In [951]: mask
Out[951]:
array([[ True, True, True, False],
[ True, True, False, False],
[ True, True, True, True]], dtype=bool)
In [952]: arr[mask] = np.concatenate(ll) # fast 1d assignment
In [953]: arr
Out[953]:
array([[1, 2, 3, 0],
[4, 5, 0, 0],
[6, 7, 8, 9]])
对于大型列表,它具有更快的潜力。但它更难理解和/或重现。
Convert Python sequence to NumPy array, filling missing values - Divakar 有一篇好帖子。还提到了itertools.zip_longest。这可以作为重复引用。
【讨论】: