您現在的位置是:首頁 > 運動
如何獲取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庫的強大運算功能,又可以使用第三方庫,來實現我們特定的處理需求。
本文由編碼那些事原創,歡迎關注+轉發+收藏+點贊,帶你一起長知識!
推薦文章
- 詹姆斯很多紀錄也許會被後輩們打破,但這5個只能被仰視,破不了
詹姆斯創造紀錄的能力,放眼歷史都是獨一檔,詹姆斯從奧尼爾巔峰尾,經歷四大前鋒、馬刺零號特工、奇才苦主、活塞五虎、凱爾三巨頭、四星老鷹、雙雄(格蘭傑,喬治)步行者、雷霆三少、四星半勇士,可以說從四大前鋒巔峰期大球時代打到現在小球時代,他創造的...
- 中證協新年第一調研:資管、代銷等五類業務有望推行電子簽約,觸及多個痛點
1.監管規則未明確要求電子簽約方式簽署衍生品協議及交易確認書2.公司內部協議簽署審批流程暫不支援電子簽約方式3.目前衍生品協議及交易確認書籤約筆數少,沒有動力改變原有紙質蓋章方式和審批流程4.較難推動客戶改變原有紙質蓋章的協議簽署習慣5.自...
- 北約14國率先行動,發起“核演習”,準備要正面“硬剛”俄羅斯?
很顯然,美國在這兩個方面同時進行,北約的核威懾演習,也會讓俄羅斯感到巨大的壓力...