首页 > 解决方案 > 比较两个数据框列以匹配字符串或者是子字符串然后在熊猫中计数(需要快速版)

问题描述

我有两个数据框(A 和 B)。我想比较 A 中的字符串并找到匹配项或包含在 B 中的另一个字符串中。然后计算 A 匹配或包含在 B 中的次数。

    Dataframe A
 
0   "4012, 4065, 4682"
1   "4712, 2339, 5652, 10007"
2   "4618, 8987"
3   "7447, 4615, 4012"
4   "6515"
5   "4065, 2339, 4012"


    Dataframe B

0   "6515, 4012, 4618, 8987"         <- matches (DF A, Index 2 & 4) (2: 4618, 8987), (4: 6515)
1   "4065, 5116, 2339, 8757, 4012"   <- matches (DF A, Index 5) (4065, 2339, 4012)
2   "1101"
3   "6515"                           <- matches (DF A, Index 4) (6515)
4   "4012, 4615, 7447"               <- matches (DF A, Index 3) (7447, 4615, 4012)
5   "7447, 6515, 4012, 4615"         <- matches (DF A, Index 3 & 4) (3: 7447, 4615, 4012 ), (4: 6515)


    Desired Output:

    Itemset             Count

2   4618, 8987            1
3   7447, 4165, 4012      2
4   6515                  3
5   4065, 2339, 4012      1

基本上,我想计算 B 中的 A 是否直接匹配(按顺序或不按顺序)或 A 是否部分包含在 B 中(按顺序或不按顺序)。我的目标是计算 A 被 B 验证的次数。顺便说一下,这些都是字符串。

编辑需要速度版:这是我之前帖子中的一个重做问题: 比较两个数据框列以匹配字符串还是子字符串,然后在熊猫中计数

我在 dfA 和 dfB 中都有数百万行来进行这些比较。在我之前的帖子中,以下代码完成了工作:

import pandas as pd

dfA = pd.DataFrame(["4012, 4065, 4682",
                    "4712, 2339, 5652, 10007",
                    "4618, 8987",
                    "7447, 4615, 4012",
                    "6515",
                    "4065, 2339, 4012",],
                    columns=['values'])

dfB = pd.DataFrame(["6515, 4012, 4618, 8987",
                    "4065, 5116, 2339, 8757, 4012",
                    "1101",
                    "6515",
                    "4012, 4615, 7447",
                    "7447, 6515, 4012, 4615"],
                    columns=['values'])

dfA['values_list'] = dfA['values'].str.split(', ')
dfB['values_list'] = dfB['values'].str.split(', ')


dfA['overlap_A'] = [sum(all(val in cell for val in row)
                    for cell in dfB['values_list']) 
                    for row in dfA['values_list']]

但是,由于要检查的总行数,我遇到了性能问题,需要另一种方法来检查频率/计数。在这种情况下,似乎需要 Numpy。这是关于我主要在熊猫工作时的 numpy 知识范围。任何人有建议让这更快?

dfA_array = dfA['values_list'].to_numpy()
dfB_array = dfB['values_list'].to_numpy()

标签: pythonpandasnumpy

解决方案


试试这个。您的算法是 O(N N K):计数平方 * 每行字数。下面应该改进到 O(NK)

from collections import defaultdict
from functools import reduce

d=defaultdict(set)
for i,t in enumerate(dfB['values']):
    for s in t.split(', '):
        d[s].add(i)
dfA['count']=dfA['values'].apply(lambda x:len(reduce(lambda a,b: a.intersection(b), [d[s] for s in x.split(', ') ])))

推荐阅读