使用 pandas 中的时间分辨率查找列的平均值

Find average of a column using a time resolution in pandas

我正在尝试找到一种方法来计算增量时间累计和小于特定分辨率的行的列 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. 是否可以找到列 var 1 的行并将其替换为具有平均行的 index_keep 列表中的索引?
  2. 如何设置 for 循环在找到平均值后从头开始重新开始?

我已经尝试过这种向量化方法来获取 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

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

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