【问题标题】:Efficient way of row-based calculation in PandasPandas中基于行计算的有效方法
【发布时间】:2020-07-09 16:30:38
【问题描述】:

我有一个包含 2 列的数据框:类(0/1)和时间(整数)。我需要附加第三列,这将是获得 1 类行的剩余时间。

df = pd.DataFrame([
    [1,101], [1,104],
    [0,107], [0,110], [0,123],
    [1,156],
    [0,167]],
  columns=['class', 'time'])
  • 如果行的类别为 0; diff 应该是 0。
  • 如果一行是 1 类; diff 应该是它的 timetime 之间的差异,即将出现的第一个具有类 0 的行。

我可以在 Lambda 函数中计算它:

df['diff'] = df.apply(lambda x: df[ (df['time'] >= x[1]) & (df['class']==0)]['time'].iloc[0] - x[1], axis=1)

对每一行都运行表达式df[ (df['time'] >= x[1]) & (df['class']==0)] 以获得下一行的 0 类。我认为它对于大数据帧效率不高。

什么是更有效的计算方法?

【问题讨论】:

    标签: python pandas lambda pandas-apply


    【解决方案1】:

    与@Datanovice 没有太大区别。

    使用whereNaN 的时间为df['class'] == 1,然后bfill 得到第一个df['class'] == 0 值。这个系列得到了正确的“时间”来减去,不管类,所以我们可以做一个正常的减法。

    df['Diff'] = df['time'].where(df['class'].eq(0)).bfill() - df['time']
    
       class  time  Diff
    0      1   101   6.0
    1      1   104   3.0
    2      0   107   0.0
    3      0   110   0.0
    4      0   123   0.0
    5      1   156  11.0
    6      0   167   0.0
    

    第一步创建的Series是:

    df['time'].where(df['class'].eq(0)).bfill()
    #0    107.0
    #1    107.0
    #2    107.0
    #3    110.0
    #4    123.0
    #5    167.0
    #6    167.0
    #Name: time, dtype: float64
    

    【讨论】:

      【解决方案2】:

      IIUC,您可以链接布尔表达式来对其进行向量化。

      首先我们找到每组1s后面的第一个0

      t = df[df['class'].ne(df['class'].shift()) & df['class'].eq(0)]['time']
      
      print(t)
      2    107
      6    167
      Name: time, dtype: int64
      
      #then we assign a column and back fill it.
      
      df = df.assign(Diff = t).bfill()
      

      最后是求和并计算 0 Diff 值的条件。

      df['Diff'] = np.where(df['class'].eq(1),df['Diff'] - df['time'],0)
      
      
      print(df)
      
         class  time  Diff
      0      1   101   6.0
      1      1   104   3.0
      2      0   107   0.0
      3      0   110   0.0
      4      0   123   0.0
      5      1   156  11.0
      6      0   167   0.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-30
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        • 2021-04-03
        • 1970-01-01
        • 2015-01-31
        • 2021-01-29
        相关资源
        最近更新 更多