给出这两个数据样本,我想通过一列进行连接,该列在左侧连接数据框中是一个值中的一个元素的列表,而在另一个数据框中是具有附加信息的相同列(主键),而没有以格式列出。
在此示例中
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学习的。
答案 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')