【问题标题】:Multi level pandas groupby多级熊猫 groupby
【发布时间】:2017-07-12 08:41:46
【问题描述】:

我需要保持“每个团队每个帐户每个脚本”的位置。所以我认为可能会使用熊猫groupby。我也试图在数据框的评论中陈述我的问题。位置栏是我手动添加的。

我有初始 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。然后添加减法匹配键。这到底是个好方法吗?

【问题讨论】:

  • 您能展示一下您实际尝试过的内容吗?
  • 怎么样? row1:pos=+2 因为 t1a1 购买了 2 个数量,row2:pos=+2 因为 t1a2 购买了 2 个数量,row3:pos:+2 因为 t2a3 购买了 2 个数量,row4:pos=0 因为 t23 出售了 2 个数量等等。你看错什么了。? t1a1=>team1account1
  • 哦,现在我明白了,不过 cmets 列还不够清晰

标签: python pandas pandas-groupby


【解决方案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

【讨论】:

  • 感谢您的帮助,我正在尝试将此部分嵌入到我的代码中。我认为 df['position'] = df.groupby(['team','account'])['some_stuff'].cumsum() 应该是 df['position'] = df.groupby(['team','account','scrip'])['some_stuff'].cumsum() 因为我需要每个脚本的位置
  • @pythonRcpp 很好,我不知道您的其余数据如何,并且由于在您的评论列中没有对脚本的引用,我只是做了一些适合提供的示例的事情,但是是的,对于整个事情,我认为你应该按团队、帐户和脚本分组。我也会在答案中添加它
  • 嘿,有没有办法得到每组的最后一行?在完成df['position'] = df.groupby(['team','account','scrip'])['some_stuff'].cumsum() 之后,我想要另一个数据框,它只创建了每个组的最后一行。 (所以我有每个组的最终位置)。
  • @pythonRcpp,即使我对您要实现的目标有所了解,我也无法确定或在测试之前给您答案并回答可能是错误的,因此请创建另一个详细的问题,带有一些示例和所需的输出,并在此处传递链接,我将对其进行检查。很抱歉给您带来不便
【解决方案2】:

这是你要找的吗?

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 默认将分组列移动到多级索引,但如果这不是您想要的,您可以在 .groupby() 中添加 as_index=False 作为 arg)

【讨论】:

  • 我首先需要添加位置列。正确添加后,您的解决方案就可以了。但主要问题是如何获取位置列。
  • 哦!我不确定我理解你是如何计算位置的。职位是等级吗?销售点?
  • 没有一个位置就像你买 n 数量你去 +n 位置(对于那个团队为那个帐户的那个股票)如果你卖 n 数量,你去 -n 位置。买 2,然后卖 1,使你的位置 1。阅读 2nd df 中的评论可能会有所帮助
猜你喜欢
  • 2019-04-12
  • 2020-10-12
  • 2019-02-24
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 2019-04-12
相关资源
最近更新 更多