#python #arrays #numpy #object #dtype
Вопрос:
У меня есть NumPy ndarray A размером (k,n,m) int, представляющий k изображений, каждое размером nxm пикселей. Я хотел бы преобразовать его в dtype=объект ndarray B размера (k,) , содержащий каждое из отдельных изображений в виде ndarray размера (n,m).
Я могу сделать это с помощью цикла for (ниже), но есть ли более элегантный/простой способ?
A = np.arange(2*3*4).reshape(2,3,4)
B = np.empty(A.shape[0],dtype=object)
for i in range(0,A.shape[0]):
B[i] = A[i]
print(B)
array([array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]), array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])], dtype=object)
Комментарии:
1.
B[:]=list(A)
может сработать. Избежать ошибок трансляции в таком задании может быть непросто. Это может быть не быстрее, так как действие в основном одно и то же.
Ответ №1:
Ваши массивы:
In [37]: A = np.arange(2*3*4).reshape(2,3,4)
...:
...: B = np.empty(A.shape[0],dtype=object)
...: for i in range(0,A.shape[0]):
...: B[i] = A[i]
...:
In [38]: B
Out[38]:
array([array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]), array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])], dtype=object)
Альтернативный способ присвоения A
B
. Короче, но не обязательно быстрее.
In [39]: B[:]=list(A)
In [40]: B
Out[40]:
array([array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]), array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])], dtype=object)
Прямое назначение не работает; это должен быть список массивов, а не массив:
In [41]: B[:]=A
Traceback (most recent call last):
File "<ipython-input-41-b3ca91787565>", line 1, in <module>
B[:]=A
ValueError: could not broadcast input array from shape (2,3,4) into shape (2,)
Другой ответ не работает:
In [42]: np.array([*A], dtype=object)
Out[42]:
array([[[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]], dtype=object)
Комментарии:
1. видите ли вы способ сделать это с помощью конструкции np.array? возможно, указав размер dtype ?
2. Зачем бы я дал этот ответ, если бы был «лучший»? 🙁 Похоже, вы не понимаете, насколько массивы dtype объектов близки к спискам.
3.
object
dtype не принимает «размер». Он просто указывает указатель на объект, то же самое, что содержится в списке.4. Спасибо! хотя объект ndarray, в отличие от списков, должен иметь форму
5.
np.array
не берет аshape
, только аndmin
.np.array
пытается создать как можно более высокий размерный массив, как показано в другом ответе. Поэтому сначала мы должны указать желаемую форму массива.np.array
это функция высокого уровня, которая скрывает много логики.np.ndarray
это конструктор низкого уровня, но обычно мы его не используем.
Ответ №2:
Вместо этого вы можете использовать распаковку, чтобы получить более чистый код:
B = np.array([*A], dtype=object)
ИЗМЕНИТЬ: Это не работает, так как внутренние элементы также преобразуются в тип объекта.
Комментарии:
1. Вы это проверяли?
2. Да, я проверил это, результат был тот же. Я заметил опечатку, теперь я ее исправил
3. Смотрите тест в моем ответе.
4. Да, вы правы, это не работает, так как внутренние массивы также превращаются в объекты (я пропустил это). Моя ошибка, спасибо за исправление.