gpt4 book ai didi

python - 如何在 Python 中删除大量对象的重复项

转载 作者:行者123 更新时间:2023-11-30 22:51:25 28 4
gpt4 key购买 nike

我有大量重复的对象列表(我说的是数千个列表,每个列表都有数千个对象,大约有 1000 万个单独的对象(已经没有重复)。

我需要遍历它们并删除每个列表中的所有重复项(无需在列表之间进行比较,只在每个列表中进行比较)。

当然,我可以浏览这些列表并与已多次发布的任何重复数据删除算法进行比较,但我想这将花费我很长时间。

我以为我可以用精心制作的 __hash__ 创建一个对象方法并使用 list(set(obj))删除它们,但首先:我不知道这是否可行,其次:我仍然需要循环列表以将元素转换为新对象。

我知道 Python 不是我想要实现的最佳解决方案,但在这种情况下,它必须在 Python 中完成。我想知道以最佳性能实现这一目标的最佳方法是什么。

编辑 :为了澄清:我有大约 2k 个对象列表,每个对象中有大约 5k 个对象(粗略估计)。复制的对象是副本,而不是对同一内存位置的引用。列表(dicts)基本上是转换后的 JSON 数组

编辑 2 : 不好意思说的不清楚,我改一下。

这是针对 django 数据迁移的,尽管我的问题仅适用于数据“格式化”,而不适用于框架本身或数据库插入。
我将一大堆数据作为 JSON 插入到表中以供以后分析。现在我需要对其进行规范化并正确保存。我创建了新表并需要迁移数据。

所以当我从数据库中检索数据时,我有大约 2000 个 JSON 数组。申请json.loads(arr) (通过文档)我得到了 2000 个对象列表(字典)。每个 dict 只有字符串、数字和 bool 值作为每个键的值,没有嵌套的对象/数组,所以像这样:

[
{
a: 'aa',
b: 2,
c: False,
date: <date_as_long> // ex: 1471688210
},
{
a: 'bb',
b: 4,
c: True,
date: <date_as_long> // ex: 1471688210
}
]

我需要的是遍历每个列表并删除重复项。如果列表中除日期之外的所有字段都匹配(这不在原始问题中,因为我没有预测到),则认为某些内容是重复的。如果它们在不同的列表中匹配,则它们不被视为重复。

经过对内容的更好分析,我发现我有接近 200 万条个人记录(而不是之前所说的 1000 万条)。
我面临的性能问题是因为每个 dict 都需要进行某种数据格式化(例如转换日期)并将其“包装”在模型对象中以进行数据库插入: ModelName(a='aaa', b=2, c=True, date=1471688210) .

数据库本身的插入由 bulk_create 完成。 .

注意 : 很抱歉没有对原始问题做出澄清。我对此进行的研究越多,我就越了解必须做什么以及如何处理数据。

我接受了@tuergeist 的回答,因为它指出了我需要的东西,即使我的细节不好。

给定 dicts 不能被散列,因此我不能将它们添加到 set(),我的解决方案是创建一个 set()重复数据的元组,并用它验证重复项。如果重复项在列表中,这可以防止额外的迭代。

所以它是这样的:
data = [lots of lists of dicts]
formatted_data = []
duplicates = set()

for my_list in data:
for element in my_list:
a = element['a']
b = convert_whatever(element['b'])
c = element['c']

d = (a, b, c) # Notice how only the elements that count for checking if it's a duplicate are here (not the date)

if d not in duplicates:
duplicates.add(d)
normalized_data = {
a: a,
b: b,
c: c,
date: element['date']
}
formatted_data.append(MyModel(**normalized_data)

duplicates.clear()

在此之后,为了更好的内存管理,我使用了生成器:
data = [lots of lists of dicts]
formatted_data = []
duplicates = set()

def format_element(el):
a = el['a']
b = convert_whatever(el['b'])
c = el['c']

d = (a, b, c)

if d not in duplicates:
duplicates.add(d)
normalized_data = {
'a': a,
'b': b,
'c': c,
'date': el['date']
}
formatted_data.append(MyModel(**normalized_data))

def iter_list(l):
[format_element(x) for x in l]
duplicates.clear()

[iter_list(my_list) for my_list in data]

这里的工作代码: http://codepad.org/frHJQaLu

注意 :我完成的代码与这个有点不同(并且在功能风格上)。这仅作为我如何解决问题的一个例子。

编辑 3 :
对于数据库插入,我使用了 bulk_create。最后,正确格式化所有内容(150 万个唯一条目,225k 个重复项)需要 1 分钟,将所有内容插入数据库需要 2 分钟。

谢谢你们!

最佳答案

(可散列项)的快速,不保留顺序的解决方案是

def unify(seq):
# Not order preserving
return list(set(seq))

完成编辑

我假设你有 dictslist 内.你有很多 list 。从单个列表中删除重复项的解决方案是:
def remove_dupes(mylist):
newlist = [mylist[0]]
for e in mylist:
if e not in newlist:
newlist.append(e)
return newlist

此处的列表包含以下字典。 (但都是随机的)
{"firstName":"John", "lastName":"Doe"}, 
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter","lastName":"Jones"}

运行它,我的 MacBook(2,4GHz,i5)上 2000 个 dicts 需要 8 秒

完整代码: http://pastebin.com/NSKuuxUe

关于python - 如何在 Python 中删除大量对象的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39033565/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com