[英]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
仍具有與以前相同的大小,但是,每個元素中的數組的長度已更改。 上面的示例可以工作,但是要花很長時間(我在代碼中做了很多次)。 有更快的方法嗎? 如果可以明確說明,則按以下方式創建m1
和m2
:
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.