分组合并一个文件到另一个文件

时间:2019-04-03 10:52:50

标签: python pandas

PythonPandas中,我有一个2018年数据框,如下所示:

Date    Stock_id    Stock_value
02/01/2018  1   4
03/01/2018  1   2
05/01/2018  1   7
01/01/2018  2   6
02/01/2018  2   9
03/01/2018  2   4
04/01/2018  2   6

,数据框只有一列,其中包含所有2018年的日期,如下所示:

Date
01/01/2018
02/01/2018
03/01/2018
04/01/2018
05/01/2018
06/01/2018
etc

我想合并这些数据,以获取第一个数据帧,其中包含2018年每只股票的完整日期以及不存在任何数据的资产净值。

基本上,我想在2018年的每个日期为每只股票创建一行(其中没有数据的行应填写NA)。

因此,我想将以下内容作为上述示例的输出:

Date    Stock_id    Stock_value
01/01/2018  1   NA
02/01/2018  1   4
03/01/2018  1   2
04/01/2018  1   NA
05/01/2018  1   7
01/01/2018  2   6
02/01/2018  2   9
03/01/2018  2   4
04/01/2018  2   6
05/01/2018  2   NA

我该怎么做?

我测试过

data = data_1.merge(data_2, on='Date' , how='outer')

data = data_1.merge(data_2, on='Date' , how='right')

但是我仍然得到原始数据框,没有添加任何新日期,而仅添加了一些行,这些行中到处都有NA。

1 个答案:

答案 0 :(得分:2)

product用于Stock_id的所有值组合,并与left join合并:

df1['Date'] = pd.to_datetime(df1['Date'], dayfirst=True)
df2['Date'] = pd.to_datetime(df2['Date'], dayfirst=True)

from  itertools import product

c = ['Stock_id','Date']
df = pd.DataFrame(list(product(df1['Stock_id'].unique(), df2['Date'])), columns=c)
print (df)
    Stock_id       Date
0          1 2018-01-01
1          1 2018-01-02
2          1 2018-01-03
3          1 2018-01-04
4          1 2018-01-05
5          1 2018-01-06
6          2 2018-01-01
7          2 2018-01-02
8          2 2018-01-03
9          2 2018-01-04
10         2 2018-01-05
11         2 2018-01-06

df = df[['Date','Stock_id']].merge(df1, how='left')
#if necessary specify both columns
#df = df[['Date','Stock_id']].merge(df1, how='left', on=['Date','Stock_id'])
print (df)
         Date  Stock_id  Stock_value
0  2018-01-01         1          NaN
1  2018-01-02         1          4.0
2  2018-01-03         1          2.0
3  2018-01-04         1          NaN
4  2018-01-05         1          7.0
5  2018-01-06         1          NaN
6  2018-01-01         2          6.0
7  2018-01-02         2          9.0
8  2018-01-03         2          4.0
9  2018-01-04         2          6.0
10 2018-01-05         2          NaN
11 2018-01-06         2          NaN

另一个想法,但是在大数据中应该慢一些:

df = (df1.groupby('Stock_id')[['Date','Stock_value']]
         .apply(lambda x: x.set_index('Date').reindex(df2['Date']))
         .reset_index())
print (df)
    Stock_id       Date  Stock_value
0          1 2018-01-01          NaN
1          1 2018-01-02          4.0
2          1 2018-01-03          2.0
3          1 2018-01-04          NaN
4          1 2018-01-05          7.0
5          1 2018-01-06          NaN
6          2 2018-01-01          6.0
7          2 2018-01-02          9.0
8          2 2018-01-03          4.0
9          2 2018-01-04          6.0
10         2 2018-01-05          NaN
11         2 2018-01-06          NaN