根据条件从列表中删除元素

Remove elements from lists based on condition

我有以下代码:

from collections import defaultdict
import pandas as pd

THRESHOLD = 3 

item_counts = defaultdict(int)

df = {'col1':['1 2 3 4 5 6 7', '1 3 6 7','2 6 7']}
lines = pd.DataFrame(data=df)

print(lines)

for line in lines['col1']:
    for item in line.split():
        item_counts[item] += 1

print(item_counts)         
for line in lines['col1']:
    for item in line.split():
        if item_counts[item] < THRESHOLD:
            del item

print(lines)

我的目标是计算每个项目,并且从我的数据框中删除低于阈值的项目。在这种情况下,只应保留 6 和 7,其余的应删除。 defaultdict 工作正常,但项目删除不起作用。

你知道我做错了什么吗?

使用 del 与从列表中删除元素不同。 考虑以下示例

>>> x=1
>>> y=2
>>> lst = [x,y]
>>> del x
>>> print(lst)
[1, 2]
>>> lst.remove(x)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'x' is not defined
>>> lst.remove(y)
>>> print(lst)
[1]
>>> print(y)
2

如您所见,对共享指向列表中元素的指针的变量使用 del 只删除了离开列表的指针。 remove 则相反。它从列表中删除了元素,但没有删除变量指针。

至于解决问题:你不应该在迭代时直接从列表中删除。

IMO 最好的解决方法是使用列表理解来制作一个仅包含所需元素的新列表并替换旧列表:

for line in lines['col1']:
    line = [item for item in line.split() if item >= THRESHOLD
    # line = ' '.join(line)

P.S。 如果您希望 return 将注释行添加到字符串

如果您不需要 DataFrame(我不明白您为什么需要这个),您可以这样做:

from collections import Counter

THRESHOLD = 3
lines = {'col1':['1 2 3 4 5 6 7', '1 3 6 7','2 6 7']}

# make proper list of ints
z = {k: [[int(x) for x in v.split()] for v in vals] for k, vals in lines.items()}
print(z)
# {'col1': [[1, 2, 3, 4, 5, 6, 7], [1, 3, 6, 7], [2, 6, 7]]}

# count the items within each value of the dict
z = {k: Counter(x for vals in arr for x in vals) for k, arr in z.items()}
print(z)
# {'col1': Counter({6: 3, 7: 3, 1: 2, 2: 2, 3: 2, 4: 1, 5: 1})}

# select the items that are seen at least THRESHOLD times
z = {col: [k for k, v in cnt.items() if v >= THRESHOLD] for col, cnt in z.items()}
print(z)
# {'col1': [6, 7]}