[英]Retrieving equal numpy array after storing as string in db
我有一個numpy.float32元素列表,我從查詢圖像中提取:
[0.013991388, 0.0070270086, 0.0012525863, 0.013302466, . . . etc
它存儲在對象中,也作為String存儲在數據庫中。 然后將對象值與檢索到的數據庫值進行比較(在從字符串中轉換它之后)。
然而,無論它們看起來多么相似,我似乎無法讓它們再次平等。 例如,我正在運行chi2距離算法來計算距離,並期望能夠為同一圖像返回0.0。
我的轉換代碼:
# converts string to numpy array (matrix). MUST CAST to float32 otherwise pythons float64 by default, this will not
# match with our query array even if they are the same image!!!
def toMatrix(text):
text = text.replace('[', '').replace(']', '')
floats = [np.float32(x) for x in text.split(',')]
return floats
在使用上面的字符串將字符串轉換回浮點數列表之后,我將它與存儲在對象中的列表進行比較,方法是將一個接一個地粘貼到PyCharm文本文件中。 檢查本地歷史記錄表明沒有發生任何變化,視覺上兩個陣列是相同的。
所以這是我認為的一個類型問題。 我打印出兩個列表的類型第一個元素,例如type(listA[0]), type(listB[0])
,兩者都是numpy.float32。
所以我使用更一般的比較:
np.array_equal(listA, listB) # returns False
np.allclose(listA, listB) # returns True
試圖找出不相等的東西:
d = {}
count = 1
for item in listA:
if item not in listB:
d[count] = type(item)
count += 1
我得到了特殊的結果: {124: <class 'numpy.float32'>}
這是兩個數組中的單個項目???
任何人都可以對正在發生的事情有所了解,以及如何讓數組相等?
大概所有的listA的項目是類型numpy.float32
,所以這段代碼:
d[type(item)] = item
將一遍又一遍地分配給相同的字典元素。
我不會嘗試解析容易出錯且繁瑣的字符串。 我寧願依賴json字符串之類的東西來保存數據,因此你可以在沒有(或至少節省大部分時間)解析數據的情況下轉換和加載數據。
您可以創建一個TextField
並將數組保存/加載到它,或者可能有某些人已經創建的django-jsonfield 。
您的數字的字符串表示形式有8位有效數字; 這不足以唯一地指定 float32
的二進制表示 。
你永遠不應該假設float(string(number))==number
浮點數的數字。 在制作浮點數的字符串表示時有足夠的流浪,如果嘗試了足夠的次數,這將導致失敗。
你應該只測試浮點數之間的相等性,如果你真的意味着你需要兩個數字在位上相等(通常在創建字符串表示時不能保留)。 通常,你想要numpy.allclose
使用的“在容忍范圍內”的標准。
如果您的情況允許,您應該考慮以二進制格式保存數據陣列。 這將在保存/加載時保留數字的位表示(如果您真的關心按位相等),並且作為額外的好處,這需要更少的存儲空間。
您遇到浮點精度問題:字符串表示形式與二進制表示形式不同。 嘗試這個:
import numpy as np
import random
a=random.random()
np.float32( str(a)) == a
我第一次嘗試時得到False
( print a => 0.893117245932
),也許你不會,但浮點數float(string(number))
不是那個數字。
如果你需要將它們保存為字符串,你應該使用numpy.tostring
- 這將從數組中的值生成二進制字符串,例如numpy.fromstring(numpy.tostring(array), dtype=numpy.float32) == array
(假設array.dtype==numpy.float32
)。
如果你不關心精度,那么用allclose
使用的公差測試近似相等可能是有意義的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.