2

I have a list like this:

lista=[[1,2,3],
       [1,2,3,4,5,6],
       [1,2],]

I want to get numpy.array like this, (the shorter list element be expand to the max legnth, then set tail values as zeros):

array([[1,2,3,0,0,0],
       [1,2,3,4,5,6],
       [1,2,0,0,0,0],])

how to do? where there are some built-in methods in numpy?

hpaulj
  • 221,503
  • 14
  • 230
  • 353
epichide
  • 31
  • 3

2 Answers2

3

There's no direct way using numpy, since each inner list has a different amount of elements. One way could be to use itertools.zip_longest with a fillvalue:

from itertools import zip_longest

np.array(list(zip_longest(*lista, fillvalue=0))).T
array([[1, 2, 3, 0, 0, 0],
       [1, 2, 3, 4, 5, 6],
       [1, 2, 0, 0, 0, 0]])
yatu
  • 86,083
  • 12
  • 84
  • 139
  • 2
    See the discussion in https://stackoverflow.com/questions/38619143/convert-python-sequence-to-numpy-array-filling-missing-values for more details. The above scales well when there's large variation in list sizes, while boolean indexing works well for large numbers of elements. – LRRR Sep 14 '20 at 07:34
  • It can also be uptimized (25% for large lists) using `np.fromiter`. `np.array(list())` is not the fastest choice usually. – mathfux Sep 14 '20 at 11:12
  • Yes @mathfux gave it a try, but if I remember correctly np.fromiter wants a structured. Sepcifying directly a single dtype for an values yields an error – yatu Sep 14 '20 at 18:53
  • @yatu I did it this way: `dt = np.dtype([('', np.int)]*M) #or np.dtype(','.join('i'*M))`; `indices = np.fromiter(zip_longest(*lists, fillvalue=0), dt)`; `indices = indices.view(np.int).reshape(-1, M).T` where `M` is length of row (look at Robo's answer). – mathfux Sep 14 '20 at 20:04
  • Gets slightly more complex for a milt improvement. But its nice to know about an alternative, thanks @mathfux :) – yatu Sep 14 '20 at 20:06
-1

How about you create a zeros numpy array and then fill the values accordingly?

lists = [[1,2,3],
       [1,2,3,4,5,6],
       [1,2]]

a = np.zeros([len(lists), max([len(x) for x in lists])])

for i, sub in enumerate(lists):
    a[i][0:len(sub)] = sub
Robo Mop
  • 3,485
  • 1
  • 10
  • 23