2017-01-05 7 views
3

Я хотел бы использовать различные функции itertools для создания массивов numpy. Я могу легко заранее вычислить количество элементов в продукте, комбинации, перестановки и т. Д., Поэтому выделение пространства не должно быть проблемой.itertools to numpy array

например.

coords = [[1,2,3],[4,5,6]] 
iterable = itertools.product(*coords) 
shape = (len(coords[0]), len(coords[1])) 
arr = np.iterable_to_array(
    iterable, 
    shape=shape, 
    dtype=np.float64, 
    count=shape[0]*shape[1] 
) #not a real thing 
answer = np.array([ 
    [1,4],[1,5],[1,6], 
    [2,4],[2,5],[2,6], 
    [3,4],[3,5],[3,6]]) 
assert np.equal(arr, answer) 
+2

Итак, есть причина 'обр = np.array (список (итерацию)) 'не работает для вас? Вероятно, вы ищете 'np.formiter', но он не очень хорошо разбирается в многомерных массивах, последний раз я пытался. –

+0

Я мог бы также создать нулевой массив, а затем заполнить отдельные значения. Это было бы быстрее, возможно: http: //forthescience.org/blog/2015/06/07/performance-of-filling-a-numpy-array/... было просто интересно, есть ли хороший способ иметь numpy выполните эту работу, так как iterables всплывают повсюду в python. – Scott

+1

К сожалению, AFAIK поддерживает только одномерные массивы из итераций. Проверьте этот обмен: https://mail.scipy.org/pipermail/numpy-discussion/2007-August/028898.html Действительно, они предлагают использовать 'empty'! –

ответ

1

Вот несколько Numpy способов создания массива с этими значениями

In [469]: coords = [[1,2,3],[4,5,6]] 
In [470]: it = itertools.product(*coords) 
In [471]: arr = np.array(list(it)) 
In [472]: arr 
Out[472]: 
array([[1, 4], 
     [1, 5], 
     [1, 6], 
     [2, 4], 
     [2, 5], 
     [2, 6], 
     [3, 4], 
     [3, 5], 
     [3, 6]]) 

fromiter будет работать с соответствующей структурированной dtype:

In [473]: it = itertools.product(*coords) 
In [474]: arr = np.fromiter(it, dtype='i,i') 
In [475]: arr 
Out[475]: 
array([(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), 
     (3, 6)], 
     dtype=[('f0', '<i4'), ('f1', '<i4')]) 

Но обычно мы используем инструменты, которые numpy обеспечивает генерацию последовательностей и сеток. np.arange используется повсеместно.

meshgrid широко используется. С небольшим количеством проб и ошибок я обнаружил, что я мог бы перенести свой выход, и производить ту же последовательность:

In [481]: np.transpose(np.meshgrid(coords[0], coords[1], indexing='ij'), (1,2,0)).reshape(-1,2) 
Out[481]: 
array([[1, 4], 
     [1, 5], 
     [1, 6], 
     [2, 4], 
     [2, 5], 
     [2, 6], 
     [3, 4], 
     [3, 5], 
     [3, 6]]) 

repeat и tile также полезно для таких задач, как это:

In [487]: np.column_stack((np.repeat(coords[0],3), np.tile(coords[1],3))) 
Out[487]: 
array([[1, 4], 
     [1, 5], 
     [1, 6], 
     [2, 4], 
     [2, 5], 
     [2, 6], 
     [3, 4], 
     [3, 5], 
     [3, 6]]) 

Я сделал некоторые тайминги на fromiter в прошлом. Моя память заключается в том, что она предлагает только скромную экономию времени за np.array.

Некоторое время назад я исследовал itertools и fromiter, и нашел способ объединить их с помощью itertools.chain

convert itertools array into numpy array

In [499]: it = itertools.product(*coords) 
In [500]: arr = np.fromiter(itertools.chain(*it),int).reshape(-1,2) 
In [501]: arr 
Out[501]: 
array([[1, 4], 
     [1, 5], 
     [1, 6], 
     [2, 4], 
     [2, 5], 
     [2, 6], 
     [3, 4], 
     [3, 5], 
     [3, 6]]) 
+0

Это работает, но за счет теперь приходится переписывать пакет itertools для numpy. – Scott

+1

Я нашел более ранний ответ, который использует 'itertools.chain' для сглаживания' product'. – hpaulj

+0

Это очень мило. – Scott