python - 使用 Pandas,如何根据给定条件的前几行的平均值将公式应用于多行?
问题描述
好吧,复杂的标题。这是我要完成的工作:
假设我有一个 n 行的数据框,其中填充了来自一台实验室设备的数据。每隔一段时间,那台设备就会自我校准,并且列中会出现几True
行Calibrating
。校准时,CalConstant
列为零,未校准的数据保存到Data
列中。一旦它完成了这个过程,它就会对 进行平均Data
并将其存储在CalConstant
列中。在正常运行期间,Data
是系统测量值减去电流的结果CalConstant
。
原来这台设备计算的自校准常数有误,我需要手动重新做。这将通过在每次仪器自校准时对标志Data
所在的列进行平均来实现。该平均值将存储在列中,并将在每一行中保留,直到下一次自校准。然后它将取下一个自校准数据的平均值,并将其应用于下一个分析数据块,依此类推。Calibrating
True
CalConstant
如果我们要画一幅漫画,它会是这样的。假设我们有这个数据框:
Index Data Calibrating CalConstant
0 49.91 True 0.0
1 49.06 True 0.0
2 50.38 True 0.0
3 47.82 True 0.0
4 51.58 True 0.0
5 11.63 False 39.75
6 10.42 False 39.75
7 11.67 False 39.75
8 10.12 False 39.75
9 10.67 False 39.75
10 10.89 False 39.75
11 11.23 False 39.75
12 10.43 False 39.75
13 11.26 False 39.75
14 10.64 False 39.75
15 50.23 True 0.0
16 52.63 True 0.0
17 49.32 True 0.0
18 50.99 True 0.0
19 51.34 True 0.0
20 12.37 False 40.90
21 11.47 False 40.90
22 10.81 False 40.90
23 13.27 False 40.90
24 12.73 False 40.90
25 11.31 False 40.90
26 12.85 False 40.90
27 10.42 False 40.90
28 11.25 False 40.90
29 10.54 False 40.90
此处,第 0-4 行是仪器校准时。但是,它错误地计算了背景!它应该是 49.75,因此对于第 5-14 行,数据报告不正确。第 15-19 行的校准问题重复出现,第 20-29 行的数据不正确。在这种情况下,CalConstant
10 是关闭的,但实际上,这些值遍布整个地图并且不容易修复。这只是一部卡通片。这就是为什么我需要弄清楚如何应用数学,而不仅仅是摆弄值。
那么现在:在我的数据中,后台校准不会定期发生,但它总是具有相同数量的条目。我需要
- 从列中找出正确的背景
Data
whileCalibrating
isTrue
, Data
先把不正确的加回CalConstant
,再减去正确的,找出正确的。
第 2 步很简单,因为我可以添加一个新列,CorrectCalConstant
而且它是一个易于应用的公式。困难的部分是弄清楚如何遍历数据帧并找到校准块的开始位置,抓取该块,并仅将其应用到下一个校准块。
我的实际输出可能如下所示:
Index Data Calibrating CalConstant ActualCalConstant ActualData
0 49.91 True 0.0 0.0 49.91
1 49.06 True 0.0 0.0 49.06
2 50.38 True 0.0 0.0 50.38
3 47.82 True 0.0 0.0 47.82
4 51.58 True 0.0 0.0 51.58
5 11.63 False 39.75 49.75 1.63
6 10.42 False 39.75 49.75 0.42
7 11.67 False 39.75 49.75 1.67
8 10.12 False 39.75 49.75 0.12
9 10.67 False 39.75 49.75 0.67
10 10.89 False 39.75 49.75 0.89
11 11.23 False 39.75 49.75 1.23
12 10.43 False 39.75 49.75 0.43
13 11.26 False 39.75 49.75 1.26
14 10.64 False 39.75 49.75 0.64
15 50.23 True 0.0 0.0 50.23
16 52.63 True 0.0 0.0 52.63
17 49.32 True 0.0 0.0 49.32
18 50.99 True 0.0 0.0 50.99
19 51.34 True 0.0 0.0 51.34
20 12.37 False 40.90 50.90 2.37
21 11.47 False 40.90 50.90 1.47
22 10.81 False 40.90 50.90 0.81
23 13.27 False 40.90 50.90 3.27
24 12.73 False 40.90 50.90 2.73
25 11.31 False 40.90 50.90 1.31
26 12.85 False 40.90 50.90 2.85
27 10.42 False 40.90 50.90 0.42
28 11.25 False 40.90 50.90 1.25
29 10.54 False 40.90 50.90 0.54
解决方案
numpy.where
与先前组的ActualCalConstant
列计数一起使用,因此这里是 的平均值:mean
0
49.750
rows 0-4
m = df['Calibrating']
s = df.groupby((~m).cumsum()[m])['Data'].transform('mean').ffill()
df['ActualCalConstant'] = np.where(df['Calibrating'], 0, s)
s1 = df['ActualCalConstant'].sub(df['CalConstant'])
df['ActualData'] = np.where(df['Calibrating'], df['Data'], df['Data'].sub(s1))
print (df)
Index Data Calibrating CalConstant ActualCalConstant ActualData
0 0 49.91 True 0.00 0.000 49.910
1 1 49.06 True 0.00 0.000 49.060
2 2 50.38 True 0.00 0.000 50.380
3 3 47.82 True 0.00 0.000 47.820
4 4 51.58 True 0.00 0.000 51.580
5 5 11.63 False 39.75 49.750 1.630
6 6 10.42 False 39.75 49.750 0.420
7 7 11.67 False 39.75 49.750 1.670
8 8 10.12 False 39.75 49.750 0.120
9 9 10.67 False 39.75 49.750 0.670
10 10 10.89 False 39.75 49.750 0.890
11 11 11.23 False 39.75 49.750 1.230
12 12 10.43 False 39.75 49.750 0.430
13 13 11.26 False 39.75 49.750 1.260
14 14 10.64 False 39.75 49.750 0.640
15 15 50.23 True 0.00 0.000 50.230
16 16 52.63 True 0.00 0.000 52.630
17 17 49.32 True 0.00 0.000 49.320
18 18 50.99 True 0.00 0.000 50.990
19 19 51.34 True 0.00 0.000 51.340
20 20 12.37 False 40.90 50.902 2.368
21 21 11.47 False 40.90 50.902 1.468
22 22 10.81 False 40.90 50.902 0.808
23 23 13.27 False 40.90 50.902 3.268
24 24 12.73 False 40.90 50.902 2.728
25 25 11.31 False 40.90 50.902 1.308
26 26 12.85 False 40.90 50.902 2.848
27 27 10.42 False 40.90 50.902 0.418
28 28 11.25 False 40.90 50.902 1.248
29 29 10.54 False 40.90 50.902 0.538
说明:
0
首先是按累计总和仅为组创建唯一组Series.cumsum
:
m = df['Calibrating']
print ((~m).cumsum()[m])
0 0
1 0
2 0
3 0
4 0
15 10
16 10
17 10
18 10
19 10
Name: Calibrating, dtype: int32
然后用于GroupBy.transform
每组重复mean
:
print (df.groupby((~m).cumsum()[m])['Data'].transform('mean'))
0 49.750
1 49.750
2 49.750
3 49.750
4 49.750
5 NaN
6 NaN
7 NaN
8 NaN
9 NaN
10 NaN
11 NaN
12 NaN
13 NaN
14 NaN
15 50.902
16 50.902
17 50.902
18 50.902
19 50.902
20 NaN
21 NaN
22 NaN
23 NaN
24 NaN
25 NaN
26 NaN
27 NaN
28 NaN
29 NaN
Name: Data, dtype: float64
最后添加前向填充缺失值:
print (df.groupby((~m).cumsum()[m])['Data'].transform('mean').ffill())
0 49.750
1 49.750
2 49.750
3 49.750
4 49.750
5 49.750
6 49.750
7 49.750
8 49.750
9 49.750
10 49.750
11 49.750
12 49.750
13 49.750
14 49.750
15 50.902
16 50.902
17 50.902
18 50.902
19 50.902
20 50.902
21 50.902
22 50.902
23 50.902
24 50.902
25 50.902
26 50.902
27 50.902
28 50.902
29 50.902
Name: Data, dtype: float64
推荐阅读
- c# - 如何成功存储和加载游戏角色的数据?
- javascript - React 被认为是一个库,Angular 被认为是一个框架。为什么这样?
- asp.net-core - Servicestack 未经授权
- python - 如何暂停 OpenCV 视频视频流以获得积分?
- php - 如何在laravel 6中使用`@`作为函数
- powershell - 您可以在 PowerShell 属性中指定单位吗?
- git - Git - 如何将主分支移动到其他分支和头部
- sql-server - System.Data.SqlClient.SqlException 过程没有提供参数和参数。我应该如何解决这个错误?
- algorithm - 前 k 个最大元素插入 O(logn) 和 O(k) 的数据结构
- asynchronous - 如何在 Kotlin 中同步检查和设置变量?