Создание массива с одним структурированным элементом, содержащим массив

#python #numpy #dtype

#python #numpy #dtype

Вопрос:

У меня есть dtype, подобный этому:

 >>> dt = np.dtype([('x', object, 3)])
>>> dt
dtype([('x', 'O', (3,))])
  

Одно поле с именем ‘x’, содержащее три указателя. Я хотел бы создать массив с одним элементом этого типа:

 >>> a = np.array([(['a', 'b', 'c'])], dtype=dt)
>>> b = np.array([(np.array(['a', 'b', 'c'], dtype=object))], dtype=dt)
>>> c = np.array((['a', 'b', 'c']), dtype=dt)
>>> d = np.array(['a', 'b', 'c'], dtype=dt)

>>> e = np.array([([['a', 'b', 'c']])], dtype=dt)
  

Все пять этих операторов дают один и тот же неверный результат:

 array([[(['a', 'a', 'a'],), (['b', 'b', 'b'],), (['c', 'c', 'c'],)]],
      dtype=[('x', 'O', (3,))])
  

Если я пытаюсь удалить внутренний список / массив, я получаю сообщение об ошибке:

 >>> f = np.array([('a', 'b', 'c')], dtype=dt)
ValueError: could not assign tuple of length 3 to structure with 1 fields.
  

Такая же ошибка возникает для

 >>> g = np.array(('a', 'b', 'c'), dtype=dt)
  

У меня закончились возможные комбинации, чтобы попробовать. Результат, который я ищу, это

  array([(['a', 'b', 'c'],)], dtype=[('x', 'O', (3,))])
  

Как мне создать массив, содержащий один элемент указанного dtype?

Пока единственный подход, который я нашел, — это ручное назначение:

 z = np.empty(1, dtype=dt)
z['x'][0, :] = ['a', 'b', 'c']
  

или

 z[0]['x'] = ['a', 'b', 'c']
  

Это кажется ненужным обходным путем для чего-то, что np.array должно быть в состоянии обрабатывать из коробки.

Комментарии:

1. Может быть, должно быть dt = np.dtype([('x', object, 3)]) ?

2. Похоже, что в некоторых ваших попытках создать кортеж длиной 1 отсутствует требуемая конечная запятая. Попробуйте a = np.array([(['a', 'b', 'c'],)], dtype=dt)

3. Я также только что столкнулся с той же задачей сегодня, единственный способ, которым я узнал, — это сначала создать пустой / нулевой массив np.object_ dtype, а затем назначить ему необходимые элементы.

4. @Arty. Я наткнулся на это, пытаясь ответить на ваш предыдущий вопрос 🙂

5. @WarrenWeckesser. Я исправил dtype. Я скопировал его в свою консоль, осознал свою ошибку и только скопировал правильный вывод обратно 🙂

Ответ №1:

 In [44]: dt = np.dtype([('x', object, 3)])   # corrected
In [45]: dt
Out[45]: dtype([('x', 'O', (3,))])
In [46]: np.empty(3, dt)
Out[46]: 
array([([None, None, None],), ([None, None, None],),
       ([None, None, None],)], dtype=[('x', 'O', (3,))])
In [47]: np.array([(['a','b','c'],)], dt)
Out[47]: array([(['a', 'b', 'c'],)], dtype=[('x', 'O', (3,))])
  

Форматирование ввода должно соответствовать форматированию вывода.

 In [48]: arr = np.empty(3, dt)
In [49]: arr['x']
Out[49]: 
array([[None, None, None],
       [None, None, None],
       [None, None, None]], dtype=object)
In [50]: arr['x'][0]
Out[50]: array([None, None, None], dtype=object)
In [51]: arr['x'][0] = ['a','b','c']
In [52]: arr
Out[52]: 
array([(['a', 'b', 'c'],), ([None, None, None],), ([None, None, None],)],
      dtype=[('x', 'O', (3,))])
  

Комментарии:

1. Понял. Отсутствует запятая. Я почти испытываю искушение закрыть как опечатку, но ответ хороший.

2. Я думаю, вам не хватает присвоения empty(...) to arr,