如何合并DataFrame中同源多列为单列并保留其他列关联数据
如何合并DataFrame中同源多列为单列并保留其他列关联数据
看起来你需要把多个来源的网站列合并成单列,同时让每个网站和该公司的所有城市做全关联,对吧?我来帮你用pandas一步步实现这个需求,完全贴合你的示例输出。
首先,我们先模拟你的输入数据(你可以直接替换成自己的DataFrame):
import pandas as pd # 模拟你的输入数据 data = { 'index': [1,2,3,4,5,6,7], 'CompanyName': ['Comp1','Comp1','Comp2','Comp2','Comp3','Comp4','Comp5'], 'Source1site': ['web1.com','Web2.com',pd.NA,pd.NA,pd.NA,pd.NA,pd.NA], 'Source2site': [pd.NA,'web2.com','site1.com',pd.NA,pd.NA,'url1.com','example.com'], 'Source3site': ['web2.com',pd.NA,pd.NA,pd.NA,pd.NA,pd.NA,pd.NA], 'City': ['Paris',pd.NA,'Oakland','London','Mexico',pd.NA,'New York'] } df = pd.DataFrame(data)
接下来分三步处理:
第一步:提取每个公司的所有非空网站(去重)
我们用melt把三列网站数据转成单列,然后过滤空值、去重:
# 将多列网站转成单列,收集所有非空值并去重 sites = df.melt( id_vars='CompanyName', value_vars=['Source1site', 'Source2site', 'Source3site'], value_name='MergeSourceSite' ) # 移除空值、多余列,去重(可选:统一网站大小写,避免Web2.com和web2.com视为不同) sites = sites.dropna(subset=['MergeSourceSite']).drop(columns='variable') sites['MergeSourceSite'] = sites['MergeSourceSite'].str.lower() # 不需要的话可以删掉这行 sites = sites.drop_duplicates()
第二步:提取每个公司的所有非空城市(去重)
单独提取城市列,过滤空值并去重:
cities = df[['CompanyName', 'City']].dropna(subset=['City']).drop_duplicates()
第三步:关联网站和城市,处理空值情况
我们需要把每个公司的网站和城市做全组合(笛卡尔积),同时保留没有网站/城市的公司条目:
# 获取所有公司的列表,确保不遗漏任何公司 all_companies = df[['CompanyName']].drop_duplicates() # 为没有网站的公司添加空值条目 sites_with_nan = pd.merge(all_companies, sites, on='CompanyName', how='left') # 为没有城市的公司添加空值条目 cities_with_nan = pd.merge(all_companies, cities, on='CompanyName', how='left') # 做笛卡尔积,得到每个网站和城市的组合 result = pd.merge(sites_with_nan, cities_with_nan, on='CompanyName', how='outer') # 重置索引,匹配你的输出格式(索引从1开始) result = result.reset_index(drop=True) result.index += 1
运行完上面的代码后,result就是你想要的输出啦!比如:
CompanyName MergeSourceSite City 1 Comp1 web1.com Paris 2 Comp1 web2.com Paris 3 Comp2 site1.com Oakland 4 Comp2 site1.com London 5 Comp2 site2.com Oakland 6 Comp2 site2.com London 7 Comp3 NaN Mexico 8 Comp4 url1.com NaN 9 Comp5 example.com New York
如果不需要统一网站的大小写,删掉str.lower()那一行就行,这样Web2.com会保留原格式。
备注:内容来源于stack exchange,提问作者Anas
相关产品推荐
相关产品推荐

