![](/img/trans.png)
[英]How do I remove rows of a Pandas DataFrame based on a certain condition?
[英]Using Pandas, how to I apply a formula to several rows, based on the average of previous rows given a certain condition?
好吧,复杂的标题。 这是我想要完成的:
假设我有一个 n 行的数据框,其中填充了来自一台实验室设备的数据。 每隔一段时间,那台设备就会进行自我校准,并且在Calibrating
列中会有几行带有True
。 校准时, CalConstant
零,未校准的数据保存到Data
列中。 完成该过程后,它CalConstant
Data
CalConstant
平均值并将其存储在CalConstant
列中。 在正常操作期间, Data
是系统测量值减去当前CalConstant
。
原来这台设备自校准常数计算错误,需要手工重新做。 这将通过在每次仪器自校准时平均Calibrating
标志为True
的Data
列来实现。 该平均值将存储在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,但实际上,这些值遍布整个地图并且不容易固定。 这只是一部卡通片。 这就是为什么我需要弄清楚如何应用数学,而不仅仅是摆弄数值。
那么现在:在我的数据,后台校准不会经常发生,但它总是有相同数量的条目。 我需要
Calibrating
为True
时从Data
列中找出正确的背景,CalConstant
,然后减去正确的,找出正确的Data
。 第 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
列计数结合使用前0
组的mean
,因此这里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
说明:
首先通过累积和Series.cumsum
为0
组创建唯一组:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.