多级熊猫groupby

时间:2017-07-12 08:41:47

标签: python pandas pandas-groupby

我需要保持“每个帐户每个团队的每个代码”的位置。所以我认为可能会使用pandas groupby。我试图在dataframe的评论中陈述我的问题。我已手动添加了位置列。

初始df我有

             time account scrip  buy_price  sell_price  qty   team  
0  06/07/17 09:36      A1  FUT1       50.0         NaN    2  team1         
1  06/07/17 09:46      A2  FUT1      100.0         NaN    2  team1         
2  06/07/17 09:56      A3  FUT1       10.0         NaN    2  team2         
3  06/07/17 09:57      A3  FUT1        NaN        10.0    2  team2         
4  06/07/17 09:58      A1  FUT1        NaN        50.0    1  team1         
5  06/07/17 09:59      A3  FUT1        NaN        50.0    1  team2 

我需要添加位置。我已手动添加了位置列,并在评论中写了一些附加说明,以明确如何计算位置。

             time account scrip  buy_price  sell_price  qty   team  position                                    comment
0  06/07/17 09:36      A1  FUT1       50.0         NaN    2  team1         2  this can only be sold by team1 account A1
1  06/07/17 09:46      A2  FUT1      100.0         NaN    2  team1         2  this can only be sold by team1 account A2
2  06/07/17 09:56      A3  FUT1       10.0         NaN    2  team2         2  this can only be sold by team2 account A3
3  06/07/17 09:57      A3  FUT1        NaN        10.0    2  team2         0                 sold by team 2 in  acc A3 
4  06/07/17 09:58      A1  FUT1        NaN        50.0    1  team1         1                  sold by team 1 in acc A1 
5  06/07/17 09:59      A3  FUT1        NaN        50.0    1  team2        -1                   sold by team 2 in acc A3

以上示例仅适用于1个脚本FUT1,会有很多写法。我的最终结果将类似于。

Team Account Scrip Position
team1 A1      FUT1 1 
      A2      FUT1 2
team2 A3      FUT1 -1

一旦成功计算位置,最终结果可以在稍后处理。 我的方法是:在每一行中创建一个唯一的键,以便知道何时+或 - 位置。例如。对于A1_FUT1_team1row1 A2_FUT1_team1row2。然后添加减法匹配键。这无论如何都是一个好方法吗?

2 个答案:

答案 0 :(得分:1)

您的问题可以通过两个步骤轻松解决:

第一步:

import math
df['some_stuff'] = df.apply(lambda x: -x.qty if math.isnan(x.buy_price) else x.qty,axis=1)

这一行正在创建一个新列some_stuff,为什么我这样做只是为了在您的数据中引入gain and loss的一些逻辑。

如果您不想要新列,并且您喜欢这个想法,只需将qty列替换为:

df['qty'] = df.apply(lambda x: -x.qty if math.isnan(x.buy_price) else x.qty,axis=1)

接下来,我使用此新列创建您的position column,如下所示:

df['position'] = df.groupby(['team','account','scrip'])['some_stuff'].cumsum()

生成此列:

position
       2
       2
       2
       0
       1
      -1

奖金:

如果您想删除额外的列some_stuff,只需使用:

del df['some_stuff']

第二步:

这是您使用此行获取最终分组表的步骤:

print(df.groupby(['team', 'account', 'scrip']).min())

最终输出:

                               time  buy_price  sell_price  qty  position
team  account scrip                                                      
team1 A1      FUT1   06/07/17 09:36       50.0        50.0    1         1
      A2      FUT1   06/07/17 09:46      100.0         NaN    2         2
team2 A3      FUT1   06/07/17 09:56       10.0        10.0    1        -1

我相信这会回答你的问题。

<强>文档

pandas.DataFrame.apply

pandas.Groupby

pandas.DataFrame.cumsum

pandas.DataFrame.min

答案 1 :(得分:0)

这就是你要找的东西吗?

df.groupby(['team', 'account', 'scrip']).min()
它给了我:

                      time  buy_price  sell_price  qty  position
team  account scrip                                             
team1 A1      FUT1   09:36       50.0        50.0    1         1
      A2      FUT1   09:46      100.0         NaN    2         2
team2 A3      FUT1   09:56       10.0        10.0    1        -1

比您想要的更多列,但您可以对您要查找的内容进行细分。

(groupby默认情况下将分组列移动到多级索引,但如果这不是你想要的,你可以在as_index=False中添加.groupby()作为arg