熊猫:以日期为基础的DataFrames的复杂合并

时间:2019-02-18 17:14:25

标签: python pandas sorting date dataframe

我有两只大熊猫DataFrame,我需要以一些复杂的方式进行合并,因此我需要一些帮助。

要插入的DataFrame:

            AAPL shares  GOOG shares  MSFT shares
date                                             
2019-01-01          0.0         10.0          0.0
2019-01-05          0.0          0.0         15.0
2019-01-12          0.0          0.0          7.0
2019-01-13          3.0          0.0          0.0
2019-01-14          0.0         -5.0          0.0

DataFrame接收插入

               0      1           2        3           4       5
0     1998-01-02  16.25  2014-03-27   558.46  1998-01-02  131.13
1     1998-01-05  15.88  2014-03-28   559.99  1998-01-05  130.38
2     1998-01-06  18.94  2014-03-31   556.97  1998-01-06  131.13
3     1998-01-07  17.50  2014-04-01   567.16  1998-01-07  129.56
4     1998-01-08  18.19  2014-04-02   567.00  1998-01-08  130.50
5     1998-01-09  18.19  2014-04-03   569.74  1998-01-09  127.00
6     1998-01-12  18.25  2014-04-04   543.14  1998-01-12  129.50
7     1998-01-13  19.50  2014-04-07   538.15  1998-01-13  132.13
8     1998-01-14  19.75  2014-04-08   554.90  1998-01-14  131.13
9     1998-01-15  19.19  2014-04-09   564.14  1998-01-15  132.31
10    1998-01-16  18.81  2014-04-10   540.95  1998-01-16  135.25
11    1998-01-20  19.06  2014-04-11   530.60  1998-01-20  137.81
12    1998-01-21  18.91  2014-04-14   532.52  1998-01-21  137.00
13    1998-01-22  19.25  2014-04-15   536.44  1998-01-22  138.63
14    1998-01-23  19.50  2014-04-16   556.54  1998-01-23  138.25
15    1998-01-26  19.44  2014-04-17   536.10  1998-01-26  141.75

1)receiving_df需要为date建立通用基础(注意,列2有所不同),因此DataFrame需要组织成{{1 }},date13,其中502的日期用于组装{{1} },以在特定日期正确反映4date1中的值。

第1步中的示例输出

3

2)5将需要根据日期 0 1 3 5 0 1998-01-02 16.25 NA 131.13 1 1998-01-05 15.88 NA 130.38 2 1998-01-06 18.94 NA 131.13 3 1998-01-07 17.50 NA 129.56 4 1998-01-08 18.19 NA 130.50 5 1998-01-09 18.19 NA 127.00 6 1998-01-12 18.25 NA 129.50 7 1998-01-13 19.50 NA 132.13 8 1998-01-14 19.75 NA 131.13 ... 10 2014-04-10 18.81 558.46 135.25 11 2014-04-11 19.06 559.99 137.81 12 2014-04-14 18.91 556.97 137.00 13 2014-04-15 19.25 567.16 138.63 14 2014-04-16 19.50 567.00 138.25 15 2014-04-17 19.44 569.74 141.75 ... 进行排序,并且inserting_dfreceiving_df['date']AAPL shares列将添加为GOOG shares。我想这将遵循与1)类似的方法。

第2步中的示例输出

MSFT shares

3)新列receiving_df 0 AAPL shares 1 GOOG shares 3 MSFT shares 5 0 1998-01-02 0.0 16.25 0.0 NA 0.0 131.13 1 1998-01-05 0.0 15.88 0.0 NA 0.0 130.38 2 1998-01-06 0.0 18.94 0.0 NA 0.0 131.13 3 1998-01-07 0.0 17.50 0.0 NA 0.0 129.56 4 1998-01-08 0.0 18.19 0.0 NA 0.0 130.50 5 1998-01-09 0.0 18.19 0.0 NA 0.0 127.00 6 1998-01-12 0.0 18.25 0.0 NA 0.0 129.50 7 1998-01-13 0.0 19.50 0.0 NA 0.0 132.13 8 1998-01-14 0.0 19.75 0.0 NA 0.0 131.13 ... 10 2014-04-10 0.0 18.81 0.0 558.46 0.0 135.25 11 2014-04-11 0.0 19.06 0.0 559.99 0.0 137.81 12 2014-04-14 0.0 18.91 0.0 556.97 0.0 137.00 13 2014-04-15 0.0 19.25 0.0 567.16 0.0 138.63 14 2014-04-16 0.0 19.50 0.0 567.00 0.0 138.25 15 2014-04-17 0.0 19.44 0.0 569.74 0.0 141.75 ... <#> 2019-01-01 0.0 <value> 10.0 <value> 0.0 <value> <#> 2019-01-02 0.0 <value> 0.0 <value> 15.0 <value> <#> 2019-01-03 0.0 <value> 0.0 <value> 7.0 <value> <#> 2019-01-04 3.0 <value> 0.0 <value> 0.0 <value> <#> 2019-01-05 0.0 <value> -5.0 <value> 0.0 <value> AAPL shares需要用cumsum填充,但我认为我的意思是: 〜GOOG shares

第3步中的示例输出

MSFT shares

因此最终目标将导致根据df.set_index('date').sort_index().fillna(value=0).cumsum())索引持有的价值和份额。对于在结果 0 AAPL shares 1 GOOG shares 3 MSFT shares 5 0 1998-01-02 0.0 16.25 0.0 NA 0.0 131.13 1 1998-01-05 0.0 15.88 0.0 NA 0.0 130.38 2 1998-01-06 0.0 18.94 0.0 NA 0.0 131.13 3 1998-01-07 0.0 17.50 0.0 NA 0.0 129.56 4 1998-01-08 0.0 18.19 0.0 NA 0.0 130.50 5 1998-01-09 0.0 18.19 0.0 NA 0.0 127.00 6 1998-01-12 0.0 18.25 0.0 NA 0.0 129.50 7 1998-01-13 0.0 19.50 0.0 NA 0.0 132.13 8 1998-01-14 0.0 19.75 0.0 NA 0.0 131.13 ... 10 2014-04-10 0.0 18.81 0.0 558.46 0.0 135.25 11 2014-04-11 0.0 19.06 0.0 559.99 0.0 137.81 12 2014-04-14 0.0 18.91 0.0 556.97 0.0 137.00 13 2014-04-15 0.0 19.25 0.0 567.16 0.0 138.63 14 2014-04-16 0.0 19.50 0.0 567.00 0.0 138.25 15 2014-04-17 0.0 19.44 0.0 569.74 0.0 141.75 ... <#> 2019-01-01 0.0 <value> 10.0 <value> 0.0 <value> <#> 2019-01-02 0.0 <value> 10.0 <value> 15.0 <value> <#> 2019-01-03 0.0 <value> 10.0 <value> 22.0 <value> <#> 2019-01-04 3.0 <value> 10.0 <value> 22.0 <value> <#> 2019-01-05 3.0 <value> 5.0 <value> 22.0 <value> 中将没有列date值的date(由于列2“缺少”一些日期),最好使该值2但0就足够了。

很高兴澄清任何事情,感谢任何/所有帮助,因为这是一个非常复杂的操作(至少对我而言),在此先感谢您!

编辑: 由于receiving_df-N/A对的数量可能会有所不同,因此现在尝试合并成一个循环。现在,我有date-value对的单独DataFrames列表:date。由于对的数量可能有所不同,因此最好不要基于列标签value dfs_list

set_index

1 个答案:

答案 0 :(得分:0)

根据您的解释,这就是我所知道的解决方案。

在给定的数据帧的情况下,我添加了列名以使情况更清楚,并将receive_df重命名为df以节省键入:

df.columns=['d1','p1','d2','p2','d3','p3']

df1=pd.merge(left=df[['d1','p1']].set_index('d1'),right=df[['d3','p3']].set_index('d3'), left_index=True, right_index=True, how='outer')

df1.head()

            p1      p3
d1      
1998-01-02  16.25   131.13
1998-01-05  15.88   130.38
1998-01-06  18.94   131.13
1998-01-07  17.50   129.56
1998-01-08  18.19   130.50

rec_df=pd.merge(left=df1,right=df[['d2','p2']].set_index('d2'),left_index=True, right_index=True, how='outer')

rec_df

            p1      p3      p2
1998-01-02  16.25   131.13  NaN
1998-01-05  15.88   130.38  NaN
1998-01-06  18.94   131.13  NaN
1998-01-07  17.50   129.56  NaN
1998-01-08  18.19   130.50  NaN
1998-01-09  18.19   127.00  NaN
1998-01-12  18.25   129.50  NaN
1998-01-13  19.50   132.13  NaN
1998-01-14  19.75   131.13  NaN
1998-01-15  19.19   132.31  NaN
1998-01-16  18.81   135.25  NaN
1998-01-20  19.06   137.81  NaN
1998-01-21  18.91   137.00  NaN
1998-01-22  19.25   138.63  NaN
1998-01-23  19.50   138.25  NaN
1998-01-26  19.44   141.75  NaN
2014-03-27  NaN NaN 558.46
2014-03-28  NaN NaN 559.99
2014-03-31  NaN NaN 556.97
2014-04-01  NaN NaN 567.16
2014-04-02  NaN NaN 567.00
2014-04-03  NaN NaN 569.74
2014-04-04  NaN NaN 543.14
2014-04-07  NaN NaN 538.15
2014-04-08  NaN NaN 554.90
2014-04-09  NaN NaN 564.14
2014-04-10  NaN NaN 540.95
2014-04-11  NaN NaN 530.60
2014-04-14  NaN NaN 532.52
2014-04-15  NaN NaN 536.44
2014-04-16  NaN NaN 556.54
2014-04-17  NaN NaN 536.10

现在,这是我无法测试的地方,因为您的插入df没有与接收df相匹配的日期索引,但是应该看起来像

final_df=pd.merge(left=rec_df, right=insert_df, left_index=True, right_index=True, dropna=False)

当然,这假定date列已被设置为样本中的索引。如果要在末尾使用数字索引,则可以reset_index(in_place=True),也可以将日期保留为索引。

看起来您已经完成了任务的最后一部分,无论如何我都无法使用给定的数据对其进行测试。

还要注意,您可以根据需要对列进行重新排序,具体取决于您希望输出的外观(df=df[[list of columns in order]]