Заполнение пустого списка списков нулями, чтобы получить список фиксированного размера из 5 кортежей - PullRequest
0 голосов
/ 07 октября 2018

У меня есть образец из 1000 примеров.Каждый образец содержит список из 18 списков переменной длины, а некоторые списки пусты.

Вот пример:

len(My_list)
18
print(My_list)
array([list([(17, 163, 0.11258018, 15),(78, 193, 0.99713018, 17),(478, 94, 0.7299528, 2), (63, 268, 0.77531445, 3), (169, 279, 0.7947326, 4),(456, 140, 0.65013665, 7), (61, 301, 0.7433308, 8)]), 
list([]),
list([]), 
list([]), 
list([]), 
list([]),
list([]),
list([]), 
list([(63, 176, 0.18713018, 0),(199, 185, 0.88743243, 79), (282, 75, 0.752135, 84)]),
list([(62, 185, 0.13743243, 1)]), 
list([]),
list([(67, 156, 0.14346971, 2)]), 
list([(2, 15, 0.00639179, 3)]),
list([]),
list([]), 
list([]), 
list([]), 
list([])], 
dtype=object)

Что я хотел бы сделать?

для каждого списка:

1 - сохраняет первые 5 кортежей

2 - Если список пуст, чем создать список из пяти кортежей как flollow

list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]).

3 - Если список не пустой, но не содержит 5 элементов, заполните его, чтобы получить пять элементов.Поскольку My_list[12] содержит только один элемент list([(67, 156, 0.14346971, 2)]), следовательно:

My_list[12]=list([(67, 156, 0.14346971, 2),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)])

Ожидаемый результат:

array([list([(17, 163, 0.11258018, 15),(78, 193, 0.99713018, 17),(478, 94, 0.7299528, 2), (63, 268, 0.77531445, 3), (169, 279, 0.7947326, 4)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(63, 176, 0.18713018, 0),(199, 185, 0.88743243, 79), (282, 75, 0.752135, 84),(0,0,0,0),(0,0,0,0)]),
list([(62, 185, 0.13743243, 1),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(67, 156, 0.14346971, 2),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(2, 15, 0.00639179, 3),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]),
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)]), 
list([(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)])], 
dtype=object)

Что я пробовал?

My_list=np.asarray(My_list)

My_list = [joint if len(joint) != 0 else [(0, 0, 0,0)] for joint in My_list]

Однако это не делает работу.Он заполняет только пустые списки с (0,0,0,0). Более того, списки с одним или несколькими элементами пропускают их.Ожидается, что все пустые списки или списки будут заполнены менее чем пятью элементами (0,0,0,0), чтобы получить по пять элементов в списке.

Любой сигнал?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Это вариант ответа @PaulP (и комментария @ Eir).Он достаточно близок, чтобы я не публиковал его, за исключением того, что он быстрее (и, возможно, более понятен).

Определите функцию, которая работает с одним списком за раз - используя эту идею добавления пэда и удаленияненужные элементы:

In [209]: z = [4*(0,) for _ in range(5)]
In [210]: def foo(alist):
     ...:     return  (alist + z)[:5]

Это может быть применено к каждому списку через понимание списка:

In [211]: [foo(row) for row in arr]
Out[211]: 
[[(17, 163, 0.11258018, 15),
  (78, 193, 0.99713018, 17),
  (478, 94, 0.7299528, 2),
  (63, 268, 0.77531445, 3),
  (169, 279, 0.7947326, 4)],
 [(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)],
 ....
 [(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]]

Но если вы хотите массив объектов, подход @ Paul, использующий frompyfunc, работает хорошо:

In [212]: np.frompyfunc(foo,1,1)(arr)
Out[212]: 
array([list([(17, 163, 0.11258018, 15), (78, 193, 0.99713018, 17), (478, 94, 0.7299528, 2), (63, 268, 0.77531445, 3), (169, 279, 0.7947326, 4)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
  ....          dtype=object)

Сроки:

In [176]: timeit np.frompyfunc(list.__getitem__, 2, 1)(arr + z, slice(5))
14.8 µs ± 18.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [184]: timeit [foo(row) for row in arr]
7.6 µs ± 26.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [213]: timeit np.frompyfunc(foo,1,1)(arr)
8.49 µs ± 27.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
0 голосов
/ 07 октября 2018

Вот один из способов: склеить 5 кортежей со всем и обрезать позже:

>>> ml
array([list([(17, 163, 0.11258018, 15), (78, 193, 0.99713018, 17), (478, 94, 0.7299528, 2), (63, 268, 0.77531445, 3), (169, 279, 0.7947326, 4), (456, 140, 0.65013665, 7), (61, 301, 0.7433308, 8)]),
       list([]), list([]), list([]), list([]), list([]), list([]),
       list([]),
       list([(63, 176, 0.18713018, 0), (199, 185, 0.88743243, 79), (282, 75, 0.752135, 84)]),
       list([(62, 185, 0.13743243, 1)]), list([]),
       list([(67, 156, 0.14346971, 2)]), list([(2, 15, 0.00639179, 3)]),
       list([]), list([]), list([]), list([]), list([])], dtype=object)
>>> 
>>> z = np.array([None, 5*[4*(0,)]])[[1]]
>>> z
array([list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)])],
      dtype=object)
>>> 
>>> res = np.frompyfunc(list.__getitem__, 2, 1)(ml + z, slice(5))
>>> res
array([list([(17, 163, 0.11258018, 15), (78, 193, 0.99713018, 17), (478, 94, 0.7299528, 2), (63, 268, 0.77531445, 3), (169, 279, 0.7947326, 4)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(63, 176, 0.18713018, 0), (199, 185, 0.88743243, 79), (282, 75, 0.752135, 84), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(62, 185, 0.13743243, 1), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(67, 156, 0.14346971, 2), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(2, 15, 0.00639179, 3), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)]),
       list([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)])],
      dtype=object)

Объяснение: массивы делегированных операций типа dtype, таких как дополнение к их элементам.Поэтому ml + z объединяет каждый исходный список с копией нулей 5х4.

Далее нам нужно только сократить каждый список до 5 элементов.Операция somelist[:5] может быть записана как somelist.__getitem__(slice(5)) или даже как list.__getitem__(somelist, slice(5)).Эта последняя форма - это то, что мы «векторизируем», используя np.frompyfunc.

...