csv 如何根据字符串customers list在 Dataframe 中选择行?

yvfmudvl  于 2023-03-05  发布在  其他
关注(0)|答案(3)|浏览(113)

我有一个包含账单的第一个 Dataframe ,在这个 Dataframe 中,名为contents的列在一个未格式化/标准化的字符串中包含客户名称,如下所示:

NUMBIL      DATE                           CONTENTS AMOUNT
0     858  01/01/23                    Billed to HENRY    25$
1     863  01/01/23                             VIKTOR    96$
2     870  01/01/23                     Regard to ALEX    13$
3     871  07/01/23                           MARK 01*    96$
4     872  07/01/23  To charge SAMANTHA every Thursday    96$
5     880  08/01/23                     VIKTOR LECOMTE    13$
6     881  08/01/23                               ****    13$

我有一个第二个 Dataframe ,其中包含一个简短的客户名称列表,如下所示:

NUMBIL
0    VIKTOR
1      ALEX
2  SAMANTHA

"我想做的事"
根据客户列表,确定第一个 Dataframe 中CONTENTS列中不包含客户名称的行。
在本例中,生成的 Dataframe 为:

NUMBIL      DATE         CONTENTS AMOUNT
0     858  01/01/23  Billed to HENRY    25$
3     871  07/01/23         MARK 01*    96$
6     881  08/01/23             ****    13$

我已经找到了一个可能的解决方案来解决我的问题,但我认为这个主题可能对社区有用,我想知道你会用什么独特的方法来处理这个问题?

**开始的 Dataframe **

import pandas as pd

fct = pd.DataFrame({'NUMBIL':[858, 863, 870, 871, 872, 880, 881],
                   'DATE':['01/01/23', '01/01/23', '01/01/23', '07/01/23', '07/01/23', '08/01/23', '08/01/23'],
                   'CONTENTS':['Billed to HENRY', 'VIKTOR', 'Regard to ALEX', 'MARK 01*', 
                               'To charge SAMANTHA every Thursday', 'VIKTOR LECOMTE', '****'],
                   'AMOUNT':['25$', '96$', '13$', '96$', '96$', '13$', '13$'],
                   })

cust = pd.DataFrame({'CUSTOMERS':['VIKTOR', 'ALEX', 'SAMANTHA'],
                   })
aoyhnmkz

aoyhnmkz1#

您可以为str.contains创建一个正则表达式,并将其输出(~)反转为布尔索引:

import re

pattern = '|'.join(map(re.escape, cust['CUSTOMERS']))

out = fct[~fct['CONTENTS'].str.contains(pattern)]

如果您只想匹配完整的单词(例如,SAM不匹配SAMANTHA),请添加单词边界(\b):

out = fct[~fct['CONTENTS'].str.contains(fr'\b(?:{pattern})\b')]

输出:

NUMBIL      DATE         CONTENTS AMOUNT
0     858  01/01/23  Billed to HENRY    25$
3     871  07/01/23         MARK 01*    96$
6     881  08/01/23             ****    13$
plupiseo

plupiseo2#

集合论

当您有大量客户需要测试时,这会快得多

s = set(cust['CUSTOMERS'])
fct[fct['CONTENTS'].map(lambda c: s.isdisjoint(c.split()))]

结果

NUMBIL      DATE         CONTENTS AMOUNT
0     858  01/01/23  Billed to HENRY    25$
3     871  07/01/23         MARK 01*    96$
6     881  08/01/23             ****    13$
6mzjoqzu

6mzjoqzu3#

我找到的解决方案用于说明目的。
与Mozway非常相似,但未考虑暴露的SAM/SAMANTHA问题。

import pandas as pd

fct = pd.DataFrame({'NUMBIL':[858, 863, 870, 871, 872, 880, 881],
                   'DATE':['01/01/23', '01/01/23', '01/01/23', '07/01/23', '07/01/23', '08/01/23', '08/01/23'],
                   'CONTENTS':['Billed to HENRY', 'VIKTOR', 'Regard to ALEX', 'MARK 01*', 
                               'To charge SAMANTHA every Thursday', 'VIKTOR LECOMTE', '****'],
                   'AMOUNT':['25$', '96$', '13$', '96$', '96$', '13$', '13$'],
                   })

cust = pd.DataFrame({'CUSTOMERS':['VIKTOR', 'ALEX', 'SAMANTHA'],
                   })

m = fct['CONTENTS'].str.contains('|'.join(cust['CUSTOMERS']))
r = fct[~m]

print(r)
NUMBIL      DATE         CONTENTS AMOUNT
0     858  01/01/23  Billed to HENRY    25$
3     871  07/01/23         MARK 01*    96$
6     881  08/01/23             ****    13$

相关问题