您現在的位置是:首頁 > 運動
如何獲取numpy陣列地址?如何與ctypes陣列共享記憶體?
陣列取地址怎麼取
1、如何獲取numpy陣列元素的真實地址?
在Python程式設計中,numpy是一個很好用的擴充套件程式庫,將其與SciPy庫和 Matplotlib繪相簿一起使用,可構成一個強大的類似於Matlab的科學計算環境,有助於我們透過 Python 學習資料科學或者機器學習。在Python中,當你定義了一個numpy型別的陣列後,它內部元素的真實地址如何獲得呢?
這裡可以透過numpy陣列的“__array_interface__”介面得到。
比如下面的例子:
import numpy as np from ctypes import * a = np。array([1, 2, 3, 4, 5], dtype=np。uint8) print(a。__array_interface__[‘data’])
上面程式定義了一個numpy型別的陣列a,執行後得到:
(1883707159072, False)
介面“__array_interface__”返回一個包含兩個元素的元組,其第1個元素即為a陣列內部元素存放的真實地址,第2個元素標明瞭該陣列是否為“只讀”屬性。
2、如何與ctypes庫建立的陣列共享記憶體空間?
對於Python程式設計人員來說,ctypes庫也是使用率比較高的一個庫,當呼叫第三方提供的動態庫連結庫函式時,它經常用於定義與C語言相容的資料型別變數,作為Python語言與C語言進行資料互動的橋樑。
那麼,如何使用ctypes庫定義一個與numpy共享記憶體空間的陣列變數呢?
仍以上面的例子,定義一個uint8型別的陣列b,與a陣列共享記憶體區域,可使用下面的程式碼:
b = (c_uint8*len(a))。from_address(a。__array_interface__[‘data’][0]) print(‘a =’, a, ‘\nb =’, b[:])
執行後得到:
a = [1 2 3 4 5] b = [1, 2, 3, 4, 5]
可見,使用ctypes庫的from_address函式定義了一個與a同地址的陣列b,打印出b的元素值後,其初始元素值確實與陣列a相同。
下面驗證一下,陣列a和b裡面的元素是否真正的佔用同一個記憶體區域。
先改變陣列a中第1個元素的值,執行下面的程式碼:
a[0] = 10 print(‘a =’, a, ‘\nb =’, b[:]}])
其執行結果為:
a = [10 2 3 4 5] b = [10, 2, 3, 4, 5]
可見,將陣列a中的第一個元素的值由1改成10後,b陣列中第一個元素也同步改變成10了。
緊接著,再改變b陣列中第二個元素的值,由2改為20:
b[1] = 20 print(‘a =’, a, ‘\nb =’, b[:])
其執行結果為:
a = [10 20 3 4 5] b = [10, 20, 3, 4, 5]
顯然,陣列a中第二個元素的值也同步改變為20了。
因此,陣列a與陣列b確實是佔用的同一個記憶體地址空間。
另外,也可以透過陣列b再定義一個與b共享記憶體區域的numpy陣列c,使用下面的程式碼即可:
c = np。frombuffer(b, dtype=np。uint8)
大家可以自行驗證陣列a、b、c是否為同一個記憶體空間。
3、結論
上面的例子表明,在Python程式設計中,numpy型別的陣列與ctypes型別的陣列可以進行互換,比如,可以使用numpy庫進行復雜的運算後,再轉換成ctypes型別的陣列,傳遞到第3方的動態庫dll函式中作進一步的處理,這樣,在某些場合下,既能使用numpy庫的強大運算功能,又可以使用第三方庫,來實現我們特定的處理需求。
本文由編碼那些事原創,歡迎關注+轉發+收藏+點贊,帶你一起長知識!
推薦文章
- 孕婦肚皮軟是女孩,肚皮硬是男孩?
可是孕期我聽說肚皮的軟硬程度也可以辨別寶寶的性別,有人說如果孕婦肚皮軟懷的就是女孩,如果肚皮硬,那麼懷的就是男孩,至於這種說法是怎麼來的,我就不確定了,只知道有人那麼說,後來我就特別注意了一下我的肚皮...
- “七夕”鮮花運輸帶旺航空貨運 玫瑰佔六成以上
結合今年“七夕”的市場情況和鮮花產量,南航貨運部預計其昆明出港鮮花運量同比去年將增長10%-15%...
- 罕見的36張照片:世界上最貴的腿毛,丹麥的美麗胖模特......
打造胖模特的人試圖告訴我們,人靠衣裝馬靠鞍,世界上沒有不好看得女孩,只有不會精心打扮的女孩...