熊猫在列表值的列上左连接

时间:2018-07-26 10:34:50

标签: python pandas

给出这两个数据样本,我想通过一列进行连接,该列在左侧连接数据框中是一个值中的一个元素的列表,而在另一个数据框中是具有附加信息的相同列(主键),而没有以格式列出。

在此示例中

df1 = pd.DataFrame({'ID':[[1111],[2222,3333],[4444,5555],[6666]],'NAME':['foo','bar','zoo','bahh']})
df2 = pd.DataFrame({'ID':[[1111],[2222],[3333],[4444],[5555],[7777]],'ALT_NAME':['foo_alt','bar_alt','zoo_alt','baoo','razz','foo fi']})
    print(df1)
    print(df2)

输出[1]:

    ID              NAME
0   [1111]          foo
1   [2222, 3333]    bar
2   [4444, 5555]    zoo
3   [6666]          bahh

输出[2]:

    ALT_NAME    ID
0   foo_alt     [1111]
1   bar_alt     [2222]
2   wis_alt     [3333]
3   baoo        [4444]
4   razz        [5555]
5   foo fi      [7777]

结果应为:

    ID              NAME    ALT NAME
0   [1111]          foo     [foo_alt]       
1   [2222, 3333]    bar     [bar_alt , wis_alt]
2   [4444, 5555]    zoo     [baoo, razz]        
3   [6666]          bahh    nan

建议的解决方案:

我可以通过将ID分成几列并进行几个左联接来解决它,但是我希望找到更在线或更智能的解决方案。因此,这个问题的本质是面向python学习的。

2 个答案:

答案 0 :(得分:2)

您应该将Ouput [2]转换为地图(熊猫系列),例如:

df2.ID = df2.ID.apply(lambda x: x[0])
s2 = df2.set_index('ID')['ALT_NAME'] # let us rename it s2 as it is a series now!

完成此操作后,您可以简单地使用apply并通过列表理解来获取值:

df1['ALT NAME'] = df1.ID.apply(lambda x: [s2.get(i,None) for i in x])
print(df1)

返回:

             ID  NAME            ALT NAME
0        [1111]   foo           [foo_alt]
1  [2222, 3333]   bar  [bar_alt, zoo_alt]
2  [4444, 5555]   zoo        [baoo, razz]
3        [6666]  bahh              [None]

小注释:这不会在最后一行给您nan。但是,如果您有1个匹配项和1个没有匹配项,那不是[match1,None]吗?。

转换为s2后的df2:

ID
1111    foo_alt
2222    bar_alt
3333    zoo_alt
4444       baoo
5555       razz
7777     foo fi

单行版本:s2 = df2.assign(ID=df2.ID.apply(lambda x: x[0])).set_index('ID')['ALT_NAME']

答案 1 :(得分:0)

我将创建其他列作为字符串类型并将其加入。

df1['ID_STR'] = df1['ID'].astype(str)
df2['ID_STR'] = df2['ID'].astype(str)

df = pd.merge(df1, df2, how = 'left', on = 'ID_STR')