如何合并/连接两个具有部分字符串匹配的列的数据框?

时间:2019-04-28 01:20:25

标签: python pandas

我使用芝加哥犯罪数据进行分析,但未提供社区名称,因此我从在线来源收集了芝加哥的社区名称。但是,Redfin房地产数据是按地区/​​社区而不是社区名称收集的。当我尝试将假定的芝加哥犯罪数据与Redfin房地产数据合并时,由于Redfin数据中的“区域名称”与芝加哥犯罪数据具有部分字符串匹配,因此出现合并错误。我尝试regex首先进行部分匹配,然后按年份和社区名称的名称合并两个数据框。

是否有任何解决方案来合并两个数据列,这些数据列的列会产生部分字符串匹配?有人可以指出我吗?谢谢

预处理数据

在这里,我创建了公共要领来查看我使用的数据:

exampled data snippet on public gist

我的尝试

pd.merge(chicago_crime, redfin, left_on='community_name', right_on='Region')

但是这给了我很多NAN,这意味着上述串联是不正确的。我该怎么办?有什么办法解决这个问题吗?谢谢

2 个答案:

答案 0 :(得分:2)

快速浏览两个数据集,似乎Chicago.Region的格式为Chicago, IL - region_name,而Redfin.community_name的格式为region_name。所以我尝试了:

areas = ['Chicago, IL - ' + s for s in redfin.community_name.unique()] 

# check if areas in the chicago.Region
a = [s in chicago.Region.unique() for s in areas]
sum(a), len(a)
# 63, 77

匹配redfin.community.unique()中77个区域中的63个。如果足够好,您可以执行以下操作:

pd.merge(redfin, chicago, 
         left_on='Chicago, IL - ' + redfin.community_name, 
         right_on='Region')

答案 1 :(得分:2)

这是我的方法。第一种方法是应用split()在两个数据帧中拆分键列中的每个单词。

chicago_crime['community_name'] = [cn.split() for cn in chicago_crime['community_name']]
redfin['Region'] = [rg.split() for rg in redfin['Region']]

然后,我尝试将chicago_crime中列结果列表中的每个元素与redfin中列结果列表中的每个元素进行比较。然后,将匹配的元素存储在两个数据帧的名为merge_ref的新列中。

idx, datavalue = [], []
for i,dv in enumerate(chicago_crime['community_name']):
    for d in dv:
        if d in redfin['Region'][i]:   
            if i not in idx:
                idx.append(i)
                datavalue.append(d)
chicago_crime['merge_ref'] = datavalue
redfin['merge_ref'] = datavalue

最后,在merge_ref上合并两个数据框:

df_merge = pd.merge(chicago_crime[['community_area','community_name','merge_ref']], redfin, on='merge_ref')

但是,由于两个数据帧中merge_ref中的值不是唯一的,因此行数可能会增加。至少,它给了你一个提示。

已更新

使用地图绘制解决方案:

### mapping neiborhood to community name

code_pairs_neighborhoods = [[p[0], p[1]] for p in [pair.strip().split('\t') for pair in neighborhood_Map.strip().split('\n')]]
neighborhood_name_dic = {k[0]:k[1] for k in code_pairs_neighborhoods} #neighborhood -> community area

chicago_crime['neighborhood'] = chicago_crime['community_name'].map(neighborhood_name_dic)
redfin['neighborhood'] = redfin['Region'].map(neighborhood_name_dic)

df_merge = pd.merge(chicago_crime, redfin, on='neighborhood')
print(df_merge)