【问题标题】:Counting the number of consecutive occurences of numbers in dataframe with multi index使用多索引计算数据框中数字连续出现的次数
【发布时间】:2020-10-02 04:32:10
【问题描述】:

我有一个具有多索引(股票和日期时间)的数据框,其中包含一个包含 1 和 0 的虚拟列,我想计算每只股票和每一天的每一行中 1 或 0 的次数发生在“虚拟”列中,每次从 1 开始,向上计数为 1,向下计数为 0 我在下面有一个示例,其中“计数器”列代表我想要创建的内容:

import pandas as pd
df = pd.DataFrame(  {
'stock': ['AAPL', 'AAPL', 'AAPL','AAPL', 'AAPL','AAPL', 'AAPL', 'MSFT', 'MSFT'], 
'datetime': ['2015-01-02 20:57', '2015-01-02 20:58', '2015-01-02 20:59', '2015-01-02 21:00','2015-01-03 20:57', '2015-01-03 20:58', '2015-01-03 20:59','2015-01-02 20:57', '2015-01-02 20:58'],
'Dummy': [0, 0, 1, 1, 1,1, 0, 1, 1],
'Counter': [-1, -2, 1, 2, 1, 2, 1, 1,2]})
df['datetime'] = pd.to_datetime(df['datetime'])
df.set_index(['stock', 'datetime'], inplace =True)

这里回答了这个问题的一个更简单的版本(但是这忽略了代码和日期)

Counting the number of consecutive occurences of numbers in dataframe

【问题讨论】:

    标签: pandas dataframe pandas-groupby


    【解决方案1】:

    只需稍微修改您之前的解决方案

    m = df.Dummy.diff().ne(0).cumsum()
    counters = df.groupby([df.index.get_level_values(0), 
                           df.index.get_level_values(1).date, 
                           m]).cumcount()+1
    df['Counter'] = np.where(df['Dummy']==0, -1, 1) * counters
    
    Out[95]:
                               Dummy  Counter
    stock datetime
    AAPL  2015-01-02 20:57:00      0       -1
          2015-01-02 20:58:00      0       -2
          2015-01-02 20:59:00      1        1
          2015-01-02 21:00:00      1        2
          2015-01-03 20:57:00      1        1
          2015-01-03 20:58:00      1        2
          2015-01-03 20:59:00      0       -1
    MSFT  2015-01-02 20:57:00      1        1
          2015-01-02 20:58:00      1        2
    

    【讨论】:

      【解决方案2】:

      基于您链接的答案:

      1. 首先,创建date 列,您需要将其包含在创建blocks 的逻辑中
      2. 然后,只需稍微修改blocks 系列的逻辑,包括| (df.day.diff().ne(0))
      3. 最后,将stock 包含在.groupby 中。您可以直接在 groupby 中引用多索引列:

      import pandas as pd
      df = pd.DataFrame(  {
      'stock': ['AAPL', 'AAPL', 'AAPL','AAPL', 'AAPL','AAPL', 'AAPL', 'MSFT', 'MSFT'], 
      'datetime': ['2015-01-02 20:57', '2015-01-02 20:58', '2015-01-02 20:59', '2015-01-02 21:00','2015-01-03 20:57', '2015-01-03 20:58', '2015-01-03 20:59','2015-01-02 20:57', '2015-01-02 20:58'],
      'Dummy': [0, 0, 1, 1, 1,1, 0, 1, 1],
      'Counter': [-1, -2, 1, 2, 1, -1, 1, 1,2]})
      df['datetime'] = pd.to_datetime(df['datetime'])
      df['date'] = df['datetime'].dt.date
      df.set_index(['stock', 'datetime'], inplace =True)
      blocks = (df.Dummy.diff().ne(0) | (df['date'].ne(df['date'].shift()))).cumsum()
      counters = df.groupby(['stock', blocks]).cumcount() + 1
      df['Counter'] = np.where(df['Dummy']==0, -1, 1) * counters
      df
      Out[1]: 
                                 Dummy  Counter        date
      stock datetime                                       
      AAPL  2015-01-02 20:57:00      0       -1  2015-01-02
            2015-01-02 20:58:00      0       -2  2015-01-02
            2015-01-02 20:59:00      1        1  2015-01-02
            2015-01-02 21:00:00      1        2  2015-01-02
            2015-01-03 20:57:00      1        1  2015-01-03
            2015-01-03 20:58:00      1        2  2015-01-03
            2015-01-03 20:59:00      0       -1  2015-01-03
      MSFT  2015-01-02 20:57:00      1        1  2015-01-02
            2015-01-02 20:58:00      1        2  2015-01-02
      

      【讨论】:

      • 哇,从昨天开始我一直在努力解决这个问题……非常感谢!!!
      • 如果我切换到下个月,这仍然有效吗?因为你用过天
      • @NiccolaTartaglia 没问题,如果有帮助,请投票和/或接受作为答案。我很感激 - 谢谢!
      • 是的,会的。我正在尝试查看哪个答案现在最有效。但是你的两个答案都非常有帮助!!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      相关资源
      最近更新 更多