假设我有一个包含不等长度列表的列表。
a = [ [ 1, 2, 3], [2], [2, 4] ]
获得标准形状的零填充numpy数组的最佳方法是什么?
zero_a = [ [1, 2, 3], [2, 0, 0], [2, 4, 0] ]
我知道我可以使用像
这样的列表操作n = max( map( len, a ) )
map( lambda x : x.extend( [0] * (n-len(x)) ), a )
zero_a = np.array(zero_a)
但我想知道有没有简单的方法来完成这项工作?
答案 0 :(得分:7)
由于numpy必须在初始化之前知道数组的大小,因此对于这种情况,最佳解决方案将是基于numpy的构造函数。可悲的是,据我所知,没有。
可能不理想,但稍快一点的解决方案是使用零创建numpy数组并填充列表值。
import numpy as np
def pad_list(lst):
inner_max_len = max(map(len, lst))
map(lambda x: x.extend([0]*(inner_max_len-len(x))), lst)
return np.array(lst)
def apply_to_zeros(lst, dtype=np.int64):
inner_max_len = max(map(len, lst))
result = np.zeros([len(lst), inner_max_len], dtype)
for i, row in enumerate(lst):
for j, val in enumerate(row):
result[i][j] = val
return result
测试用例:
>>> pad_list([[ 1, 2, 3], [2], [2, 4]])
array([[1, 2, 3],
[2, 0, 0],
[2, 4, 0]])
>>> apply_to_zeros([[ 1, 2, 3], [2], [2, 4]])
array([[1, 2, 3],
[2, 0, 0],
[2, 4, 0]])
性能:
>>> timeit.timeit('from __main__ import pad_list as f; f([[ 1, 2, 3], [2], [2, 4]])', number = 10000)
0.3937079906463623
>>> timeit.timeit('from __main__ import apply_to_zeros as f; f([[ 1, 2, 3], [2], [2, 4]])', number = 10000)
0.1344289779663086
答案 1 :(得分:2)
不是严格来自numpy的函数,但你可以做这样的事情
from itertools import izip, izip_longest
import numpy
a=[[1,2,3], [4], [5,6]]
res1 = numpy.array(list(izip(*izip_longest(*a, fillvalue=0))))
或者,或者:
res2=numpy.array(list(izip_longest(*a, fillvalue=0))).transpose()
如果您使用python 3,请使用zip
和itertools.zip_longest
。