Python 熊猫合并多个数据帧,保留列并填充其余列

Python 熊猫合并多个数据帧,保留列并填充其余列,python,pandas,dataframe,join,merge,Python,Pandas,Dataframe,Join,Merge,我有一组数据帧df1,df2。。。dfn dfs类似于: id | date | metric_value 001 | 2013-01-01 | 0.73 001 | 2013-03-01 | 0.73 002 | 2013-01-01 | 0.73 002 | 2013-02-01 | 0.73 但是id和date列之间不一定匹配,因此我可以使用类似以下的df1: id | date | metric_value1 00

我有一组数据帧df1,df2。。。dfn

dfs类似于:

 id  |    date    | metric_value
001  | 2013-01-01 |     0.73
001  | 2013-03-01 |     0.73
002  | 2013-01-01 |     0.73
002  | 2013-02-01 |     0.73
但是id和date列之间不一定匹配,因此我可以使用类似以下的df1:

 id  |    date    | metric_value1
001  | 2013-01-01 |     0.73
001  | 2013-03-01 |     0.73
002  | 2013-01-01 |     0.73
002  | 2013-02-01 |     0.73
004  | 2013-03-01 |     0.73
和df2类似:

id   |    date    | metric_value2
001  | 2013-01-01 |     0.72
003  | 2013-02-01 |     0.72
003  | 2013-03-01 |     0.72
004  | 2013-01-01 |     0.72
我如何合并df1和df2,一般来说是df1。。。dfn,所以我可以有这样的东西:

id   |    date    | metric_value1  | metric_value2
001  | 2013-01-01 |     0.73       |       0.72
001  | 2013-02-01 |      Nan       |       Nan
001  | 2013-03-01 |     0.73       |       Nan
002  | 2013-01-01 |     0.73       |       Nan
002  | 2013-02-01 |     0.73       |       Nan
002  | 2013-03-01 |      Nan       |       Nan
003  | 2013-01-01 |      Nan       |       Nan
003  | 2013-02-01 |      Nan       |       0.72
003  | 2013-03-01 |      Nan       |       0.72
004  | 2013-01-01 |      Nan       |       0.72
004  | 2013-02-01 |      Nan       |       Nan
004  | 2013-03-01 |     0.73       |       Nan
要覆盖从最小日期到最大日期的整个日期范围内的所有ID,请尝试:

data='''id|date|metric_value1
001|2013-01-01|0.73
001|2013-03-01|0.73
002|2013-01-01|0.73
002|2013-02-01|0.73
004|2013-03-01|0.73'''
df1 = pd.read_csv(io.StringIO(data), sep='|', engine='python')

data='''id|date|metric_value2
001|2013-01-01|0.72
003|2013-02-01|0.72
003|2013-03-01|0.72
004|2013-01-01|0.72'''
df2 = pd.read_csv(io.StringIO(data), sep='|', engine='python')

df1.merge(df2, on=['id', 'date'], how='outer')
输出:

   id        date  metric_value1  metric_value2
0   1  2013-01-01          0.730          0.720
1   1  2013-03-01          0.730            NaN
2   2  2013-01-01          0.730            NaN
3   2  2013-02-01          0.730            NaN
4   4  2013-03-01          0.730            NaN
5   3  2013-02-01            NaN          0.720
6   3  2013-03-01            NaN          0.720
7   4  2013-01-01            NaN          0.720
    id       date  metric_value1  metric_value2
0    1 2013-01-01           0.73           0.72
1    1 2013-02-01            NaN            NaN
2    1 2013-03-01           0.73            NaN
3    2 2013-01-01           0.73            NaN
4    2 2013-02-01           0.73            NaN
5    2 2013-03-01            NaN            NaN
6    3 2013-01-01            NaN            NaN
7    3 2013-02-01            NaN           0.72
8    3 2013-03-01            NaN           0.72
9    4 2013-01-01            NaN           0.72
10   4 2013-02-01            NaN            NaN
11   4 2013-03-01           0.73            NaN

将@JonathanLeon解决方案再进一步:

import io
import pandas as pd

data='''id|date|metric_value1
001|2013-01-01|0.73
001|2013-03-01|0.73
002|2013-01-01|0.73
002|2013-02-01|0.73
004|2013-03-01|0.73'''
df1 = pd.read_csv(io.StringIO(data), sep='|', engine='python')

data='''id|date|metric_value2
001|2013-01-01|0.72
003|2013-02-01|0.72
003|2013-03-01|0.72
004|2013-01-01|0.72'''
df2 = pd.read_csv(io.StringIO(data), sep='|', engine='python')

df_out = df1.merge(df2, on=['id', 'date'], how='outer')

df_out['date'] = pd.to_datetime(df_out['date'])

df_out.set_index(['id', 'date'])\
      .reindex(pd.MultiIndex.from_product([df_out['id'].unique(),
                                           df_out['date'].unique()],
                                          names=['id', 'date']))\
      .sort_index()
      .reset_index()
输出:

   id        date  metric_value1  metric_value2
0   1  2013-01-01          0.730          0.720
1   1  2013-03-01          0.730            NaN
2   2  2013-01-01          0.730            NaN
3   2  2013-02-01          0.730            NaN
4   4  2013-03-01          0.730            NaN
5   3  2013-02-01            NaN          0.720
6   3  2013-03-01            NaN          0.720
7   4  2013-01-01            NaN          0.720
    id       date  metric_value1  metric_value2
0    1 2013-01-01           0.73           0.72
1    1 2013-02-01            NaN            NaN
2    1 2013-03-01           0.73            NaN
3    2 2013-01-01           0.73            NaN
4    2 2013-02-01           0.73            NaN
5    2 2013-03-01            NaN            NaN
6    3 2013-01-01            NaN            NaN
7    3 2013-02-01            NaN           0.72
8    3 2013-03-01            NaN           0.72
9    4 2013-01-01            NaN           0.72
10   4 2013-02-01            NaN            NaN
11   4 2013-03-01           0.73            NaN

令人惊叹的!!这正是我想要的。该代码是否可以推广到N个dfs,每个dfs具有不同的度量值?我可以这样合并N个数据帧吗?合并一次只能处理两个数据帧。您可以使用join来连接许多数据帧,但您必须首先将所有数据帧的“连接”列移动到索引中。如果我取出df_并与df3合并,然后继续这样做,再与N个数据帧合并,是否有效?如何将所有数据帧的“连接”列首先移动到索引中?是的,您可以将df_与df3合并,依此类推。但是如果使用join,您可以一次完成所有操作。如果索引正确对齐,则连接([df2,df3,…])。