Numpy объединение двух 2D массивов при сохранении отдельных данных - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть NUMPY массивов A и B:

A = [
    [1, 2 ,3, 4, 5, 6, 7, 8, 9],
    [1, 1 ,1, 1, 5, 0, 7, 8, 3],
    ..etc
]

B = [
    [1, 2 ,3],
    [1, 0 ,1],
    ..etc
]

Оба 2D-массива имеют одинаковое количество строк. Я хотел бы создать массив C:

C = [
    [ [1, 2 ,3, 4, 5, 6, 7, 8, 9], [1, 2 ,3] ],
    [ [1, 1 ,1, 1, 5, 0, 7, 8, 3], [1, 0 ,1] ],
    ..etc
]

Я также хотел бы знать, как я могу сделать обратное. значение go от C до A и B. Я пробовал такие функции, как добавление, объединение и стек. но я не могу понять, как это сделать.

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Я обновил свой код и применил что-то похожее на то, что упоминалось здесь :

import numpy as np
A = [
[1, 2 ,3, 4, 5, 6, 7, 8, 9],
[1, 1 ,1, 1, 5, 0, 7, 8, 3]
]

B = [
[1, 2 ,3],
[1, 0 ,1]
]

aArray=np.array(A)
bArray=np.array(B)

x_z = map(tuple,aArray)
y_z = map(tuple,bArray)
cArray=[list(i) for i in zip(x_z, y_z)]
cArray

Вывод:

[[(1, 2, 3, 4, 5, 6, 7, 8, 9), (1, 2, 3)],
 [(1, 1, 1, 1, 5, 0, 7, 8, 3), (1, 0, 1)]]
1 голос
/ 16 апреля 2020

Вопреки вашему описанию, A и B являются списками

In [414]: A = [ 
     ...:     [1, 2 ,3, 4, 5, 6, 7, 8, 9], 
     ...:     [1, 1 ,1, 1, 5, 0, 7, 8, 3]]                                                             
In [415]: B = [ 
     ...:     [1, 2 ,3], 
     ...:     [1, 0 ,1]]                       

Как показывают другие, просто использовать zip для чередования элементов этих 2 списков:

In [416]: C = [[a,b] for a,b in zip(A,B)]                                                              
In [417]: C                                                                                            
Out[417]: 
[[[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3]],
 [[1, 1, 1, 1, 5, 0, 7, 8, 3], [1, 0, 1]]]

Если вы хотите, чтобы C был массивом, вам нужно создать массив dtype объекта нужного размера и заполнить его:

In [418]: C = np.empty((2,2),object)                                                                   
In [419]: C[:,0] = A                                                                                   
In [420]: C[:,1] = B                                                                                   
In [421]: C                                                                                            
Out[421]: 
array([[list([1, 2, 3, 4, 5, 6, 7, 8, 9]), list([1, 2, 3])],
       [list([1, 1, 1, 1, 5, 0, 7, 8, 3]), list([1, 0, 1])]], dtype=object)

Однако, если A действительно массив, это назначение не будет работать:

In [422]: C[:,0] = np.array(A)                                                                         
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-422-d1283e1b548a> in <module>
----> 1 C[:,0] = np.array(A)

ValueError: could not broadcast input array from shape (2,9) into shape (2)

Нельзя присвоить массив A этому объекту C, но это сложно.

Что касается обратного

In [425]: C[:,0]                                                                                       
Out[425]: 
array([list([1, 2, 3, 4, 5, 6, 7, 8, 9]),
       list([1, 1, 1, 1, 5, 0, 7, 8, 3])], dtype=object)

Более естественный способ объединения массивов, таких как A и B, заключается в следующем:

In [424]: np.hstack((A,B))                                                                             
Out[424]: 
array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3],
       [1, 1, 1, 1, 5, 0, 7, 8, 3, 1, 0, 1]])

В этом новом массиве A и B теряют свою идентичность, хотя их легко восстановить с помощью индексации:

In [426]: np.hstack((A,B))[:,:-3]                                                                      
Out[426]: 
array([[1, 2, 3, 4, 5, 6, 7, 8, 9],
       [1, 1, 1, 1, 5, 0, 7, 8, 3]])

Короче говоря, желаемое C несколько двусмысленно и не является самой естественной структурой numpy. Оригинальный zip-список не уступает - он может быть даже быстрее.

===

Играя с этими списками, я обнаружил, что

In [430]: np.array((A,B))                                                                              
Out[430]: 
array([[list([1, 2, 3, 4, 5, 6, 7, 8, 9]),
        list([1, 1, 1, 1, 5, 0, 7, 8, 3])],
       [list([1, 2, 3]), list([1, 0, 1])]], dtype=object)

This a ( 2,2) массив объектов списков. И его транспонирование дает тот же массив, что и в [421]:

In [431]: _.T                                                                                          
Out[431]: 
array([[list([1, 2, 3, 4, 5, 6, 7, 8, 9]), list([1, 2, 3])],
       [list([1, 1, 1, 1, 5, 0, 7, 8, 3]), list([1, 0, 1])]], dtype=object)

Но, пытаясь сделать то же самое с массивами, я сталкиваюсь с той же ошибкой, что и в [422]. Фактически [422] может объяснить эту ошибку:

In [432]: np.array((np.array(A),np.array(B)))                                                          
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-432-a4327b98cfe7> in <module>
----> 1 np.array((np.array(A),np.array(B)))

ValueError: could not broadcast input array from shape (2,9) into shape (2)

Если A и B совпадают по форме, np.array((A,B)) является трехмерным массивом. Часто, когда входные данные различаются по форме, результатом является массив типа dtype. Но для некоторых комбинаций, таких как эта, возникает ошибка. Так что np.array((A,B)) не является надежным способом создания массива dtype объекта.

1 голос
/ 16 апреля 2020

Вы можете zip() их:

A = [
    [1, 2 ,3, 4, 5, 6, 7, 8, 9],
    [1, 1 ,1, 1, 5, 0, 7, 8, 3],
]

B = [
    [1, 2 ,3],
    [1, 0 ,1],
]

C = list(map(list, zip(A, B)))

C будет:

[[[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3]],
 [[1, 1, 1, 1, 5, 0, 7, 8, 3], [1, 0, 1]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...