Создание массива numy из набора - PullRequest
2 голосов
/ 28 октября 2019

Я заметил следующее поведение, демонстрируемое массивами numpy:

>>> import numpy as np
>>> s = {1,2,3}
>>> l = [1,2,3]
>>> np.array(l)
array([1, 2, 3])
>>> np.array(s)
array({1, 2, 3}, dtype=object)
>>> np.array(l, dtype='int')
array([1, 2, 3])
>>> np.array(l, dtype='int').dtype
dtype('int64')
>>> np.array(s, dtype='int')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'set'

Есть две вещи, на которые следует обратить внимание:

  1. Создание массива из набора приводит к массиву dtype будучи object
  2. Попытка указать dtype приводит к ошибке, которая предполагает, что набор обрабатывается как отдельный элемент, а не как итеративный.

Чего мне не хватает -Я не до конца понимаю, какой кусок питона я пропускаю. Set является изменяемым объектом, очень похожим на список.

РЕДАКТИРОВАТЬ: кортежи работают нормально:

>>> t = (1,2,3)
>>> np.array(t)
array([1, 2, 3])
>>> np.array(t).dtype
dtype('int64')

Ответы [ 4 ]

6 голосов
/ 28 октября 2019

Фабрика array лучше всего работает с sequence объектами, которые не являются набором. Если вам не важен порядок элементов и вы знаете, что они являются целыми числами или могут быть преобразованы в int, тогда вы можете использовать np.fromiter

np.fromiter({1,2,3},int,3)
# array([1, 2, 3])

Второй (dtype) аргумент является обязательным;последний аргумент (число) является необязательным, если он может повысить производительность.

2 голосов
/ 28 октября 2019

Документация np.array говорит, что аргумент object должен быть "массивом, любым объектом, представляющим интерфейс массива, объектом, метод которого __array__ возвращает массив, или любым(вложенная) последовательность"(выделение добавлено).

Набор не является последовательностью . В частности, наборы неупорядочены и не поддерживают метод __getitem__. Следовательно, вы не можете создать массив из набора, как вы пытаетесь с помощью списка.

1 голос
/ 28 октября 2019

Как видно из синтаксиса использования фигурных скобок, set более тесно связаны с dict, чем с list. Вы можете решить это очень просто, превратив набор в list или tuple перед преобразованием в массив:

>>> import numpy as np
>>> s = {1,2,3}
>>> np.array(s)
array({1, 2, 3}, dtype=object)
>>> np.array(list(s))
array([1, 2, 3])
>>> np.array(tuple(s))
array([1, 2, 3])

Однако это может быть слишком неэффективно для больших наборов, потому что list илиtuple функции должны пройти через весь set, прежде чем даже начинать создание массива. Лучшим методом было бы использовать set в качестве итератора:

>>> np.fromiter(s, int)
array([1, 2, 3])
0 голосов
/ 28 октября 2019

Numpy ожидает, что аргумент будет списком, он не понимает установленный тип, поэтому он создает массив объектов (это будет то же самое, если вы передадите любой другой непоследовательный объект). Вы можете создать массив с набором, сначала преобразовав набор в список numpy.array(list(my_set)). Надеюсь это поможет.

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