我有两个数据框,例如
df1
和 df2
import pandas as pd
col_1= ["A", ["B","C"], ["A","C","D"], "D"]
col_id = [1,2,3,4]
col_2 = [1,2,2,3,3,4,4]
d1 = {'ID': [1,2,3,4], 'Labels': col_1}
d2 = {'ID': col_2, }
d_2_get = {'ID': col_2, "Labels": ["A", "B", "C", "A", "C", "D", np.nan] }
df1 = pd.DataFrame(data=d1)
df2 = pd.DataFrame(data=d2)
df_2_get = pd.DataFrame(data=d_2_get)
df1
看起来像
ID col2
0 1 A
1 2 [B, C]
2 3 [A, C, D]
3 4 D
和
df2
看起来像
ID
0 1
1 2
2 2
3 3
4 3
5 4
6 4
我想将一列
Labels
添加到df2
,取自df1
,这样:
i
,从 df1
df2["ID"]
中的新行有重复条目,则获取 df1
中的下一个值(如果存在)。如果没有,请设置 NaN
。给定
df1
和 df2
,输出应如下所示df_2_get
ID Labels
0 1 A
1 2 B
2 2 C
3 3 A
4 3 C
5 4 D
6 4 NaN
我目前笨拙的尝试如下,
from collections import Counter
def list_flattener(list_of_lists):
return [item for row in list_of_lists for item in row]
def my_dataframe_filler(df1, df2):
list_2_fill = []
repeats = dict(Counter(df2["ID"]))
for k in repeats.keys():
available_labels_list = df1[df1["ID"]==k]["Labels"].tolist()
available_labels_list+=[[np.nan]*10]
available_labels_list = list_flattener(available_labels_list)
list_2_fill+=available_labels_list[:repeats[k]]
return list_2_fill
然后用作
df2["Labels"] = my_dataframe_filler(df1, df2)
但是我想了解熊猫黑带如何处理这个问题,谢谢
IIUC,您可以
explode
并在使用 merge
进行重复数据删除后执行 groupby.cumcount
:
out = (df2
.assign(n=df2.groupby('ID').cumcount())
.merge(df1.explode('Labels').assign(n=lambda x: x.groupby('ID').cumcount()),
on=['ID', 'n'], how='left'
)
)