我有一些数据,其中包含5个元素'a''b''c''d''e'的比率,如下所示:

data = [
    {'a': 0.197, 'b': 0.201, 'c': 0.199, 'd': 0.202, 'e': 0.201},
    {'a': 0.624, 'b': 0.628, 'c': 0.623, 'd': 0.625, 'e': 0.750},
    {'a': 0.192, 'b': 0.203, 'c': 0.200, 'd': 0.202, 'e': 0.203},
    {'a': 0.630, 'b': 0.620, 'c': 0.625, 'd': 0.623, 'e': 0.752},
]

我想将每个比率数据(表示为dict)散列到一个字符串中,该字符串可用作具有容差的比率的唯一标识符.例如,对于每个元素的比率的容差为0.1,期望第一个和第三个DICT应该具有相同的标识符,并且第二个和第四个DICT应该具有相同的标识符.如果只想比较两个比率数据是否在公差范围内,这很容易做到,但我不确定如何创建唯一的标识符.

编辑:我正在寻找一些四舍五入的方法,而不是完全任意的散列.

推荐答案

简单地铺地板和拼接怎么样?

data = [     {'a': 0.197, 'b': 0.201, 'c': 0.199, 'd': 0.202, 'e': 0.201},     {'a': 0.624, 'b': 0.628, 'c': 0.623, 'd': 0.625, 'e': 0.750},     {'a': 0.192, 'b': 0.203, 'c': 0.200, 'd': 0.202, 'e': 0.203},     {'a': 0.630, 'b': 0.620, 'c': 0.625, 'd': 0.623, 'e': 0.752}, ]

def hashwithtol(datum, abstol=0.1):
    return ','.join(
        str(int(datum[k] // abstol))
        for k in 'abcde'
    )

def groupby_hashwithtol(data, abstol=0.1):
    groups = {}
    for datum in data:
        groups.setdefault(hashwithtol(datum, abstol), []).append(datum)
    return groups

for abstol in (1, 0.1, 0.01):
    print(f'Abs tol = {abstol}')
    groups = groupby_hashwithtol(data, abstol)
    print(*(f'{k}: {g}' for k,g in groups.items()), sep='\n')
    print()
Abs tol = 1
0,0,0,0,0: [{'a': 0.197, 'b': 0.201, 'c': 0.199, 'd': 0.202, 'e': 0.201}, {'a': 0.624, 'b': 0.628, 'c': 0.623, 'd': 0.625, 'e': 0.75}, {'a': 0.192, 'b': 0.203, 'c': 0.2, 'd': 0.202, 'e': 0.203}, {'a': 0.63, 'b': 0.62, 'c': 0.625, 'd': 0.623, 'e': 0.752}]

Abs tol = 0.1
1,2,1,2,2: [{'a': 0.197, 'b': 0.201, 'c': 0.199, 'd': 0.202, 'e': 0.201}]
6,6,6,6,7: [{'a': 0.624, 'b': 0.628, 'c': 0.623, 'd': 0.625, 'e': 0.75}, {'a': 0.63, 'b': 0.62, 'c': 0.625, 'd': 0.623, 'e': 0.752}]
1,2,2,2,2: [{'a': 0.192, 'b': 0.203, 'c': 0.2, 'd': 0.202, 'e': 0.203}]

Abs tol = 0.01
19,20,19,20,20: [{'a': 0.197, 'b': 0.201, 'c': 0.199, 'd': 0.202, 'e': 0.201}]
62,62,62,62,74: [{'a': 0.624, 'b': 0.628, 'c': 0.623, 'd': 0.625, 'e': 0.75}]
19,20,20,20,20: [{'a': 0.192, 'b': 0.203, 'c': 0.2, 'd': 0.202, 'e': 0.203}]
62,61,62,62,75: [{'a': 0.63, 'b': 0.62, 'c': 0.625, 'd': 0.623, 'e': 0.752}]
  • 如果你更喜欢四舍五入而不是地板,那么你可以用int(round(datum[k] / abstol))代替int(datum[k] // abstol).
  • 在上面的示例中,您可以注意到0.199和0.2不会被放在同一个垃圾桶中,因为0.199被压到了0.1.使用四舍五入而不是地板不能解决这个问题,只需将问题移到不同的数字;例如,0.149将向下舍入为0.1,而0.150将向上舍入为0.2.
  • 如果每个DICT有5个以上的值,并且键开始变得太长,则可以将其包装在对Python的内置hash:def hashwithtol(datum, abstol=0.1): return hash(','.join(str(int(datum[k] // abstol)) for k in 'abcde'))的调用中

Python相关问答推荐

比较两个二元组列表,NP.isin

DataFrame groupby函数从列返回数组而不是值

Odoo 14 hr. emergency.public内的二进制字段

Python 约束无法解决n皇后之谜

将图像拖到另一个图像

通过pandas向每个非空单元格添加子字符串

如何获取numpy数组的特定索引值?

try 将一行连接到Tensorflow中的矩阵

在嵌套span下的span中擦除信息

使用特定值作为引用替换数据框行上的值

pandas:对多级列框架的列进行排序/重新排序

python—telegraph—bot send_voice发送空文件

在代码执行后关闭ChromeDriver窗口

获取PANDA GROUP BY转换中的组的名称

如何在验证文本列表时使正则表达式无序?

如何将返回引用的函数与pybind11绑定?

在第一次调用时使用不同行为的re. sub的最佳方式

Python:从目录内的文件导入目录

如何让PYTHON上的Selify连接到现有的Firefox实例-我无法连接到Marionette端口

将时间序列附加到数据帧