указать dtype каждого объекта в массиве python - PullRequest
6 голосов
/ 16 сентября 2010

Следующий фрагмент создает «типичный тестовый массив», целью которого является тестирование ассортимента вещей в моей программе. Есть ли способ или вообще возможно изменить тип элементов в массиве?

import numpy as np
import random
from random import uniform, randrange, choice

# ... bunch of silly code ...

def gen_test_array( ua, low_inc, med_inc, num_of_vectors ):
  #typical_array = [ zone_id, ua, inc, veh, pop, hh, with_se, is_cbd, re, se=0, oe]
  typical_array = np.zeros( shape = ( num_of_vectors, 11 ) )

  for i in range( 0, num_of_vectors ):
    typical_array[i] = [i, int( ua ), uniform( low_inc / 2, med_inc * 2 ), uniform( 0, 6 ),
                        randrange( 100, 5000 ), randrange( 100, 500 ),
                        choice( [True, False] ), choice( [True, False] ),
                        randrange( 100, 5000 ), randrange( 100, 5000 ),
                        randrange( 100, 5000 ) ]

  return typical_array

Ответы [ 2 ]

9 голосов
/ 16 сентября 2010

Способ сделать это в numpy - использовать структурированный массив .

Однако во многих случаях, когда вы используете разнородные данные, простой список Python выглядит как намного лучший выбор.(Или, хотя он не был широко доступен, когда был написан этот ответ, pandas.DataFrame абсолютно идеален для этого сценария.)

Несмотря на это, приведенный выше пример будет отлично работать как "нормальный" numpyмассив.Вы можете просто сделать все плавающим в приведенном вами примере.(Все выглядит как int, за исключением двух столбцов с плавающей точкой ... Bools можно легко представить в виде целых чисел.)

Тем не менее, чтобы проиллюстрировать использование структурированных dtypes ...

import numpy as np

ua = 5 # No idea what "ua" is in your code above...
low_inc, med_inc = 0.5, 2.0 # Again, no idea what these are...

num = 100
num_fields = 11

# Use more descriptive names than "col1"! I'm just generating the names as placeholders
dtype = {'names':['col%i'%i for i in range(num_fields)],
                 'formats':2*[np.int] + 2*[np.float] + 2*[np.int] + 2*[np.bool] + 3*[np.int]}
data = np.zeros(num, dtype=dtype)

# Being rather verbose...
data['col0'] = np.arange(num, dtype=np.int)
data['col1'] = int(ua) * np.ones(num)
data['col2'] = np.random.uniform(low_inc / 2, med_inc * 2, num)
data['col3'] = np.random.uniform(0, 6, num)
data['col4'] = np.random.randint(100, 5000, num)
data['col5'] = np.random.randint(100, 500, num)
data['col6'] = np.random.randint(0, 2, num).astype(np.bool)
data['col7'] = np.random.randint(0, 2, num).astype(np.bool)
data['col8'] = np.random.randint(100, 5000, num)
data['col9'] = np.random.randint(100, 5000, num)
data['col10'] = np.random.randint(100, 5000, num)

print data

Что дает массив из 100 элементов с 11 полями:

array([ (0, 5, 2.0886534380436226, 3.0111285613794276, 3476, 117, False, False, 4704, 4372, 4062),
       (1, 5, 2.0977199579338115, 1.8687472941590277, 4635, 496, True, False, 4079, 4263, 3196),
       ...
       ...
       (98, 5, 1.1682309811443277, 1.4100766819689299, 1213, 135, False, False, 1250, 2534, 1160),
       (99, 5, 1.746554619056416, 5.210411489007637, 1387, 352, False, False, 3520, 3772, 3249)], 
      dtype=[('col0', '<i8'), ('col1', '<i8'), ('col2', '<f8'), ('col3', '<f8'), ('col4', '<i8'), ('col5', '<i8'), ('col6', '|b1'), ('col7', '|b1'), ('col8', '<i8'), ('col9', '<i8'), ('col10', '<i8')])
4 голосов
/ 16 сентября 2010

Цитирование первой строки главы 1 ссылки на NumPy:

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

Таким образом, каждый член массива должен быть одного типа.Здесь потеря общности по сравнению с обычными списками Python является компромиссом, который позволяет выполнять высокоскоростные операции над массивами: циклы могут выполняться без проверки типа каждого элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...