繁体   English   中英

使用 Pandas,如何根据给定条件下前几行的平均值将公式应用于多行?

[英]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标志为TrueData列来实现。 该平均值将存储在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,但实际上,这些值遍布整个地图并且不容易固定。 这只是一部卡通片。 这就是为什么我需要弄清楚如何应用数学,而不仅仅是摆弄数值。

那么现在:在我的数据,后台校准不会经常发生,但总是有相同数量的条目。 我需要

  1. CalibratingTrue时从Data列中找出正确的背景,
  2. 通过首先加回不正确的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.whereActualCalConstant列计数结合使用前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.cumsum0组创建唯一组:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM