2016-03-03 2 views
1

Я хочу создать массив 2D Numpy в форме python (2,7), определяющий тип каждого столбца. Некоторые из столбцов будут массивом. Таким образом, мой желаемый массив должен быть таким:2D NumpyArray с типом данных

[[ (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.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.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, 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, 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])]] 

Я попытался

>>> A = np.zeros(shape=(2), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float') 

Но я получаю 1D массив:

>>> print A 
[ (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.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.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, 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, 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])] 

И если я определяю это так:

>>> A = np.zeros(shape=(2,7), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float') 

Я получаю массив намного больше, чем я хочу; это (2,7x7).

Делая это, я получаю сообщение об ошибке:

>>> A = np.zeros(shape=([[2],[7]]), dtype= 'int, (3)float, (8)float, (8)float, (8)float, (10)float, (10)float') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: an integer is required 

Я не понимаю, как добраться до моего выхода. Любая помощь, возможно с объяснением, очень ценится! Благодаря!

ответ

3

A = np.zeros(shape=(2), dtype= '...') средства составляют массив с формой (2,) и с соединением dtype. Это именно то, что у вас есть.

(2,) - 1d форма. Он назвал поля, а не столбцы. Указание формы (2,7) просто делает массив 2d с теми же 7 полями.

С dtype вот так вы получите structured array. Вы получаете доступ к полям по имени, например. A['f0'].

Прочитайте документы по адресу dtype и структурированные массивы, если вы хотите получить доступ к этому подходу.

Другой ответ направляет вас на pandas. Это может быть лучше для ваших целей - или, может быть, нет. Но под обложками pandas использует массивы numpy, а в случае смешанных данных он будет использовать структурированные массивы или dtype=object.

С более простым dtype:

In [742]: A = np.zeros(shape=(2), dtype= 'int, (3)float, (4)float') 
In [743]: A 
Out[743]: 
array([(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])], 
     dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))]) 

Первым полем является 1d массивом целых чисел:

In [744]: A['f0'] 
Out[744]: array([0, 0]) 

Третьим можно рассматривать как 2x4 поплавков

In [745]: A['f2'] 
Out[745]: 
array([[ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.]]) 

Вы можете выбрать запись или элемент из этого массива:

In [746]: A[0] 
Out[746]: (0, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]) 

Вы можете выполнять операции с обычным числовым массивом в отдельных полях. Но работа в разных областях ограничена.

Вы не можете, например, сделать np.sum(A), суммировать по полям; но вы можете действовать на одном поле:

In [749]: np.sum(A['f1'],axis=1) 
Out[749]: array([ 0., 0.]) 

Структурированные массивы чаще всего создается путем чтения файла CSV, где поля соответствуют столбцам в файле, и некоторые столбцы текста.

Мое проиллюстрированное A может представлять собой файл, в котором 1-й столбец является счетчиком записей/строк, следующие 3 числа представляют одно значение, а следующее 4 - логически отличное значение. Альтернативой было бы создание массива поплавков (2,(1+3+4)) 2d.


Относительно Регулировочные элементы соединения типа массивов:

In [916]: A = np.zeros(shape=(2), dtype= 'int, (3)float, (4)float') 

можно установить все значения одного поля с массивом размера согласования или списка:

In [918]: A['f0']=[1,2] 

можно установить все значения поля многоэлементов в том же месте; здесь я просто заполнить их все:

In [920]: A['f1']=1 
In [921]: A 
Out[921]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]), 
     (2, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0])], 
     dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))]) 

Я могу индексировать и ломтиком один из полей обычным образом, рассматривая его, в этом случае в качестве 2-го массива:

In [922]: A['f2'][1,2:]=34 
In [923]: A 
Out[923]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]), 
     (2, [1.0, 1.0, 1.0], [0.0, 0.0, 34.0, 34.0])], 
     dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))]) 

Я не могу назначить все значения одной записи (строки) со списком значений, даже вложенные один:

In [924]: A[1]=[3,[1,2,3],[1,2,3,4]] 
... 
TypeError: 'list' does not support the buffer interface 

Но я могу установить его с кортежем

In [925]: A[1]=(3,[1,2,3],[1,2,3,4]) 
In [926]: A 
Out[926]: 
array([(1, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]), 
     (3, [1.0, 2.0, 3.0], [1.0, 2.0, 3.0, 4.0])], 
     dtype=[('f0', '<i4'), ('f1', '<f8', (3,)), ('f2', '<f8', (4,))]) 

Различие между списком и кортежами важно при работе со структурированными массивами. Обратите внимание, что на дисплее A отображается каждая запись с кортежем (). Несколько строк A могут быть установлены или инициализированы списком кортежей. Использование кортежей рисует линию между размерами содержащего массива и структурой внутри dtype.

+0

Это действительно круто! Я, конечно, не очень хорошо понимаю официальную документацию, или между документом и реализацией существует недостаток. Надеюсь, это поможет OP решить его проблему. – innoSPG

+0

Спасибо, hpaulj! Но когда я создаю пустой 2D-массив 'shape = (2,7)', а затем я пытаюсь вставить список, я получаю эту ошибку 'ValueError: установка элемента массива с последовательностью. '. Поэтому, я думаю, мне нужно указать, что 'A [0] [1]', например, должен быть подматрицей из 3-х плавающих и т. Д. Для других col. Как это сделать? Является ли это возможным? –

+0

Я добавил несколько примеров установки значений в массив 'A'. – hpaulj

1

Это, возможно, лучше всего подходит в качестве комментария, я судил, что он содержит достаточную информацию для ответа.

Numpy array - это не то, что вы ищете, вам лучше посмотреть на другие инструменты, такие как Pandas Dataframe. Вам нужно понять, что такое массив numpy; из документации numpy array, у вас есть это заявление:

NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type.

И это как-то противоречит тому, что вы пытаетесь достичь. Из той же документации, у вас есть это другое заявление:

An item extracted from an array, e.g., by indexing, is represented by a Python object whose type is one of the array scalar types built in Numpy. The array scalars allow easy manipulation of also more complicated arrangements of data.

Это означает, что тип данных вы предоставите должны соответствовать одному из этих скалярных типов. Вы предоставляете строку из множества скалярных типов.

+0

Спасибо за исчерпывающий ответ. Если бы я правильно понял, я должен был бы всплывать, например. Я все еще немного смущен, хотя, как в документации [dtypes documentation] (http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html) Я понял, что можно делать то, что я хочу '>>> dt = np.dtype (('i4, (2,3) f8, f4', (2,3))) # 2 x 3 structured sub -array'. Но тогда это, вероятно, что-то другое. –

+0

Вы правы, что у вас должно быть все плавание, например. Np.dtype, о котором вы говорите, это структура данных, а не скаляр, поэтому вы не можете иметь массив numpy с определенным пользователем np.dtype. Однако вы также можете создать то, что вы пытаетесь сделать с этим. Но у вас не будет легкой индексации, заданной массивом. – innoSPG

+0

Хорошо! Спасибо, это очень ясно. Я новичок в python, и иногда многочисленные массивы немного странны для меня. –