爲numpy.frombuffer
函數的文檔具體說,所產生的陣列將是一維:如何從多維緩衝區初始化一個NumPy數組?
解釋一個緩衝區作爲1維陣列。
我不確定此報價的後果。文檔只是告訴我,生成的數組將是一維的,但從不說輸入緩衝區必須描述一維對象。
我在C++中有一個(2D)Eigen matrix。我想創建一個Python buffer,它描述矩陣的內容。然後,我想用這個緩衝區來初始化我的NumPy數組,並將它提供給我的Python腳本。目標是將信息傳遞給Python而不復制數據並允許python修改矩陣(例如初始化矩陣)。
的numpy.frombuffer
的C-API當量PyArray_FromBuffer
,並且它也共享單維短語,但它有更多的文檔(重點煤礦):
PyObject* PyArray_FromBuffer(PyObject* buf, PyArray_Descr* dtype, npy_intp count, npy_intp offset)
構建的一維從導出緩衝區協議(或具有返回導出緩衝區協議的對象的屬性__buffer__)的對象buf導出單個類型的ndarray。首先會嘗試寫入緩衝區,然後再嘗試讀取緩衝區。返回數組的NPY_ARRAY_WRITEABLE標誌將反映哪一個成功。假定數據從對象的內存位置開始的偏移量字節處開始。緩衝區中數據的類型將根據數據類型描述符dtype進行解釋。如果count爲負,那麼它將根據緩衝區的大小和請求的itemsize來確定,否則,count表示應該從緩衝區轉換多少個元素。
「單段」是指它不能包含使用的填充,例如對齊矩陣的行嗎?在這種情況下,我搞砸了,因爲我的矩陣可以很好地使用需要填充的對齊策略。
回到原來的問題:
有我的方式來創建一個與NumPy陣列,其與預先存在的緩衝共享內存?
備註:有在GitHub上的一個項目叫Eigen3ToPython,其目的是與蟒蛇連接徵,但它並不支持內存共享(重點煤礦):
(然而, 內存不是兩種表示之間共享)這個庫允許:[...]從numpy的陣列(
np.array
)以透明的方式轉換爲/
編輯 有人可能會指出了同樣的同名問題Numpy 2D- Array from Buffer?。不幸的是,這裏給出的解決方案似乎不適合我的情況,因爲生成的二維數組不會與原始緩衝區共享內存。
編輯:如何在數據本徵
徵2D矩陣映射在一維緩衝存儲器,通過使用跨距訪問組織的。例如,雙精度3×2矩陣需要6倍,即48個字節。一個48字節的緩衝區被分配。此緩衝區中的第一個元素表示矩陣中的[0, 0]
條目。
爲了訪問該元素[i, j]
,下面的公式:
double* v = matrix.data() + i*matrix.rowStride() + j*matrix.colStride()
,其中matrix
是矩陣對象和它的成員函數data()
,rowStride()
和colStride()
返回分別的起始地址緩衝區,兩個連續行之間的距離以及兩個連續列之間的距離(浮點格式大小的倍數)。
默認情況下,Eigen使用列主要格式,因此rowStride() == 1
,但它也可以配置爲使用行主格式,並使用colStride() == 1
。
另一個重要的配置選項是對齊。數據緩衝區很可能包含一些不需要的值(即,不是矩陣的一部分的值),以使列或行開始於對齊的地址。這使得矩陣上的操作可以進行矢量化。在上面的例子中,假設列優先格式和16字節對齊,下面的矩陣
3 7
1 -2
4 5
可以存儲贏取以下緩衝液:
0 0 3 1 4 0 7 -2 5 0
的0值被稱爲填充。開始處的兩個0可能是必要的,以確保實際數據的開始對齊到相同的邊界。 (請注意,data()
成員函數將返回3的地址)。在這種情況下,爲步幅的行和列是
rowStride: 1
colStride: 4
(而在未對齊的情況下,它們將是1和3分別。)
Numpy需要一個C連續緩衝區,即沒有填充的行主結構。如果Eigen沒有插入填充,那麼可以非常容易地解決列主要特徵矩陣的行主要問題的問題:將緩衝區傳遞給一個numpy數組,然後重構和轉置結果ndarray
。我設法完美地完成了這項工作。
但是在Eigen插入填充的情況下,使用這種技術無法解決問題,因爲ndarray
仍然會看到數據中的零,並認爲它們是矩陣的一部分,同時丟棄了某些值數組的末尾。而這是我問一個解決方案的問題。
現在,作爲一個方面的評論,既然我們在循環中有@ggael的運氣,誰可能會說出一些光,我不得不承認,我從來沒有Eigen在我的矩陣中插入任何填充。我在Eigen文檔中似乎沒有發現任何填充。但是,我希望對齊策略能夠對齊每一列(或行),而不僅僅是第一列。我的期望錯了嗎?如果我是,那麼整個問題不適用於Eigen。但是它適用於我正在使用的其他圖書館,這些圖書館採用了上述的校準策略,所以請在回答問題時不要考慮最後一段。
您是否嘗試過直接使用['np。]創建NumPy數組。ndarray'](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.html)?根據文檔,它有一個'buffer'參數。 – unutbu
'numpy'數據存儲在一個平面緩衝區中。所以一個緩衝區(一組連續的字節)包含4000個字節,我們指定dtype'int32','frombuffer'應該給一個(1000)形狀的數組。隨後的「重塑」可以使其成爲2D。在numpy多維度是由形狀和步幅屬性,而不是數據。 – hpaulj
解釋'Eigen'如何存儲其數據。它是一個簡單的1d緩衝區嗎?或者更像是指向指針的「C」指針? – hpaulj