簡體   English   中英

結合兩個包含數組的Numpy矩陣

[英]Combining two Numpy matrices containing arrays

我有兩個尺寸分別為125、30、360的矩陣(m1和m2),其中包含不同長度的數組。 我想做的是將這些數組逐個元素地連接起來。 現在,我使用for循環來做到這一點:

for i in range(125):
    for j in range(30):
        for k in range(360):
            m1[i, j, k] = np.hstack(m1[i, j, k], m2[i, j, k])

因此,生成的m1仍具有與以前相同的大小,但是,每個元素中的數組的長度已更改。 上面的示例可以工作,但是要花很長時間(我在代碼中做了很多次)。 有更快的方法嗎? 如果可以明確說明,則按以下方式創建m1m2

m1 = np.zeros([125, 30, 360], dtype=np.ndarray)
for i in range(125):
    for j in range(30):
        for k in range(360):
            m1[i,j,k] = np.array([])

編輯:我上面的文字有點不清楚,這導致了一些混亂。 因此,我在下面創建了一個我想做的小例子。

步驟1:創建m1和m2。

m1 = np.zeros([2, 2], dtype=np.ndarray)
m2 = np.zeros([2, 2], dtype=np.ndarray)
for i in range(2):
    for j in range(2):
        m1[i, j] = np.array(range(i+j))
        m2[i, j] = np.array(range(i+j+1))

步驟1導致:

m1 = array([[array([], dtype=float64), array([0])],
  [array([0]), array([0, 1])]], dtype=object)
m2 = array([[array([0]), array([0, 1])],
  [array([0, 1]), array([0, 1, 2])]], dtype=object)

步驟2:串聯m1和m2。

for i in range(2):
    for j in range(2):
        m1[i, j] = np.hstack((m1[i, j], m2[i, j]))

步驟2導致:

m1 = array([[array([ 0.]), array([0, 0, 1])],
  [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object)

因此,問題是:步驟2可以更快地完成嗎?

In [164]: m1 = np.zeros([2, 2], dtype=np.ndarray)
     ...: m2 = np.zeros([2, 2], dtype=np.ndarray)
     ...: for i in range(2):
     ...:     for j in range(2):
     ...:         m1[i, j] = np.array(range(i+j))
     ...:         m2[i, j] = np.array(range(i+j+1))
     ...:         

結果是2個2d的dtype對象數組。 dtype=np.ndarray成為object為任何不是在限定的一組dtypes

In [165]: m1
Out[165]: 
array([[array([], dtype=float64), array([0])],
       [array([0]), array([0, 1])]], dtype=object)
In [166]: m1.shape
Out[166]: (2, 2)
In [167]: m2.shape
Out[167]: (2, 2)
In [168]: m1[0,0]
Out[168]: array([], dtype=float64)

m1是2d數組,其中包含指向內存中其他位置的對象的指針。 在您的情況下,它們是數組,但它們可以是列表,字典, None ,字符串或數字甚至函數。

這樣的數組可以描述為一個榮耀的列表,因為它具有形狀(2d),可以重塑,並且在某些情況下甚至可以將數學運算投影到元素上(例如m1*2 )。 或者它可能是一個降級的列表,因為它沒有像append這樣的方法。

在大多數情況下,此類數組上的numpy操作需要Python級別的迭代。 並且具有需要雙環或等效環的2d形狀。

與任何nd數組一樣,您可以通過扁平化來解決嵌套循環的問題。 例如,使用列表理解:

In [173]: [np.concatenate((a,b)) for a,b in zip(m1.flat, m2.flat)]
Out[173]: [array([ 0.]), array([0, 0, 1]), array([0, 0, 1]), array([0, 1, 0, 1, 2])]
In [174]: np.array([np.concatenate((a,b)) for a,b in zip(m1.flat, m2.flat)]).reshape(2,2)
Out[174]: 
array([[array([ 0.]), array([0, 0, 1])],
       [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object)

在這種情況下, frompyfunc可能會有用,並為您照顧更高維度。 我發現它在更明確的循環上提供了適中的速度(最多2倍):

In [177]: f=np.frompyfunc(lambda a,b: np.concatenate((a,b)),2,1)
In [178]: f(m1,m2)
Out[178]: 
array([[array([ 0.]), array([0, 0, 1])],
       [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object)

總而言之,與對nd數值數組進行的類似操作相比,對對象數組進行任何按元素進行的操作都將較慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM