【问题标题】:Find average of a column using a time resolution in pandas在熊猫中使用时间分辨率查找列的平均值
【发布时间】:2020-10-03 04:48:33
【问题描述】:

我正在尝试找到一种方法来计算增量时间累积总和小于某个分辨率的行的列 var 1 的平均值。 delta 是以小时为单位的时间。以下是数据示例:

|id    |label|delta      |var 1|
|------|-----|-----------|-----|
|23_100|0    |2.533333333|5    |
|23_100|0    |1.133333333|     |
|23_100|0    |0.733333333|3    |
|23_100|0    |0.7        |7    |
|23_100|0    |1.033333333|     |
|23_100|0    |0.366666667|9    |
|23_100|0    |0.916666667|     |
|23_100|0    |0.383333333|2    |
|23_100|0    |0.066666667|     |
|23_100|0    |2.883333333|1    |
|23_100|0    |0.15       |5    |
|23_100|0    |0.233333333|3    |
|23_100|0    |1.35       |     |
|23_100|0    |0.75       |8    |
|23_100|0    |2.133333333|7    |

为了实现这一点,我有以下想法:

cumsum_time = 0
index_keep = []
resolution = 4  # 4 hours
for index, row in df.iterrows():
    cumsum_time = cumsum_time + row['delta']
    index_keep.append(index)
    if cumsum_time <= resolution:
        print(cumsum_time)
        print(index_keep)
        # Find the average of the column var 1 for the rows in the index_keep list

第一个 for 循环以 index_keep = [0, 1] 停止,这是正确的。由于2.533333333 + 1.13333333 = 3.666666663and 小于4 小时的定义分辨率。

但我陷入了以下两个问题:

  1. 是否可以使用 index_keep 列表中的索引找到并替换列 var 1 的行以及平均行?
  2. 如何将 for 循环设置为在找到平均值后从头开始?

【问题讨论】:

    标签: python pandas time-series moving-average


    【解决方案1】:

    为满足条件的分组创建一个标志。然后我们计算每个组的平均值并将它们添加到原始数据框中。

    import pandas as pd
    import numpy as np
    import io
    
    data = '''
    id    label delta      "var 1"
    23_100 0    2.533333333 5    
    23_100 0    1.133333333     
    23_100 0    0.733333333 3    
    23_100 0    0.7        7    
    23_100 0    1.033333333     
    23_100 0    0.366666667 9    
    23_100 0    0.916666667     
    23_100 0    0.383333333 2    
    23_100 0    0.066666667     
    23_100 0    2.883333333 1    
    23_100 0    0.15        5    
    23_100 0    0.233333333 3    
    23_100 0    1.35            
    23_100 0    0.75        8    
    23_100 0    2.133333333 7    
    '''
    
    df = pd.read_csv(io.StringIO(data), delim_whitespace=True)
    
    i = 0
    cumsum_time = 0
    index_keep = []
    resolution = 4  # 4 hours
    for index, row in df.iterrows():
        cumsum_time += row['delta']
        if cumsum_time <= resolution:
            df.loc[index,'flg'] = i +1
        else:
            cumsum_time = 0
            i += 1
    df['flg'].fillna(method='bfill', inplace=True)
    df['flg'].fillna(df['flg'].max()+1, inplace=True)
    df['mean'] = df.groupby('flg')['var 1'].transform('mean')
    df
        id  label   delta   var 1   flg mean
    0   23_100  0   2.533333    5.0 1.0 5.00
    1   23_100  0   1.133333    NaN 1.0 5.00
    2   23_100  0   0.733333    3.0 2.0 5.25
    3   23_100  0   0.700000    7.0 2.0 5.25
    4   23_100  0   1.033333    NaN 2.0 5.25
    5   23_100  0   0.366667    9.0 2.0 5.25
    6   23_100  0   0.916667    NaN 2.0 5.25
    7   23_100  0   0.383333    2.0 2.0 5.25
    8   23_100  0   0.066667    NaN 2.0 5.25
    9   23_100  0   2.883333    1.0 3.0 4.25
    10  23_100  0   0.150000    5.0 3.0 4.25
    11  23_100  0   0.233333    3.0 3.0 4.25
    12  23_100  0   1.350000    NaN 3.0 4.25
    13  23_100  0   0.750000    8.0 3.0 4.25
    14  23_100  0   2.133333    7.0 4.0 7.00
    

    【讨论】:

    • 感谢您的回答。如何用 average 方法中的索引行替换平均行?
    • 如果要更新原来的'var 1',只需将df['mean']改为df['var 1']即可。
    【解决方案2】:

    我已经尝试过这种矢量化方法来获取 delta 的 cumsum 并通过在将 cumsum 除以 4 后将分子四舍五入将其分成 bin。

    df = pd.DataFrame({'delta':[2.533333333, 1.133333333, 0.733333333, 0.7, 
                   1.033333333, 0.366666667, 0.916666667, 0.383333333,
                  0.066666667, 2.883333333],
                  'var_1':[5, np.nan, 3, 7, np.nan, 9, np.nan, 2, np.nan, 1]})
    
    df['delta_cumsum'] = df.delta.cumsum()
    df['delta_bins'] = np.ceil(df.delta_cumsum / 4)
    df['index_keep'] = df.index
    
    print(df)
    
        delta      var_1    delta_cumsum    delta_bins  index_keep
    0   2.533333    5.0     2.533333        1.0          0
    1   1.133333    NaN     3.666667        1.0          1
    2   0.733333    3.0     4.400000        2.0          2
    3   0.700000    7.0     5.100000        2.0          3
    4   1.033333    NaN     6.133333        2.0          4
    5   0.366667    9.0     6.500000        2.0          5
    6   0.916667    NaN     7.416667        2.0          6
    7   0.383333    2.0     7.800000        2.0          7
    8   0.066667    NaN     7.866667        2.0          8
    9   2.883333    1.0     10.750000       3.0          9
    
    
    df.groupby('delta_bins').agg({'index_keep':list, 'var_1':'mean'})
    
               index_keep               var_1
    delta_bins      
    1.0        [0, 1]                   5.00
    2.0        [2, 3, 4, 5, 6, 7, 8]    5.25
    3.0        [9]                      1.00
    

    【讨论】:

      猜你喜欢
      • 2015-01-21
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2020-09-24
      • 2016-03-03
      • 2015-09-11
      • 1970-01-01
      相关资源
      最近更新 更多