我有一个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'>}
这是两个数组中的单项???
任何人都可以了解到究竟发生了什么,以及如何让阵列变得平等?
答案 0 :(得分:1)
推测listA中的所有项目都是numpy.float32
类型,所以这段代码:
d[type(item)] = item
将一遍又一遍地分配给相同的字典元素。
答案 1 :(得分:1)
我不会尝试解析容易出错且繁琐的字符串。我宁愿依赖json字符串之类的东西来保存数据,所以你可以在没有(或至少节省大部分时间)解析数据的情况下转换和加载数据。
你可以创建一个TextField
并将数组保存/加载到它,或者可能有某些人已经创建的django-jsonfield。
答案 2 :(得分:1)
您的数字的字符串表示形式有8位有效数字; dplyr
的{{3}}。
您永远不应该假设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
不是那个数字。
如果您需要将它们保存为字符串,则应使用this is not enough to uniquely specify the binary representation - 这将使用数组中的值生成二进制字符串,例如float(string(number))
(假设为numpy.fromstring(numpy.tostring(array), dtype=numpy.float32) == array
)。
如果您不关心精度,那么使用array.dtype==numpy.float32
中使用的容差测试近似相等可能是有意义的。