问题描述
我正在尝试找到一种方法,以计算增量时间总和小于某个分辨率的行的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
小时。
但是我遇到了以下两个问题:
- 是否可以用平均行将index_keep列表中的索引替换为
var 1
列的行? - 如何将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