заполните недостающие значения в 3D-списке нулями, чтобы создать 3D-массив numpy

У меня есть трехмерный список ll, который может иметь размер 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]]
]

Я хочу, чтобы это было

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]]]

так что я могу создать 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]]
])

Я прочитал следующее, но они для 2D, я не могу сделать это для 3D.

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

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


person WhySoSerious    schedule 18.12.2019    source источник
comment
Я не понимаю вашего вопроса. Не могли бы вы быть более точным? Почему бы вам просто не добавить недостающие нули?   -  person IcesHay    schedule 18.12.2019
comment
Являются ли самые внутренние списки также переменной длины? Или они всегда содержат три элемента?   -  person emilaz    schedule 18.12.2019
comment
они являются координатами, поэтому всегда будут иметь 3 элемента.   -  person WhySoSerious    schedule 18.12.2019
comment
ll[len(ll) - 1].append([0, 0, 0]) Вы имеете в виду что-то вроде этого?   -  person IcesHay    schedule 18.12.2019
comment
@IcesHay Я думаю, что идея состоит в том, чтобы что-то более общее работало, то есть когда вы не знаете, сколько нулей нужно дополнить и где.   -  person emilaz    schedule 18.12.2019
comment
Я отредактировал Вопрос.   -  person WhySoSerious    schedule 18.12.2019


Ответы (2)


Вот способ, который заранее выделяет массив NumPy, а затем копирует данные. Предполагая, что вам на самом деле не нужен расширенный ll, это должно использовать меньше памяти, чем добавление 0-троек к ll перед созданием 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]) сообщает нам максимальное количество троек в любом элементе ll. Мы выделяем инициализированный 0 массив NumPy нужного размера. Затем в цикле интеллектуальное индексирование сообщает нам, куда в a1 копировать каждый член ll.

person mtrw    schedule 18.12.2019

Перебрать все элементы в списке, которые также являются списками, и получить максимальную длину. Затем добавьте нули к каждому «подсписку», который не имеет максимальной длины.

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])

person IcesHay    schedule 18.12.2019
comment
Хороший метод, но max уже является именем функции в Python, поэтому, вероятно, лучше не использовать его повторно для имени переменной. Вы можете сделать что-то вроде m = max([len(k) for k in ll]), чтобы превратить первую часть вашего ответа в нечто более Pythonic. - person mtrw; 18.12.2019
comment
Ты прав. Я обновлю свой ответ. Спасибо за ваш отзыв. - person IcesHay; 18.12.2019