Создать numpy массив из генератора, список списков - PullRequest
2 голосов
/ 28 апреля 2020

Я пытаюсь преобразовать генератор в массив numpy. Я применяю функцию карты к списку данных, и в результате получается генератор. Я попытался сделать list(map()), а затем создать вектор numpy, но это занимает много времени. Я где-то видел, что я могу напрямую использовать np.fromiter для создания вектора numpy из моего генератора. Однако я сталкиваюсь с этой ошибкой:

ValueError: setting an array element with a sequence.

Я обнаружил, что ошибка возникает, потому что мой генератор генерирует список списков. как: [[1,2,3], [4,5,6]] и я должен использовать правильную структурную dtype для функции fromiter(). Я не мог найти правильное объяснение того, как это сделать. Вы можете помочь мне?

Вот полный пример:

import numpy as np

def foo(bar):
  return [bar] * 3 # so for 4 it returns [4,4,4], ..

a = [1,2,3,4,5,6,7]
b = map(foo,a)
c = np.fromiter(b, int) # this doesn't work.

1 Ответ

2 голосов
/ 28 апреля 2020

Чтобы использовать соединение dtype, функция должна возвращать кортежи, а не списки

In [977]: def foo(bar): 
     ...:   return (bar,) * 3 # so for 4 it returns [4,4,4], .. 
     ...:  
     ...: a = [1,2,3,4,5,6,7] 
     ...: b = map(foo,a)                                                                               
In [978]: list(b)                                                                                      
Out[978]: [(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7)]
In [979]: def foo(bar): 
     ...:   return (bar,) * 3 # so for 4 it returns [4,4,4], .. 
     ...:  
     ...: a = [1,2,3,4,5,6,7] 
     ...: b = map(foo,a)                                                                               
In [980]: np.fromiter(b, 'i,i,i')                                                                      
Out[980]: 
array([(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6),
       (7, 7, 7)], dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])

некоторые периоды времени:

In [981]: %%timeit b = map(foo,a) 
     ...: np.array(list(b)) 
     ...:  
     ...:                                                                                              
1.9 µs ± 55.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [982]: %%timeit b = map(foo,a) 
     ...: np.fromiter(b, 'i,i,i') 
     ...:  
     ...:                                                                                              
17.2 µs ± 9.72 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...