python - 数据集中的评分一致性

标签 python python-3.x data-integrity data-cleaning

假设我得到了一组结构化数据。已知数据存在问题,我需要以某种方式对它们的一致性进行“评分”。例如,我有如下所示的数据:

fieldA | fieldB | fieldC
-------+--------+-------
foo    | bar    | baz
fooo   | bar    | baz
foo    | bar    | lorem
..     | ..     | ..
lorem  | ipsum  | dolor
lorem  | upsum  | dolor
lorem  | ipsum  | baz

所以假设第一行被认为是正确的条目,因为与第二行和第三行中的记录相比,该组合中的数据相对更多。在第二行中,fieldA 的值应为 foo(由于拼写错误而导致不一致)。然后在第三行中,fieldC 的值应该是 baz,因为数据集中的其他条目具有与 fieldA 相似的值(foo ) 和 fieldB (bar) 建议。

此外,在数据集的其他部分,还有另一种组合相对更常见(loremipsumdolor)。所以后面记录的问题和前面提到的一样,只是值的组合不同而已。

我最初将所有内容转储到 SQL 数据库,并使用带有 GROUP BY 的语句来检查字段值的一致性。因此,对于我要检查一致性的每个字段以及每条记录,将有 1 个查询。

SELECT    fieldA, count(fieldA)
FROM      cache
WHERE     fieldB = 'bar' and fieldC = 'baz'
GROUP BY  fieldA

然后我可以通过将记录引用到下面的对象(先前SQL查询的处理结果)来检查记录的fieldA的值是否与其余值一致。

{'foo': {'consistency': 0.99, 'count': 99, 'total': 100}
 'fooo': {'consistency': 0.01, 'count': 1, 'total': 100}}

但是它非常慢(数据集有大约 220 万条记录,我正在检查 4 个字段,所以进行了大约 900 万次查询),并且需要半天才能完成。然后我将 SQL 存储替换为 elasticsearch,处理时间缩短到 5 小时左右,是否可以更快一些?

也只是出于好奇,我是不是在这里重新发明了一个轮子?有现成的工具吗?目前它是在 Python3 中实现的,带有 elasticsearch。

最佳答案

我刚刚阅读了您的问题,发现它很有趣。我使用 ntlk 做了类似的事情(python 自然语言工具包)。 无论如何,在这种情况下,我认为您不需要复杂的 string comparison algorithms .

所以我尝试了一种使用 python difflib 的方法.标题听起来很有前途:difflib — Helpers for computing deltas

difflib.SequenceMatcher 类说:

这是一个灵活的类,用于比较任何类型的序列对,只要序列元素是可散列的即可。

顺便说一句,我认为如果你想节省时间,你可以在内存中轻松保存和处理 2.000.000 个三元组(相对较短)的字符串。 (请参阅下面的测试运行和内存使用情况)

所以我写了一个demo App产生 2.000.000(你可以改变它)随机轻微打乱的字符串的 3 元组。打乱后的字符串基于并与像您这样的默认模式进行比较:['foofoo', 'bar', 'lorem']。然后使用 difflib.SequenceMatcher 比较它们。全部在内存中。

这是比较代码:

def compare(intuple, pattern_list):
    """
    compare two strings with difflib
    intuple: in this case a n-tuple of strings
    pattern_list: a given pattern list.
    n-tuple and list must be of the same lenght.

    return a dict (Ordered) with the tuple and the score
    """
    d = collections.OrderedDict()
    d["tuple"] = intuple
    #d["pattern"] = pattern_list
    scorelist = []
    for counter in range(0,len(pattern_list)):
        score = difflib.SequenceMatcher(None,intuple[counter].lower(),pattern_list[counter].lower()).ratio()
        scorelist.append(score)
    d["score"] = scorelist
    return d

以下是运行时和内存使用结果:

2000 个三元组: - 比较时间:417 毫秒 = 0,417 秒 - 内存使用:594 KiB

200.000 个三元组: - 比较时间:5360 毫秒 = 5.3 秒 - 内存使用:58 MiB

2.000.000 三元组: - 比较时间:462241 毫秒 = 462 秒 - 内存使用:580 MiB

因此它在时间和内存使用方面呈线性扩展。它(仅)需要 462 秒来比较 2.000.000 个三元组字符串。

结果如下所示:(200.000 行的示例)

[ TIMIMG ]
build                function took 53304.028034 ms
[ TIMIMG ]
compare_all          function took 462241.254807 ms
[ INFO ]

num rows: 2000000
pattern: ['foofoo', 'bar', 'lorem']
[ SHOWING 10 random results ]
0: {"tuple": ["foofoo", "bar", "ewrem"], "score": [1.0, 1.0, 0.6]}
1: {"tuple": ["hoofoo", "kar", "lorem"], "score": [0.8333333333333334, 0.6666666666666666, 1.0]}
2: {"tuple": ["imofoo", "bar", "lorem"], "score": [0.6666666666666666, 1.0, 1.0]}
3: {"tuple": ["foofoo", "bar", "lorem"], "score": [1.0, 1.0, 1.0]}
....

如您所见,您会根据字符串与模式的相似性得到一个分数。 1.0 意味着相等,分数越低,下面的一切都会变得越糟。

difflib 被认为不是最快的算法,但我认为 7 分钟比半天或 5 小时有很大的改进。

我希望这对您有所帮助(并且不是完全误解)但是昨天编写这个程序很有趣。我学到了很多。 ;) 例如使用 tracemalloc 跟踪内存使用情况.以前从未这样做过。

我把代码放到了github (as a one file gist) .

关于python - 数据集中的评分一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36643618/

相关文章:

python - Windows下的PyGObject : Could not locate gdk_pixbuf_new_from_file

python - 具有非标量输出的 Numpy 矢量化函数

python-3.x - 使用 PIL 动画 gif W/O

python - 使用另一个dict python在嵌套Json中插入元素

mysql - 时间表工具的数据库规范化并确保数据完整性

sql - 如何测试SQL脚本? (数据完整性/迁移测试)

visual-studio-2010 - VS 2010 数据库项目删除有关列名称更改的数据

python - 为什么从 numpy 数组继承的类的方法返回不同的东西?

python - 使用 LineProfiler 对 Django 应用程序进行逐行分析

python-3.x - Gremlin 服务器连接到 Orient DB