a = np.array([1,2,3])
b = np.array([4,5])
l = [a,b]
我想要一个函数stack_padding
这样:
assert(stack_padding(l) == np.array([[1,2,3],[4,5,0]])
numpy是否有实现
的标准方法编辑:l
可能包含更多元素
答案 0 :(得分:3)
我认为itertools.zip_longest
和fill_value=0
可以为您工作:
import itertools
a = np.array([1,2,3])
b = np.array([4,5])
l = [a,b]
def stack_padding(l):
return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))
>>> stack_padding(l)
array([[1, 2, 3],
[4, 5, 0]])
答案 1 :(得分:1)
使用numpy.pad
:
a = np.array([1,2,3])
b = np.array([4,5])
l = [a,b]
max_len = max([len(arr) for arr in l])
padded = np.array([np.lib.pad(arr, (0, max_len - len(arr)), 'constant', constant_values=0) for arr in l])
答案 2 :(得分:1)
如果您不想使用itertools
和column_stack
,numpy.ndarray.resize
也会做得很好。正如jtweeder所提到的,您只需要知道每行的结果大小即可。使用resize
的好处是numpy.ndarray
在内存中是连续的。当每一行的大小不同时,调整大小的速度更快。两种方法之间的性能差异是可以观察到的。
import numpy as np
import timeit
import itertools
def stack_padding(it):
def resize(row, size):
new = np.array(row)
new.resize(size)
return new
# find longest row length
row_length = max(it, key=len).__len__()
mat = np.array( [resize(row, row_length) for row in it] )
return mat
def stack_padding1(l):
return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))
if __name__ == "__main__":
n_rows = 200
row_lengths = np.random.randint(30, 50, size=n_rows)
mat = [np.random.randint(0, 100, size=s) for s in row_lengths]
def test_stack_padding():
global mat
stack_padding(mat)
def test_itertools():
global mat
stack_padding1(mat)
t1 = timeit.timeit(test_stack_padding, number=1000)
t2 = timeit.timeit(test_itertools, number=1000)
print('With ndarray.resize: ', t1)
print('With itertool and vstack: ', t2)
在以上比较中,resize
方法获胜:
>>> With ndarray.resize: 0.30080295499647036
>>> With itertool and vstack: 1.0151802329928614