pandas 在DataFrame中合并两个以上的列而不复制列

6l7fqoea  于 2023-06-04  发布在  其他
关注(0)|答案(2)|浏览(144)

我有一个问题,我不知道如何解决:假设我有三个不同的 Dataframe :
df1:
| 一个|B| C类|
| - -----|- -----|- -----|
| a1| b1| C1|
| a2| b2| C2|
| A3| b3| C3|
df2:
| B| D| E级|
| - -----|- -----|- -----|
| b1| d1| e1|
| b4| d4| E4|
| NaN| d5| E5|
df3:
| 一个|D| F级|G型|
| - -----|- -----|- -----|- -----|
| A3| d3| F3| G3|
| NaN| d4| f4| g4|
| NaN| d5| f5| G5|
考虑到没有列存在于所有的 Dataframe 中,但是在两个 Dataframe 之间总是至少有一个列是公共的,我希望有一种方法将这些 Dataframe 合并成一个 Dataframe 。我所期望的是这样的:
| 一个|B| C类|D| E级|F级|G型|
| - -----|- -----|- -----|- -----|- -----|- -----|- -----|
| a1| b1| C1| d1| e1| NaN| NaN|
| a2| b2| C2| NaN| NaN| NaN| NaN|
| A3| b3| C3| d3| NaN| F3| G3|
| NaN| b4| NaN| d4| E4| f4| g4|
| NaN| NaN| NaN| d5| E5| f5| G5|
我尝试使用pd.concat,但结果是重复列或将DataFrame的行粘贴到另一个DataFrame的下面,而不是以我期望的方式关联列。

iklwldmw

iklwldmw1#

可能有更简单的方法,但是:
在关联它们之后,您可以找到在每列中包含匹配值的行的索引。

df_m = pd.concat([df1, df2, df3], ignore_index=True)

groups = (
   df_m.stack()
       .to_frame()
       .reset_index()
       .set_axis(['row', 'col', 'value'], axis=1)
       .groupby(['col', 'value'])
)
rows = groups.agg(tuple)[groups.count() > 1].dropna().reset_index(drop=True)['row'].explode()

rows爆炸前:

0    (2, 6)
1    (0, 3)
2    (4, 7)
3    (5, 8)
Name: row, dtype: object

所以行2, 6需要被“组合”,0, 3等等。
一种方法是将它们的索引设置为相同的值并使用.groupby
例如,将其转换为{ 2: 2, 6: 2, 0: 0, 3: 0, ... }
然后我们可以.groupby().first()来获得每个“组合”行:

idx = rows.groupby(level=0).transform('first').set_axis(rows)
idx = df_m.index.to_series().map(idx).fillna(df_m.index.to_series())

df.groupby(idx).first()
A     B     C     D     E     F     G
0    a1    b1    c1    d1    e1  None  None
1    a2    b2    c2  None  None  None  None
2    a3    b3    c3    d3  None    f3    g3
4  None    b4  None    d4    e4    f4    g4
5  None  None  None    d5    e5    f5    g5
v2g6jxz6

v2g6jxz62#

你可以这样做:

from functools import reduce
l = lambda x: x[x.first_valid_index()][1]
df_out = reduce(lambda x, y: x.set_index(x.apply(l, axis=1)).combine_first(y.set_index(y.apply(l, axis=1))), [df1,df2,df3])

df_out

输出:

A    B    C    D    E    F    G
1   a1   b1   c1   d1   e1  NaN  NaN
2   a2   b2   c2  NaN  NaN  NaN  NaN
3   a3   b3   c3   d3  NaN   f3   g3
4  NaN   b4  NaN   b4   e4   f4   g4
5  NaN  NaN  NaN   d5   e5   f5   g5

详细信息,创建一个函数,定义值代表哪一行,即set_index。然后使用df.combine_first将所有 Dataframe 合并到 Dataframe 索引和列标题上。使用functools.reduce,您可以合并两个以上的 Dataframe 。

相关问题