计算数百个文件中的唯一 ID?



我有大约 750 个文件 (.csv),每行都有一个条目,这是一个 UUID。我的目标是让这个脚本计算所有 750 个左右文件中存在多少个唯一的 UUID。文件名结构如下所示:

DATA-20200401-005abf4e3f864dcb83bd9030e63c6da6.csv

如您所见,它有一个日期和一些随机ID。它们都在同一个目录中,并且都具有相同的文件扩展名。每个文件的格式都是换行分隔的,只有一个如下所示的 UUID:b0d6e1e9-1b32-48d5-b962-671664484616

我尝试合并所有文件,但事情变得混乱,这是大约 15GB 的数据。

我的最终目标是获得一个输出,以便它声明所有文件中唯一 ID 的数量。例如:

文件 1:

xxx-yyy-zzz
aaa-bbb-ccc
xxx-yyy-zzz

文件2:

xxx-yyy-zzz
aaa-bbb-ccc
xxx-yyy-zzz

扫描这两个文件后的最终输出将是:

The total number of unique ids is: 2

我认为使用计数器可能是最快的方法:

from collections import Counter
with open(filename) as f:
c = Counter(f)
print(sum(c.values()))

计数器提供每个唯一项的计数。这是使用哈希表实现的,因此对于大量项目应该相当快。

如果您不必使用 Python,那么一个简单的解决方案可能是命令行:

cat *.csv | sort -u | wc -l   

这会将所有 CSV 文件的内容通过管道传输到sort -u,以便对重复项进行排序和删除,然后将其管道传输到执行行计数的wc -l

注意:sort将根据需要溢出到磁盘,如果您愿意,可以使用-S size来控制其内存使用量。

我很想在具有大量 RAM 的强大机器上运行它。

也许这样的事情会起作用:

from os import listdir
import re
import pandas as pd
my_folder_path = "C:\\"
# Generic regular expression
pat = r"DATA-d{8}-.+.csv}"
p = re.compile(pat)
# UUID column in each file (I don't know if this is the case; Adjust accodingly.
uuid_column = "uuids"
# Empty result dataframe with single column
result_df = pd.DataFrame(columns=["unique_uuid"])
file_list = [rf"{my_folder_path}{i}" for i in listdir(my_folder_path)]
for f in file_list:
# Check for matching regular expression pattern
if p.search(f):
# Read file if pattern matches.
df = pd.read_csv(f, usecols=[uuid_column])
# Append only unique values from the new Series to the dataframe
(result_df["unique_uuid"]
.append(list(set(df[uuid_column].values)
.difference(result_df["unique_uuid"].values)))
)

连接目录中的所有csv文件已在一篇非常受欢迎的帖子中得到解决 这里唯一的区别是你删除了重复项。 当然,只有当每个文件中有大量重复项(至少足以让所有重复的帧都适合内存并执行最终drop_duplicates)时,这才能很好地工作。

该链接中还有其他一些建议,例如完全跳过列表。

import glob
import pandas as pd
files = glob.glob('./data_path/*.csv')
li = []
for file in files:
df = pd.read_csv(file, index_col=None, header=None)
li.append(df.drop_duplicates())
output = pd.concat(li, axis=0, ignore_index=True)
output = output.drop_duplicates()

读取所有文件,并随时将所有 UUID 添加到集合中。 集强制实施唯一性,因此集的长度是您找到的唯一 UUID 的数量。 大约:

import csv
import os
uuids = set()
for path in os.listdir():
with open(path) as file:
for row in csv.reader(file):
uuids.update(row)
print(f"The total number of unique ids is: {len(uuids)}")

这假定您可以将所有唯一的 UUID 存储在内存中。 如果不能,那么接下来要尝试在磁盘上构建数据库(例如,用sqlite db或类似的东西替换set)。 如果您有许多太大而无法存储在任何地方的唯一 ID,只要您愿意牺牲一些精度,仍然有解决方案:https://en.wikipedia.org/wiki/HyperLogLog

最新更新