2016-05-25 36 views
1

我試圖將spacy.io文檔序列化爲字節字符串並將它們保存在numpy數組中。numpy修剪字節字符串中的尾隨零

spacy有一個to_bytes功能,它產生一個bytearray。我在此bytearray上調用str,並將該字符串對象插入到numpy數組中。這適用於大多數文檔,除了那些以尾隨零字節結尾的文檔。

要重現:

>>> import numpy as np 
>>> b_arr = bytearray(b'\xca\x00\x00\x00n\xff\xff\xff\x19C\x98\xc9\x06\xb18{\xa5\xe0\xaf6\xe3\x9f\xa7\xad\x86\xd6\x8d\xc0\xe6Mo;{\x96xm\x80\xe5\x8c\x9f<!\xc33\x9dg\xd3\xb3D\xf6\xac\x03P\x8do\x07m$r)\x06XBI\xc87\xcao\x83\x1d\xe4\r]\x86\xda\xeb\xb8\x1f\xd5\xcb\xde\xaa\x85r\x0f\xf1=p\xd6\x01\xdc\x83Z|&\xeb\xce|\xf9o\xa0\xe99x\x87\x87\xac\x1b\x17\x08\x000\x92\x10A\x98\x10\x13\x89(0\x88 "!*N\xf8\xe6\xf4\r\xb1e\xf0\x9d\xfd\x80\xa2G2\x18\xdesv\xec\x85\xf7\xb1\xb3\xb3\xa68\xa7n\xe8BF\xa6\xe0\xb1\x8d\x8d\x9c\xe5\x99\x9bV\xfcE`\x1cI\x92$I\x92$I\x92$%I\x92\xe4\xff\xff\x7f\xd1\xff\xf0T\xa6\xe8\n\x9a\xd3\xffMe0\xa9\x15\xf1|\x00') 
>>> b_arr_text = str(b_arr) 
>>> b_arr_np = np.asarray([b_arr_text], dtype=np.str) 
>>> b_arr_text == b_arr_np[0] 
Out[229]: False 
>>> len(b_arr_text) 
Out[230]: 206 
>>> len(b_arr_np[0]) 
Out[231]: 205 
>>> b_arr_np.dtype 
Out[232]: dtype('S206') 

numpy串修剪任何尾隨零,對於固定長度字符串的D型細胞是相同的長度,然而,輸入的文本。

你甚至可以從陣列中的尾隨零個字節產生任何字節串看到:

>>> np.asarray(['\xca\x00\x00\x00'], dtype=np.str) 

Out: array(['\xca'], dtype='|S4') 

我相信numpy認爲尾隨零是無意義?但是,我無法將這些字節串反序列化回spacy文檔對象。

有什麼辦法可以讓numpy不修剪尾部零或者我必須堅持Python列表這種情況?

+1

存儲之前附加虛擬非零字節和取回後刪除嗎? – nekomatic

+0

@nekomatic謝謝你的建議,我可以確實做到這一點,它會工作。理想情況下,我想知道'numpy'爲什麼會這樣做,尤其對'dtype'字符串長度和修剪字符串大小之間的不匹配感到好奇。 – dsimmie

回答

3

這是正常的行爲。在b_arr_np.tostring()之後你可以看到,所有的尾隨零都是有序的。

b_arr = bytearray(b'\xca\x00\x00\x00') 

b_arr_text = str(b_arr) 

b_arr_np = np.asarray([b_arr_text], dtype=np.str) 

b_arr_np 
Out[303]: 
array(['\xca'], 
     dtype='|S4') 

b_arr_np.tostring() 
Out[304]: '\xca\x00\x00\x00' 

查看帖子information loss with bytes type來自github。問題是要麼使用trailng非零字節或使用dtype=uint8b_arr

b_arr_np = np.asarray([b_arr], dtype=np.uint8) 

b_arr_np 
Out[319]: array([[202, 0, 0, 0]], dtype=uint8) 

b_arr_np.tostring() 

Out[320]: '\xca\x00\x00\x00' 
+0

感謝@ vadim-shkaberda ..這個帖子解釋了我想知道的一切。可悲的是你的建議使用'np.uint8'不適用於我,因爲我混合形狀bytearrays: 'np.asarray([bytearray(b'\ xca \ x00 \ x00 \ x00'),bytearray(b'\ XCA \ X00 \ X00' )],D型細胞= np.uint8)' 產生值誤差: 'ValueError異常:設置一個數組元素與sequ​​ence.' 作爲交表明我可以使用對象'D型'但是失去了在Python列表上使用'numpy'的任何好處。我想我會堅持使用@nekomatic建議的解決方法,並附加一個虛擬字節並在之後刪除。 – dsimmie