Создайте массив numpy с столбцами dtypes - PullRequest
1 голос
/ 09 мая 2020

Так что я действительно отказываюсь от этого .. Я хотел бы предварительно выделить огромный 2d- numpy массив с shape(10000000,3) с одним определением c dtype на столбец.

Пример:

    a         b        c     
 -------- --------- -------- 
  uint32   float32   uint8   
  ------   ------    ------  
  90       2.43      4       
  100      2.42      2       
  123      2.33      1   

Итак, из документации Я могу создать 2-мерный массив следующим образом:

arr = np.zeros((4,3))                                                                                                                                                                                          
arr                                                                                                                                                                                                            
Out[6]: 
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

Пока хорошо, но как насчет dtypes?

In [16]: arr.dtype                                                                                                                                                                                                     
Out[16]: dtype('float64')

All float - Итак, давайте определим dtype:

dtype_L1 = np.dtype({'names': ['a', 'b', 'c'], 
               'formats': [np.uint32, np.float32, np.uint8]})

И сравним оба:

In [25]: arr_dtype = np.zeros((4,3), dtype=dtype_L1)                                                                                                                                                                   

In [26]: arr = np.zeros((4,3))                                                                                                                                                                                         

In [27]: arr[0,0]                                                                                                                                                                                                      
Out[27]: 0.0

In [28]: arr_dtype[0,0]                                                                                                                                                                                                
Out[28]: (0, 0., 0)

In [29]: type(arr_dtype[0,0])                                                                                                                                                                                          
Out[29]: numpy.void

In [30]: type(arr[0,0])                                                                                                                                                                                                
Out[30]: numpy.float64

In [31]: arr.shape                                                                                                                                                                                                     
Out[31]: (4, 3)

In [32]: arr_dtype.shape                                                                                                                                                                                               
Out[32]: (4, 3)

Итак - я не видите, почему arr_dtype не то же самое, что arr, просто с другими dtype на столбец. Кто-нибудь может указать направление, пожалуйста? Похоже, я создаю массив со слишком большими размерами ..:

** Обновление: одно измерение слишком глубокое ..? **

>>> arr[0,0]
0 ## Correct

>>> arr_dtype[0,0]
(0, 0., 0) 

Здесь действительно хранится массив dtyped ?! Если посмотреть на одно измерение глубже:

>>> type(arr_dtype[0,0][0])
<class 'numpy.uint32'>
>>> type(arr_dtype[0,0][1])
<class 'numpy.float32'>
>>> type(arr_dtype[0,0][2])
<class 'numpy.uint8'>
# all good - But one level too deep.
  • Ожидаемое: numpy выводит матрицу 4x3, где каждый элемент - это число. 12 чисел вообще верны.
  • Наблюдается: numpy выводит матрицу 4x3, где каждый элемент представляет собой структуру shape (3,). Итак, у меня есть поля 4x3x3 = 36 чисел.

Так можно ли применить dtype по-другому?

Окончательное решение

Вам нужно решить, что важнее: экономия места или хранение всех данных в одном array? В одном массиве может быть только один dtype. Поэтому, если вам нужны разные типы данных, go для нескольких массивов с одинаковой длиной оси Y. В противном случае создайте его просто как arr_dtype = np.zeros((4,3), dtype=np.float32) и обязательно установите dtype на правильный тип для каждого массива. Спасибо за комментарии!

Ответы [ 2 ]

1 голос
/ 11 мая 2020

Считайте строку в вашем массиве отдельным элементом. Именно это и делает для вас составной dtype. Вы можете определить свой dtype как

d1 = np.dtype({'names': ['a', 'b', 'c'], 
               'formats': [np.uint32, np.float32, np.uint8]})

Это означает, что у вас есть массив из 3 столбцов. Вы назначаете ему что-то вроде

arr = np.empty(10000, dtype=d1)

Замените zeros на empty по своему усмотрению. Результатом является массив (10000, 3), хотя он выглядит как массив (10000,). Вы можете извлекать представления в отдельные столбцы, используя имена полей, например:

arr['a']
0 голосов
/ 09 мая 2020

arr_dtype - это структурированный массив с полями (здесь 'a', 'b' и 'c'), которым вы можете назначать разные типы данных. Каждый элемент структурированного массива является структурой, а элементы структуры (соответствующие полям) могут иметь разные типы данных (технически все элементы arr_dtype имеют один и тот же тип, который в данном случае является структурой numpy.void. Это элементы этого numpy.void объекта, который может иметь разные типы данных (другими словами, numpy элементы массива всегда однородны). arr, с другой стороны, представляет собой неструктурированный массив, все элементы которого имеют один и тот же тип данных. Каждый элемент неструктурированного массива представляет собой отдельный объект (в данном случае числа).

Проверьте вывод, чтобы увидеть разницу:

arr_dtype
[[(0, 0., 0) (0, 0., 0) (0, 0., 0)]
 [(0, 0., 0) (0, 0., 0) (0, 0., 0)]
 [(0, 0., 0) (0, 0., 0) (0, 0., 0)]
 [(0, 0., 0) (0, 0., 0) (0, 0., 0)]]

arr
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
...