Python ndarray с элементами разных типов - PullRequest
0 голосов
/ 03 июля 2018

Я хотел создать массив для хранения смешанных типов - string и int.

Следующий код не работал должным образом - все элементы были напечатаны как String.

>>> a=numpy.array(["Str",1,2,3,4])
>>> print a
['Str' '1' '2' '3' '4']
>>> print type(a[0]),type(a[1])
<type 'numpy.string_'> <type 'numpy.string_'>

Все элементы массива были напечатаны как 'numpy.string _'

Но, как ни странно, если я передаю один из элементов как "None", типы получаются по желанию:

>>> a=numpy.array(["Str",None,2,3,4])
>>> print a
['Str' None 2 3 4]
>>> print type(a[0]),type(a[1]),type(a[2])
<type 'str'> <type 'NoneType'> <type 'int'>

Таким образом, включение элемента «None» дает мне обходной путь, но мне интересно, почему это должно быть так. Даже если я не передам один из элементов как None, разве элементы не должны быть напечатаны при их передаче?

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Альтернативой добавлению None является явное указание типа dtype:

In [80]: np.array(["str",1,2,3,4])
Out[80]: array(['str', '1', '2', '3', '4'], dtype='<U3')
In [81]: np.array(["str",1,2,3,4], dtype=object)
Out[81]: array(['str', 1, 2, 3, 4], dtype=object)

Создание массива dtype объекта и заполнение его из списка - это еще один вариант:

In [85]: res = np.empty(5, object)
In [86]: res
Out[86]: array([None, None, None, None, None], dtype=object)
In [87]: res[:] = ['str', 1, 2, 3, 4]
In [88]: res
Out[88]: array(['str', 1, 2, 3, 4], dtype=object)

Здесь это не нужно, но имеет значение, когда вам нужен массив списков.

0 голосов
/ 03 июля 2018

Смешанные типы в NumPy настоятельно не рекомендуются. Вы теряете преимущества векторизованных вычислений. В данном случае:

  • Для вашего первого массива NumPy принимает решение преобразовать ваш массив в единый массив строк из 3 или менее символов.
  • Для вашего второго массива None недопустимо в качестве "строковой" переменной в NumPy, поэтому NumPy использует стандартный object dtype. object dtype представляет коллекцию указателей на произвольные типы.

Это можно увидеть при печати атрибутов dtype ваших массивов:

print(np.array(["Str",1,2,3,4]).dtype)     # <U3
print(np.array(["Str",None,2,3,4]).dtype)  # object

Этого вполне следует ожидать. NumPy сильно предпочитает однородные типы, как, впрочем, и любые значимые вычисления. В противном случае Python list может быть более подходящей структурой данных.

Более подробное описание приоритетов NumPy dtype смотрите в:

...