python - 检查列表是否是 Pandas 数据框中另一个列表的子集

标签 python pandas

所以,我有这个包含近 3000 行的数据框,看起来像这样:

        CITIES
0       ['A','B']
1       ['A','B','C','D']
2       ['A','B','C']
4       ['X']
5       ['X','Y','Z']
...     ...
2670    ['Y','Z']
我想从 DF 中删除“CITIES”列表包含在另一行中的所有行(顺序无关紧要),在上面的示例中,我想删除 0 和 2,因为两者都包含在 1 中,并删除 4 和 2670,因为两者都包含在内,我尝试了一些东西,它有点工作,但它真的很愚蠢,花了将近 10 分钟来计算,就是这样:
indexesToRemove=[]
for index, row in entrada.iterrows():
    citiesListFixed=row['CITIES']
    for index2, row2 in entrada.iloc[index+1:].iterrows():
        citiesListCurrent=row2['CITIES']
        if set(citiesListFixed) <= set(citiesListCurrent):
            indexesToRemove.append(index)
            break
有没有更有效的方法来做到这一点?

最佳答案

首先创建虚拟数据帧,然后我们可以使用矩阵乘法来查看其中一行是否是另一行的完整子集,方法是检查与另一行的乘法和是否等于该行中的元素数。 (将是一个内存密集型)

import pandas as pd
import numpy as np

df = pd.DataFrame({'Cities': [['A','B'], ['A','B','C','D'], ['A','B','C'],
                              ['X'], ['X','Y','Z'], ['Y','Z']]})    
arr = pd.get_dummies(df['Cities'].explode()).max(level=0).to_numpy()
#[[1 1 0 0 0 0 0]
# [1 1 1 1 0 0 0]
# [1 1 1 0 0 0 0]
# [0 0 0 0 1 0 0]
# [0 0 0 0 1 1 1]
# [0 0 0 0 0 1 1]]

subsets = np.matmul(arr, arr.T)
np.fill_diagonal(subsets, 0)  # So same row doesn't exclude itself

mask = ~np.equal(subsets, np.sum(arr, 1)).any(0)

df[mask]
#         Cities
#1  [A, B, C, D]
#4     [X, Y, Z]

如果你有两行与最长的子集相关联,(即两行带有 ['A','B','C','D'] )都被删除了。如果这不是您想要的,您可以先 drop_duplicates'Cities' (需要转换为可散列类型,如 frozenset ),然后应用上述内容。

关于python - 检查列表是否是 Pandas 数据框中另一个列表的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66066357/

相关文章:

python - 使用多个 boolean 列过滤 Pandas 数据框

python - 如何在Power BI中使用Python/R生成的表格?

python - 使用 pd.json_normalize 展平字典

python - 如何修改 HSV 图像数据的 numpy 数组中的像素值?

python - 计算蛋白质序列的所有可能的 RNA 密码子组合

python - Haystack 对多对多字段的搜索不起作用

使用 numpy 中的加载文本导入 cdv 时出现 ' b ' 的 Python 问题

python - 在python中生成没有闭包的函数

python - 如何在 Pandas 中获取盘中价格 - 成交量图?

python - 在 Pandas 数据框中将月份转换为季度