【问题标题】:How to filter dataframe on two columns and output cumulative sum如何过滤两列上的数据框并输出累积和
【发布时间】:2020-07-18 00:56:09
【问题描述】:

我是早期初学者。

我有以下数据框 (df1),其中交易日期为索引,列 = 帐户 #,交易数量和股票代码。

             Account  Quantity Symbol/CUSIP
Trade Date                                 
2020-03-31         1       NaN    990156937
2020-03-31         2     0.020        IIAXX
2020-03-24         1       NaN    990156937
2020-03-20         1   650.000          DOC
2020-03-23         1       NaN    990156937
...              ...       ...          ...
2017-11-24         2    55.000          QQQ
2018-01-01         1    10.000         AMZN
2018-01-01         1   250.000          HOS
2017-09-13         1   229.051        VFINX
2017-09-21         1     1.118        VFINX
[266 rows x 3 columns]

我想填充第二个数据框 (df2),该数据框显示 (df1) 索引的最小值和最大值之间的每一天的总量,按帐户和股票代码分组。下面是我想要做的空数据框:

df2 = Total Quantity by ticker and account #, on every single day between min and max of df1

              990156937 IIAXX  DOC  AER  NaN ATVI    H VCSH GOOGL  VOO   VG  \
2020-03-31 3       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           2       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           1       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
2020-03-30 3       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           2       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           1       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
2020-03-29 3       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           2       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN   
           1       NaN   NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN  NaN  NaN    

因此,对于 df1 中交易日期的最小值和最大值之间的每一天 - 我需要计算该日期或更早的所有交易的累积总和,按帐户和股票代码分组。

我怎么能做到这一点?提前致谢。

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    我建议如下:

    import pandas as pd
    import numpy as np
    
    # first I reproduce a similar dataframe
    df = pd.DataFrame({"date": pd.date_range("2017-1-1", periods=3).repeat(6),
                       "account": [1, 1, 3, 1, 2, 3, 2,2, 1, 1, 2, 3, 1, 2, 3, 2,2,1],
                       "quantity": [123, 0.020, np.NaN, 650, 345, np.NaN, 345, 456, 121, 243, 445, 453, 987, np.NaN, 76, 143, 87, 19],
                       "symbol": ['990156937', '990156937', '990156937', 'DOC', 'AER', 'ATVI', 'AER', 'ATVI', 'IIAXX',
                                  '990156937', '990156937', '990156937', 'DOC', 'AER', 'ATVI', 'AER', 'ATVI', 'IIAXX']})
    

    这就是它的样子:

           date  account  quantity     symbol
    0 2017-01-01        1    123.00  990156937
    1 2017-01-01        1      0.02  990156937
    2 2017-01-01        3       NaN  990156937
    3 2017-01-01        1    650.00        DOC
    4 2017-01-01        2    345.00        AER
    

    您想使用unstack 转到宽格式:

    # You groupby date, account and symbol and sum the quantities
    df = df.groupby(["date", "account", "symbol"]).agg({"quantity":"sum"})
    df_wide = df.unstack()
    # Finally groupby account to get the cumulative sum per account across dates
    # Fill na with 0 to get cumulative sum right
    df_wide = df_wide.fillna(0)
    df_wide = df_wide.groupby(df_wide.index.get_level_values("account")).cumsum()
    

    你得到结果:

                      quantity                            
                       990156937    AER   ATVI    DOC  IIAXX
    date       account                                      
    2017-01-01 1          123.02    0.0    0.0  650.0    0.0
               2            0.00  345.0    0.0    0.0    0.0
               3            0.00    0.0    0.0    0.0    0.0
    2017-01-02 1          366.02    0.0    0.0  650.0  121.0
               2          445.00  690.0  456.0    0.0    0.0
    

    【讨论】:

    • 我希望获得初始 df 的最小值和最大值之间的每一天的累积数量(不仅仅是交易日期)。例如,在您的结果中,DOC 在 2017 年 1 月 3 日也应该是 650.0,并且在 2017 年 1 月 1 日应该有帐户 2 的行。我一直在寻找每个交易品种、每个账户、每天的累计数量。
    • @andrewmarco 我通过添加一个带有 0 的 fillna 来修改答案,以便累积总和根据您的需要工作。在第一个日期没有帐户 2 的行,因为我的示例数据框没有对此进行观察,但我添加了一些,现在帐户 2 确实出现在该日期。它是否符合您想要的输出?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多