在类似Python的Excel VLOOKUP中使用部分字符串匹配进行合并

2024-09-30 20:17:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数据集:销售(公司名称)和;营销(联系人和公司名称)。我希望将营销数据集中的公司名称与销售数据集中的公司名称进行匹配,即使(尤其是)存在部分匹配

样本数据

sales_df = pd.DataFrame({'CompanyName': ['EDF', 'EDF Business', 'L'Oreal France', 'L'oreal Produits De Luxe Belgilux - Be'],        

marketing_df = pd.DataFrame({'ContactName': ['Eddie', 'Antoine', 'Tracy', 'Iria'],
                'Email': ['eddie@edf.fr', 'antoine.g@edf.fr', 'tracy@us.loreal.com', 'iria@loreal.com'],
                'CompanyName': ['EDF', 'EDF', 'L'Oréal', 'L’Oreal Produit Luxe France''],
                'Industry': ['Energy', 'Energy', 'CPG', 'CPG']})

最终,我将寻求一种类似于Excel中的VLOOKUP的解决方案,其中我返回与销售数据集中的公司名称匹配/部分匹配的营销数据集行。这样,我就有了公司和联系人级别(电子邮件地址和联系人姓名)数据,可以用来知道营销数据集中的哪些联系人属于销售数据集中的公司

期望结果

    ContactName Email               CompanyName    Industry
0   Eddie       eddie@edf.fr        edf            Energy
1   Antoine     antoine.g@edf.fr    edf            Energy
2   Tracy       tracy@us.loreal.com loreal...      CPG
3   Iria        iria@loreal.com     loreal...      Energy

基本上,我想从我的销售数据集中保留所有联系人级别的数据,只要该联系人属于某个公司

在这里,我清理我的数据

# import Pandas
import pandas as pd

# Convert spreadsheets into data frames
marketing_df = pd.read_csv('/Users/me/Desktop/Project Data/Country_MKTG_data.csv')
sales_df = pd.read_csv('/Users/me/Desktop/Project Data/Country_Sales_data.csv')

# Display all rows & drop null values in company name columns  
pd.set_option('display.max_rows', None)
marketing_df['CompanyMKTG'] = marketing_df['CompanyMKTG'].dropna()
sales_df['CompanySales'] = sales_df['CompanySales'].dropna()

# Make all company names lower case   
sales_df['CompanySales'] = sales_df['CompanySales'].str.lower()
marketing_df['CompanyMKTG'] = marketing_df['CompanyMKTG'].str.lower()

# Eliminate unwanted characters & words    
bad_characters = ['-', ',', '.', '?', '~', '/', 'france', 'ltd', 'uk', 'sa', 'sas', 'the', 'spain', 'japan', 'usa', 'la', 'le', 'de']

for element in bad_characters:
     marketing_df['CompanyMKTG'] = marketing_df['CompanyMKTG'].str.replace(element, '', case=False)
     sales_df['CompanySales'] = sales_df['CompanySales'].str.replace(element, '', case=False)

# Clean white space  
marketing_df['CompanyMKTG'] = marketing_df['CompanyMKTG'].str.rstrip().str.replace(' ', '')
sales_df['CompanySales'] = sales_df['CompanySales'].str.rstrip().str.replace(' ', '')

问题是,在清理数据之后,我无法使用部分字符串匹配合并数据帧。我尝试过许多不同的方法:合并、合并、使用difflib进行百分比匹配、转换为集合以及查找两个集合的交集

我的最新解决方案是检查我的两个数据集中的公司名称是否是彼此的子字符串,然后用我的销售数据集中的名称替换我的营销数据集中的公司名称。通过这种方式,我可以导出一个新的数据框,其中包含仅属于销售数据集中公司的营销联系人

# Replace company names in MKTG data set
real_comp = sales_df['CompanySales'].tolist()

for i in marketing_df:
      if i['CompanyMKTG'].isin(real_comp):
        if i['CompanyMKTG'].issubstring(real_comp[real_comp.get_index(i['CompanySales'])]):
          if real_comp[real_comp.get_index(i['CompanySales'])].issubstring((i['CompanyMKTG'])):
            marketing_df['CompanyMKTG'].replace(real_comp, inplace=True)
            i['CompanySales'] = real_comp[real_comp.get_index(i['CompanyMKTG'])]

但我一直得到TypeError:字符串索引必须是整数

或者使用pd.series.apply返回部分字符串匹配的行

def get_match(x):
   return marketing_df.loc[marketing_df['CompanyMKTG'].str.contains(x, na=False), 'EmailAddress'].iloc[0]

sales_df['Match'] = sales_df['CompanySales'].apply(get_match)
print(sales_df)

但这样我就得到了索引器:单位置索引器是出界的


Tags: 数据名称df联系人公司realmarketingpd
1条回答
网友
1楼 · 发布于 2024-09-30 20:17:21

出现错误的原因是,当使用for循环在DF中交互时,会得到字符串格式的列名称,这就是i['CompanyMKTG']抛出错误的原因

为了避免此错误,可以使用iterrows方法对行进行迭代

for index , row in marketing_df.iterrows()

因为您希望通过比较销售数据集公司名称从营销数据集中提取数据。在完成所有清洁过程后,您可以使用下面的方法

marketing_df[marketing_df['CompanyMKTG'].isin(sales_df)]

请注意,对于数据帧或序列,没有issubstring方法。请参阅文件>;https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.isin.html

在IF语句中使用isin()方法也会引发异常/错误,因为o/p是不明确的。如果您想使用多个条件,您可以使用下面的验证条件并打印结果营销数据集

r=[]
for i, row in marketing_df.iterrows():
    if row['CompanyMKTG'] in str(sales_df['CompanyMKTG']):
        r.append(row['CompanyMKTG'])
marketing_df[marketing_df['CompanyMKTG'].isin(r)] 

相关问题 更多 >