计算每小时的平均值以消除峰值和低点

时间:2016-08-17 20:56:22

标签: python-3.x pandas logging

我有一个如下所示的日志文件:(日期/时间 - 温度 - 湿度)

2016-05-17 21:17    18.5    39.2
2016-05-17 21:18    18.5    39.2
2016-05-17 21:19    18.6    39.3
2016-05-17 21:20    18.5    39.3
2016-05-17 21:21    18.5    39.3
2016-05-17 21:22    18.4    39.2
2016-05-17 21:23    18.5    39.3
2016-05-17 21:24    18.4    39.3
2016-05-17 21:25    18.5    39.4
2016-05-17 21:26    18.4    39.3
2016-05-17 21:27    18.3    39.4
2016-05-17 21:28    18.3    39.4
2016-05-17 21:29    18.4    39.5
2016-05-17 21:30    4.4 39.5
2016-05-17 21:31    18.4    39.5
2016-05-17 21:32    18.3    39.5
2016-05-17 21:33    18.3    39.5
2016-05-17 21:34    18.3    39.5
2016-05-17 21:35    18.3    39.5
2016-05-17 21:36    18.3    39.6
2016-05-17 21:37    18.3    39.6
2016-05-17 21:38    18.3    39.6
2016-05-17 21:39    18.3    39.6
2016-05-17 21:40    18.3    15.6
2016-05-17 21:41    18.2    39.5

我想消除显示异常尖峰和低频的行(测量错误)。

我的方法:

计算每小时的平均温度和湿度值,然后将该小时内的每个值与平均值进行比较。如果温度或湿度与平均值相差很远,那么整排都会被踢掉。

我可以用熊猫来做这件事吗?

到目前为止,我只设置了df。

df = pd.read_csv('Logger.csv',delimiter="\t", names =['Timestamp', 'Temperature', 
'Humidity'],header=None, parse_dates=["Timestamp"], index_col="Timestamp").resample('H')
.mean().dropna()

所以我得到每小时的平均值。

问题:我可以使用pandas比较每行的每个Temp和Hum值,并消除5°C或计算出的平均值5%的值吗?

编辑:所以我在日志文件中发布了更多内容,并在21:30和21:40“添加了”2个测量错误。这些测量误差每天发生一次或两次,这些是我想要消除的行。 数据通过Raspberry Pi和DHT22传感器24/7记录(传感器有一个导致错误测量的错误)

我不太清楚我理解你的问题。我想将好的数据写入新的.csv文件(好的data.csv),将坏的数据写入另一个新的.csv文件(baddata.csv) 对不起如果我的问题出错了。

我想计算日志文件中每60分钟的平均值,然后逐行比较相应小时的平均值。 对于顶级熊猫的日志示例给我:

                     Temperature  Humidity
Timestamp                                 
2016-05-17 21:00:00        17.82    38.464

所以我清理日志的想法是将2016-05-17日期和21:00-22:00的每个温度值与17.82°C进行比较。 我想和湿度一样。

日历文件中每天每小时的整个过程。

如果我没有说得那么清楚,我很抱歉。

@凯尔:我以为我可以用这种差异来玩一下。也许5°C有点缩小,但我认为10°C可以完成这项工作,可能还有10%的潮湿。 日志是在一个封闭的车库中拍摄的,我认为帽子不应该起作用。测量误差我想摆脱常规测量值的相当大的豁免。 @MaxU: 所以我尝试了代码,但它没有用,我用它来理解语法,这就是我最终的结果:

logfile =pd.read_csv('/Users/Peter/Desktop/LearnPython/DataLoggerTEST.csv',header=None, delimiter="\t",names['Timestamp','Temperature','Humidity'],index_col=0,parse_dates='Timestamp')

df=[logfile[['Temperature','Humidity']].groupby(pd.TimeGrouper('1H')).transform('mean').abs().query('Temperature > 5 and Humidity > 5').index]

我得到的是每小时的mean值 输出是(提取):

Date/Time                                 
2016-05-17 21:17:00        17.82    38.464
2016-05-17 21:18:00        17.82    38.464
2016-05-17 21:19:00        17.82    38.464
2016-05-17 21:20:00        17.82    38.464
2016-05-17 21:21:00        17.82    38.464
2016-05-17 21:22:00        17.82    38.464
2016-05-17 21:23:00        17.82    38.464
2016-05-17 21:24:00        17.82    38.464
2016-05-17 21:25:00        17.82    38.464
2016-05-17 21:26:00        17.82    38.464
2016-05-17 21:27:00        17.82    38.464

似乎我应该得到mean值与实际值之间的绝对差异的部分不起作用

1 个答案:

答案 0 :(得分:1)

我不确定这是最漂亮/最优雅的解决方案,但它应该可以胜任:

代码:

df.ix[(df[['Temp','Hum']]
       -
       df.groupby(pd.TimeGrouper('1H', key='Timestamp')).transform('mean')
      ).abs()
       .query('Temp < 5 and Hum < 5')
       .index
     ]

<强>解决方案:

In [115]: df.ix[(df[['Temp','Hum']]
   .....:        -
   .....:        df.groupby(pd.TimeGrouper('1H', key='Timestamp')).transform('mean')
   .....:       ).abs()
   .....:        .query('Temp < 5 and Hum < 5')
   .....:        .index
   .....:      ]
Out[115]:
             Timestamp  Temp   Hum
0  2016-05-17 20:17:00  18.5  39.2
1  2016-05-17 20:18:00  18.5  39.2
2  2016-05-17 20:19:00  18.6  39.3
3  2016-05-17 20:20:00  18.5  39.3
4  2016-05-17 21:21:00  18.5  39.3
5  2016-05-17 21:22:00  18.4  39.2
6  2016-05-17 21:23:00  18.5  39.3
7  2016-05-17 21:24:00  18.4  39.3
8  2016-05-17 21:25:00  18.5  39.4
9  2016-05-17 21:26:00  18.4  39.3
10 2016-05-17 21:27:00  18.3  39.4
11 2016-05-17 21:28:00  18.3  39.4
12 2016-05-17 21:29:00  18.4  39.5
14 2016-05-17 21:31:00  18.4  39.5
15 2016-05-17 21:32:00  18.3  39.5
16 2016-05-17 21:33:00  18.3  39.5
17 2016-05-17 21:34:00  18.3  39.5
18 2016-05-17 21:35:00  18.3  39.5
19 2016-05-17 21:36:00  18.3  39.6
20 2016-05-17 21:37:00  18.3  39.6
21 2016-05-17 21:38:00  18.3  39.6
22 2016-05-17 21:39:00  18.3  39.6
24 2016-05-17 21:41:00  18.2  39.5

说明:以下表达式将给出实际值与平均值(对应小时)之间的绝对差值:

In [119]: (df[['Temp','Hum']]
   .....:  -
   .....:  df.groupby(pd.TimeGrouper('1H', key='Timestamp')).transform('mean')
   .....: ).abs()
Out[119]:
         Temp        Hum
0    0.025000   0.050000
1    0.025000   0.050000
2    0.075000   0.050000
3    0.025000   0.050000
4    0.814286   0.985714
5    0.714286   0.885714
6    0.814286   0.985714
7    0.714286   0.985714
8    0.814286   1.085714
9    0.714286   0.985714
10   0.614286   1.085714
11   0.614286   1.085714
12   0.714286   1.185714
13  13.285714   1.185714
14   0.714286   1.185714
15   0.614286   1.185714
16   0.614286   1.185714
17   0.614286   1.185714
18   0.614286   1.185714
19   0.614286   1.285714
20   0.614286   1.285714
21   0.614286   1.285714
22   0.614286   1.285714
23   0.614286  22.714286
24   0.514286   1.185714

数据:

In [116]: df
Out[116]:
             Timestamp  Temp   Hum
0  2016-05-17 20:17:00  18.5  39.2
1  2016-05-17 20:18:00  18.5  39.2
2  2016-05-17 20:19:00  18.6  39.3
3  2016-05-17 20:20:00  18.5  39.3
4  2016-05-17 21:21:00  18.5  39.3
5  2016-05-17 21:22:00  18.4  39.2
6  2016-05-17 21:23:00  18.5  39.3
7  2016-05-17 21:24:00  18.4  39.3
8  2016-05-17 21:25:00  18.5  39.4
9  2016-05-17 21:26:00  18.4  39.3
10 2016-05-17 21:27:00  18.3  39.4
11 2016-05-17 21:28:00  18.3  39.4
12 2016-05-17 21:29:00  18.4  39.5
13 2016-05-17 21:30:00   4.4  39.5
14 2016-05-17 21:31:00  18.4  39.5
15 2016-05-17 21:32:00  18.3  39.5
16 2016-05-17 21:33:00  18.3  39.5
17 2016-05-17 21:34:00  18.3  39.5
18 2016-05-17 21:35:00  18.3  39.5
19 2016-05-17 21:36:00  18.3  39.6
20 2016-05-17 21:37:00  18.3  39.6
21 2016-05-17 21:38:00  18.3  39.6
22 2016-05-17 21:39:00  18.3  39.6
23 2016-05-17 21:40:00  18.3  15.6
24 2016-05-17 21:41:00  18.2  39.5

PS我有意编辑前3行,所以我们在分组时会有至少两小时的数据:

In [117]: df.groupby(pd.TimeGrouper('1H', key='Timestamp')).mean()
Out[117]:
                          Temp        Hum
Timestamp
2016-05-17 20:00:00  18.525000  39.250000
2016-05-17 21:00:00  17.685714  38.314286