通常,在創建一個 numpy 字串陣列時,我們可以執行類似的操作
import numpy as np
np.array(["Hello world!", "good bye world!", "whatever world"])
>>> array(['Hello world!', 'good bye world!', 'whatever world'], dtype='<U15')
現在的問題是,我得到了一個來自外部 C 函式的長位元組陣列,如下所示:
b'Hello world!\x00<some rubbish bytes>good bye world!\x00<some rubbish bytes>whatever world\x00<some rubbish bytes>'
保證每 32 個位元組都是一個以 null 結尾的字串(即,\x00在字串的有效部分附加一個位元組),我需要將這個長位元組陣列轉換為類似的東西array(['Hello world!', 'good bye world!', 'whatever world'], dtype='<U15'),最好是就地(即,沒有記憶體副本)。
這就是我現在所做的:
for i in range(str_count):
str_arr[i] = byte_arr[i * 32: (i 1) * 32].split(b'\x00')[0].decode('utf-8')
str_arr_np = np.array(str_arr),
它可以作業,但有點尷尬并且沒有就地完成(位元組至少復制一次,如果不是兩次)。有沒有更好的方法?
uj5u.com熱心網友回復:
如果您可以將 C 端的資料清零,那么您可以使用np.frombuffer它,它的效率將與您合理預期的一樣高:
因此,如果您可以將資料歸零,那么可以使用它來讀取numpy.frombuffer它,并且它可能會像您可以合理期望的那樣高效:
>>> raw = b'hello world\x00\x00\x00\x00\x00Good Bye\x00\x00\x00\x00\x00\x00\x00\x00'
>>> np.frombuffer(raw, dtype='S16')
array([b'hello world', b'Good Bye'], dtype='|S16')
當然,這會為您提供一個位元組字串,而不是 unicode 字串,盡管在您的情況下這可能是可取的。
請注意,以上依賴于剝離尾隨空位元組的內置行為,如果之后有垃圾,它將不起作用:
>>> data = b'hello world\x00aaaaGood Bye\x00\x00\x00\x00\x00\x00\x00\x00'
>>> np.frombuffer(data, dtype='S16')
array([b'hello world\x00aaaa', b'Good Bye'], dtype='|S16')
注意,這不應該復制,注意:
>>> arr = np.frombuffer(raw, dtype='S16')
>>> arr
array([b'hello world', b'Good Bye'], dtype='|S16')
>>> arr[0] = b"z"*16
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: assignment destination is read-only
但是,如果目標不是只讀的,那么假設您有一個bytearray開始:
>>> raw = bytearray(raw)
>>> arr = np.frombuffer(raw, dtype='S16')
>>> arr[0] = b"z"*16
>>> arr
array([b'zzzzzzzzzzzzzzzz', b'Good Bye'], dtype='|S16')
>>> raw
bytearray(b'zzzzzzzzzzzzzzzzGood Bye\x00\x00\x00\x00\x00\x00\x00\x00')
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/518093.html
標籤:PythonC麻木的
