Pandas合并:组合列值和&将新列值合并到同一行

时间:2018-03-12 22:28:56

标签: python pandas merge

我不确定一种方法,甚至合并数据帧的做法是否可以实现我的意图 - 或者我是否需要使用for循环来编写自己的函数。

我希望逐步构建一个主数据框,其中包含来自具有可变列数据的多个较小数据帧的所有可能列值。所有数据帧都来自具有相同名称约定的记录,应避免重复使用相同名称的行

  • 我想先将每个较小的数据帧合并到主文件
  • 不应丢失任何数据。在共享名称的地方,值应合并到主数据框的现有列
  • 不应创建新列
  • 如果两个较小的数据帧在同一列中具有不同的值,我希望这些值共享主,列表或字符串中的相同列无关紧要
  • 当同名的较小数据框条目包含以前未填充的列的新值时,它们应合并到现有行而不是创建新行

1。我的数据框

df_master = pd.DataFrame(columns=('Names','Age','Hair','Breakfast','Lunch','Dinner'))
df_lunch = pd.DataFrame([['Joe',16,'red','sandwich'],['Mary',22,'brown','carrot']],columns=('Names','Age','Hair','Lunch'))
df_ingredients =  pd.DataFrame([['Joe','ham']],columns=('Names','Lunch',))
df_breakfast = pd.DataFrame([['Joe','fruit loops'],['Mary','toast']],columns=('Names','Breakfast',))

2。尝试逐步构建主数据帧

df_master = pd.merge(df_master, df_lunch, on=['Names','Age','Hair','Lunch'], how='outer')

到目前为止,这么好(除了列顺序有趣)

df_master = pd.merge(df_master, df_ingredients, on=['Names','Lunch'], how='outer') 
乔已经获得了新的一排,他的火腿没有添加到他的三明治中

df_master = pd.merge(df_master, df_breakfast, on=['Names','Breakfast'], how='outer') 
乔,玛丽有新行,只是为了容纳早餐

3。理想情况下应该如何看待这个阶段

df_base = pd.DataFrame(columns=('Names','Age','Hair','Breakfast','Lunch','Dinner'))
df_sofar = pd.DataFrame([['Joe',16,'red','fruit loops', 'sandwich, ham'],['Mary',22,'brown','toast','carrot']],columns=('Names','Age','Hair','Breakfast','Lunch'))
df_ideal = pd.merge(df_base, df_sofar, on=['Names','Age','Hair','Breakfast','Lunch'], how='outer') 

显示了我希望从2.看起来的最终数据框

    Dinner  Names   Age Hair    Breakfast   Lunch
0           Joe     16  red     fruit loops sandwich, ham
1           Mary    22  brown   toast       carrot

我是否认为这一切都错了?或者有什么明显的东西我不见了?谢谢!

1 个答案:

答案 0 :(得分:2)

让我们试试concat + groupby + agg

df = pd.concat(
    [df_master, df_lunch, df_ingredients, df_breakfast]
)

g = df.groupby('Names', sort=False, as_index=False).agg(lambda x: ','.join(x.dropna()))
g['Age'] = df_lunch['Age']

  Names    Breakfast Dinner   Hair         Lunch  Age
0   Joe  fruit loops           red  sandwich,ham   16
1  Mary        toast         brown        carrot   22

另类
如果您将所有内容都转换为字符串,则在groupby

期间不会丢失任何信息
df = pd.concat(
        [df_master, df_lunch, df_ingredients, df_breakfast]
    )

df.groupby('Names', sort=False, as_index=False).agg(
        lambda x: ','.join(x.dropna().astype(str))
)

  Names   Age    Breakfast Dinner   Hair         Lunch
0   Joe  16.0  fruit loops           red  sandwich,ham
1  Mary  22.0        toast         brown        carrot