Becauuse NamedTuple
- это подкласс tuple
, построение массива объектов из L
приводит к массиву (n, 2), так же, как если бы мы указали его как список кортежей или список списков:
In [4]: np.array(L, object)
Out[4]:
array([[{'violet', 'blue'}, 4],
[{'blue', 'orange'}, 1],
[{'blue', 'green'}, 3],
[{'red', 'orange'}, 2]], dtype=object)
In [5]: _.shape
Out[5]: (4, 2)
Вот один трюк - сначала добавьте объект None
в список:
In [13]: arr = np.array(L+[None], object)[:-1]
In [14]: arr
Out[14]:
array([tuple(colors={'violet', 'blue'}, number=4),
tuple(colors={'blue', 'orange'}, number=1),
tuple(colors={'blue', 'green'}, number=3),
tuple(colors={'red', 'orange'}, number=2)], dtype=object)
In [15]: arr.shape
Out[15]: (4,)
In [16]: arr = np.reshape(arr,(2,2))
In [17]: arr
Out[17]:
array([[tuple(colors={'violet', 'blue'}, number=4),
tuple(colors={'blue', 'orange'}, number=1)],
[tuple(colors={'blue', 'green'}, number=3),
tuple(colors={'red', 'orange'}, number=2)]], dtype=object)
Я обнаружил в предыдущих вопросах, что frompyfunc
является наиболее удобным инструментом (иСамый быстрый) для доступа к элементам такого массива.
Наиболее эффективный способ установить атрибуты для объектов в массиве
In [18]: np.frompyfunc(lambda x: x.colors, 1,1)(arr)
Out[18]:
array([[{'violet', 'blue'}, {'blue', 'orange'}],
[{'blue', 'green'}, {'red', 'orange'}]], dtype=object)
Чтобы построить структурированный массив,мы можем сделать:
In [19]: arr1 = np.array(L, dtype=[('colors', object), ('number', int)])
In [20]: arr1
Out[20]:
array([({'violet', 'blue'}, 4), ({'blue', 'orange'}, 1),
({'blue', 'green'}, 3), ({'red', 'orange'}, 2)],
dtype=[('colors', 'O'), ('number', '<i8')])
NamedTuple
является подклассом tuple
, поэтому он работает как ввод данных (например, список кортежей).
In [22]: arr1['colors']
Out[22]:
array([{'violet', 'blue'}, {'blue', 'orange'}, {'blue', 'green'},
{'red', 'orange'}], dtype=object)
In [23]: arr1['number']
Out[23]: array([4, 1, 3, 2])
Инициализациямассив 1d и присвоение элементов работают:
In [30]: arr2 = np.empty(4, object)
In [31]: arr2[:] = L
In [32]: arr2
Out[32]:
array([tuple(colors={'violet', 'blue'}, number=4),
tuple(colors={'blue', 'orange'}, number=1),
tuple(colors={'blue', 'green'}, number=3),
tuple(colors={'red', 'orange'}, number=2)], dtype=object)
Заполнение np.empty((2,2), object)
будет немного сложнее.
Я могу построить массив объектов из полей структурированного массива(или любая другая пара списков входов) с:
In [44]: np.frompyfunc(NamedTuple, 2,1)(arr1['colors'], arr1['number'])
Out[44]:
array([tuple(colors={'violet', 'blue'}, number=4),
tuple(colors={'blue', 'orange'}, number=1),
tuple(colors={'blue', 'green'}, number=3),
tuple(colors={'red', 'orange'}, number=2)], dtype=object)