как установить все внутренние значения массива 2d numpy одинакового размера со значениями заполнения по умолчанию - PullRequest
1 голос
/ 18 июня 2020

У меня есть массив NumPy с множеством подмассивов разного размера. Я бы хотел, чтобы все подмассивы были одинакового размера. Я не хочу удалять какую-либо информацию, поэтому я хотел бы заполнить массив значениями по умолчанию.

Преобразуйте это:

[array([ 1. , 15.5]) array([1.]) array([ 1. , 15.5]) array([1.])
 array([ 1. , 15.5]) array([1.]) array([ 1. , 15.5]) array([1.])
 array([1.]) array([1.]) array([ 1. , 15.5]) array([1.])
 array([ 1. , 15.5, 92. ]) array([1.]) array([ 1. , 15.5]) array([1.])
 array([ 1. , 15.5]) array([1.]) array([ 1. , 15.5]) array([1.])
 array([ 1. , 15.5]) array([1.]) array([1.]) array([1.])]

В это:

[[1., 15.5, 0],   [1., 0, 0], [1., 15.5, 0],  [1., 0, 0],
 [1., 15.5, 0],   [1., 0, 0], [1., 15.5, 0],  [1., 0, 0],
 [1., 0, 0],      [1., 0, 0], [1., 15.5, 0],  [1., 0, 0],
 [1., 15.5, 92.], [1., 0, 0], [1., 15.5, 0],  [1., 0, 0],
 [1., 15.5, 0],   [1., 0, 0], [1., 15.5, 0],  [1., 0, 0],
 [1., 15.5, 0],   [1., 0, 0], [1., 0, 0],     [1., 0, 0]]

Я использовал 0 в качестве значения по умолчанию в приведенном выше примере.

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Найдите максимальный размер массивов и используйте встроенную функцию заполнения, чтобы заполнить их все до максимального размера (вы даже можете передать значение по вашему выбору, чтобы заполнить заполнение в этой функции - по умолчанию 0):

l_m = max([i.size for i in a])
padded = np.stack([np.pad(i,(0,l_m-len(i)),'constant') for i in a])

вывод:

[[ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.   0.   0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5 92. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.  15.5  0. ]
 [ 1.   0.   0. ]
 [ 1.   0.   0. ]
 [ 1.   0.   0. ]]
1 голос
/ 18 июня 2020

Вот быстрый метод с использованием itertools.zip_longest

np.array([*it.zip_longest(*map(np.ndarray.tolist,a),fillvalue=0)]).T
array([[ 1. , 15.5,  0. ],
       [ 1. ,  0. ,  0. ],
           < -- snip -- > 
       [ 1. ,  0. ,  0. ],
       [ 1. , 15.5, 92. ],
       [ 1. ,  0. ,  0. ],
           < -- snip -- > 
       [ 1. ,  0. ,  0. ],
       [ 1. ,  0. ,  0. ]])

Мы можем немного пожертвовать скоростью и упростить:

np.transpose([*it.zip_longest(*a,fillvalue=0)])

Это все еще намного быстрее, чем np.pad метод:

timeit(lambda:np.array([*it.zip_longest(*map(np.ndarray.tolist,a),fillvalue=0)]).T,number=10000)
0.12874844600446522
>>> timeit(lambda:np.transpose([*it.zip_longest(*a,fillvalue=0)]),number=10000)
0.29307466209866107
>>> timeit(lambda:np.stack([np.pad(i,(0,l_m-len(i)),'constant') for i in a]),number=10000)
6.289798409212381

Варианты

Если результат должен быть C -смежным:

np.array([*it.zip_longest(*map(np.ndarray.tolist,a),fillvalue=0)],order="F").T

Если он должен владеть своими данными:

np.array([*zip(*it.zip_longest(*a,fillvalue=0))])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...