数据帧操作:在具有重复索引的新数据帧上“爆炸行”

问题描述 投票:0回答:1

我有两个数据框,例如

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)

但是我想了解熊猫黑带如何处理这个问题,谢谢

python pandas dataframe
1个回答
0
投票

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'
          )
)
© www.soinside.com 2019 - 2024. All rights reserved.