2

I have a 3D list ll which can be of size 100 K * 10 * 3

ll = [
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10,11,12]], [[6, 7, 8],[12, 13, 14]], [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
]

I want it to be

ll = [[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10,11,12]], [[6, 7, 8],[12, 13, 14], [0, 0, 0], [0, 0, 0]], [[10, 20, 30], [40, 50, 60], [70, 80, 90], [0,0,0]]]

so that I can create a1 = np.array(l1)

a1

array([
[[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
[[6,7,8], [12,13,14], [0,0,0], [0,0,0]]
[[10, 20, 30], [40, 50, 60], [70, 80, 90], [0,0,0]]
])

I have read the following but they are for 2D, i am not able to do it for 3D.

https://stackoverflow.com/a/38619333/5202279

https://stackoverflow.com/a/43149308/5202279

WhySoSerious
  • 185
  • 1
  • 19

2 Answers2

2

Here's a way that allocates the NumPy array up front then copies the data over. Assuming you don't actually need the expanded ll, this should use less memory than appending the 0-triples to ll before creating a1:

a1 = np.zeros((len(ll), max([len(k) for k in ll]), 3))
for ctr,k in enumerate(ll):
     a1[ctr,:len(k),:] = k

a1
array([[[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.],
        [10., 11., 12.]],

       [[ 6.,  7.,  8.],
        [12., 13., 14.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[10., 20., 30.],
        [40., 50., 60.],
        [70., 80., 90.],
        [ 0.,  0.,  0.]]])

max([len(k) for k in ll]) tells us the maximum number of triples in any member of ll. We allocate a 0-initialized NumPy array of the desired size. Then in the loop, smart indexing tells us where in a1 to copy each member of ll.

mtrw
  • 34,200
  • 7
  • 63
  • 71
1

Iterate over all elements in the list, which are also lists and get the max length. Then append zeros to every "sublist" that does not have the max length.

m = max([len(k) for k in ll])

for i in range(0, len(ll)):
    while len(ll[i]) < m:
        ll[i].append([0, 0, 0])

IcesHay
  • 359
  • 2
  • 13
  • Good method, but `max` is the name of a function in Python already, so probably best not to reuse it for a variable name. You can do something like `m = max([len(k) for k in ll])` to turn the first part of your answer into something more Pythonic – mtrw Dec 18 '19 at 13:16
  • You are right. I will update my answer. Thanks for your feedback. – IcesHay Dec 18 '19 at 13:17