df1 = pd.DataFrame({'a':['id1','id2','id3'],'b':['W','W','W'],'c1':[1,2,3]})
df2 = pd.DataFrame({'a':['id1','id2','id3'],'b':['W','W','W'],'c2':[4,5,6]})
df3 = pd.DataFrame({'a':['id1','id4','id5'],'b':['Q','Q','Q'],'c1':[7,8,9]})

我试图将df1 df2df3连接到一个数据帧中:

a    b   c1   c2
id1  W   1    4
id2  W   2    5
id3  W   3    6
id1  Q   7    NA
id4  Q   8    NA
id5  Q   9    NA

我试过:

l = [d.set_index(['a','b']) for d in [df1,df2,df3]]
pd.concat(l, axis=1)

但输出并不是我所期望的:

        c1   c2   c1
a   b               
id1 W  1.0  4.0  NaN
id2 W  2.0  5.0  NaN
id3 W  3.0  6.0  NaN
id1 Q  NaN  NaN  7.0
id4 Q  NaN  NaN  8.0
id5 Q  NaN  NaN  9.0

推荐答案

您可以加入DataFrame.stack创建的MultiIndex Series:

l = [d.set_index(['a','b']).stack() for d in [df1,df2,df3]]
df = pd.concat(l).unstack().sort_index(level=[1,0], ascending=[False, True])
print (df)
        c1   c2
a   b          
id1 W  1.0  4.0
id2 W  2.0  5.0
id3 W  3.0  6.0
id1 Q  7.0  NaN
id4 Q  8.0  NaN
id5 Q  9.0  NaN

如果只有3列数据帧,请使用DataFrame.squeeze或 Select iloc[:, 0]作为系列列表的第一列:

l = [d.set_index(['a','b']).squeeze() for d in [df1,df2,df3]]
keys = [x.name for x in l]
df = (pd.concat(l, axis=0, keys=keys)
        .unstack(0)
        .sort_index(level=[1,0], ascending=[False, True]))
print (df)
        c1   c2
a   b          
id1 W  1.0  4.0
id2 W  2.0  5.0
id3 W  3.0  6.0
id1 Q  7.0  NaN
id4 Q  8.0  NaN
id5 Q  9.0  NaN

l = [d.set_index(['a','b']).iloc[:, 0] for d in [df1,df2,df3]]
keys = [x.name for x in l]
df = (pd.concat(l, axis=0, keys=keys)
        .unstack(0)
        .sort_index(level=[1,0], ascending=[False, True]))

另一个 idea 是将列表中的多个数据帧按DataFrame.combine_first进行链接:

from functools import reduce

dfs = [d.set_index(['a','b']) for d in [df1,df2,df3]]
df = (reduce(lambda x, y: x.combine_first(y), dfs)
        .sort_index(level=[1,0], ascending=[False, True]))
print (df)
        c1   c2
a   b          
id1 W  1.0  4.0
id2 W  2.0  5.0
id3 W  3.0  6.0
id1 Q  7.0  NaN
id4 Q  8.0  NaN
id5 Q  9.0  NaN

Python相关问答推荐

人口全部乱序 - Python—Matplotlib—映射

以异步方式填充Pandas 数据帧

语法错误:文档. evaluate:表达式不是合法表达式

使用Python TCP套接字发送整数并使用C#接收—接收正确数据时出错

用fft计算指数复和代替求和来模拟衍射?

有没有办法让Re.Sub报告它所做的每一次替换?

Python协议不兼容警告

.awk文件可以使用子进程执行吗?

如何在表单中添加管理员风格的输入(PDF)

ValueError:必须在Pandas 中生成聚合值

如何将django url参数传递给模板&S url方法?

Python-迭代PANAS中的数据框并替换列表中不包含字符串的值

没有与提供的参数匹配

从html获取元素时出现问题

如何reshape 极地数据帧?

我很难用Python Pandas打开旧格式的XLS文件

多索引数据帧:对每个组的值进行排序

无法调用Python文档对象

如何计算数据集中的类别值并将求和转换为新的数据集?

在LangChain和OpenAI嵌入中没有从链中获取源文档