使用时间分辨率以熊猫为单位查找列的平均值

问题描述

我正在尝试找到一种方法,以计算增量时间总和小于某个分辨率的行的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.666666663并且小于定义的分辨率4小时。

但是我遇到了以下两个问题:

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

解决方法

我已经尝试过使用这种矢量化方法来获取delta的总和,并将总和除以4后将分子四舍五入,从而将其分成垃圾箱。

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,9,2,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,4,5,6,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