python - 在 Python 中比较来自两个不同来源的大型数据集的最佳方法是什么?

标签 python pandas

我有来自 2 个来源的大型数据集,一个是巨大的 csv 文件,另一个来自数据库查询。我正在编写一个验证脚本来比较两个来源的数据并记录/打印差异。我认为值得一提的是,两个来源的数据的格式或顺序并不完全相同。例如:

来源 1(CSV 文件):

email1@gmail.com,key1,1
email2@gmail.com,key1,3
email1@gmail.com,key2,1
email1@gmail.com,key3,5
email2@gmail.com,key3,2
email2@gmail.com,key3,2
email3@gmail.com,key2,3
email3@gmail.com,key3,1

来源 2(数据库):

email                 key1     key2    key3
email1@gmail.com      1        1       5
email2@gmail.com      3        2       <null>
email4@gmail.com      1        1       5

我想要的脚本的输出是这样的:

source1 - source2 (or csv - db):  2 rows total with differences
email2@gmail.com      3        2       2
email3@gmail.com      <null>   3       1

source2 - source1 (or db-csv):  2 rows total with differences
email2@gmail.com      3        2       <null>
email4@gmail.com      1        1       5

输出格式可能略有不同,以便更清楚地显示更多差异(来自数千/数百万条记录)。

我开始编写脚本将两个源的数据保存到两个字典中,并循环字典或从字典创建集合,但这似乎是一个非常低效的过程。我考虑过使用 pandas,但 pandas 似乎没有办法进行这种类型的数据帧比较。

请告诉我是否有更好/更有效的方法。提前致谢!

最佳答案

你走在正确的道路上。你想要的是快速匹配这两个表。 Pandas 可能有点过分了。

您可能想要迭代第一个表并创建一个字典。您不想想要做的是交互每个元素的两个列表。即使是很小的列表也需要大量的搜索。

ReadCsv模块是一个很好的从磁盘读取数据的模块。对于每一行,您将其放入字典中,其中键是电子邮件,值是完整的行。在普通台式计算机中,您可以在一秒钟内迭代 1000 万行。

现在您将迭代抛出第二行,对于每一行,您将使用电子邮件从字典中获取数据。这样看,由于字典是一种数据结构,您可以在 O(1) 时间内获取键值,因此您将通过 N + M 行进行交互。几秒钟后,您应该能够比较两个表。这真的很简单。这是示例代码:

import csv
firstTable = {}
with open('firstTable.csv', 'r') as csvfile:
     reader = csv.reader(csvfile, delimiter=',')
        for row in reader:
            firstTable[row[0]] = row #email is in row[0]

for row2 in get_db_table2():
    email = row2[0]
    row1 = firstTable[email] #this is a hash. The access is very quick
    my_complex_comparison_func(row1, row2)

如果您没有足够的 RAM 内存来容纳内存中第一个字典的所有键,您可以使用 Shelve module对于第一个表变量。这将在磁盘中创建一个可以快速访问的索引。

由于您的一个表已经在数据库中,也许我首先要做的是使用您的数据库将磁盘中的数据加载到临时表中。创建索引,并对表进行内部联接(如果需要知道哪些行在其他表中没有数据,则进行外部联接)。数据库针对此类操作进行了优化。然后,您可以从 python 中进行选择以获取连接的行,并使用 python 进行复杂的比较逻辑。

关于python - 在 Python 中比较来自两个不同来源的大型数据集的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49374192/

相关文章:

Python:在满足特定条件时跳过代码块(计算)而不使用 "if"语句

python - 为什么你可以在字符串上重载 __radd__ 而不是 __rmod__ ?

python - 使用正则表达式的 Amazon S3 查询

python-3.x - 为什么两个 DataFrame 在使用 `=` 时会被链接?

python - 映射 pandas 数据框中的列

python-2.7 - python pandas dataframe索引,错误TypeError : Input must be iterable, pandas版本可能错误

python - 在 Pandas 中,如何用最接近的非纳米值替换零值?

python - Numpy:为列表中的每个数组的 np.array 的每一行乘以 (1/2)^k

python - 排序容器的时间复杂度

python - 在一组中获得最大差异