Python 在大熊猫中每10秒查找值变化的平均值和标准偏差

Python 在大熊猫中每10秒查找值变化的平均值和标准偏差,python,python-3.x,pandas,dataframe,time-series,Python,Python 3.x,Pandas,Dataframe,Time Series,我有一个来自不同传感器的数据集。目标是每隔10秒获得所有传感器的平均变化和标准偏差(即,最终输出只是时间戳和平均变化和标准变化偏差) 由于数据非常大,我最初使用Spark来处理2亿行: 原始数据如下所示: >>> df.show(10, False) +--------------+-----------------------+-----------+-------+ +integerdate | event_timestamp| sensor_id|r

我有一个来自不同传感器的数据集。目标是每隔10秒获得所有传感器的平均变化和标准偏差(即,最终输出只是时间戳和平均变化和标准变化偏差)

由于数据非常大,我最初使用Spark来处理2亿行:

原始数据如下所示:

>>> df.show(10, False)

+--------------+-----------------------+-----------+-------+
+integerdate   |        event_timestamp|  sensor_id|reading|
+--------------+-----------------------+-----------+-------+
|20180703      |2018-07-03 10:32:50.473|      Front|  54.82|
|20180703      |2018-07-03 15:59:50.616|      Front|  54.54|
|20180703      |2018-07-03 14:49:55.718|      Front|  54.64|
|20180703      |2018-07-03 09:30:00.003|       Bore|  55.60|
|20180703      |2018-07-03 15:08:16.099|       Bore|  54.66|
|20180703      |2018-07-03 09:30:54.837|      Atten|  57.08|
|20180703      |2018-07-03 09:40:24.333|      Atten|  57.08|
|20180703      |2018-07-03 10:06:01.027|      Atten|  56.69|
|20180703      |2018-07-03 10:06:28.787|      Atten|  56.70|
|20180703      |2018-07-03 10:14:32.675|      Atten|  56.64|
+--------------+-----------------------+-----------+-------+
但是,由于我只对读数的变化感兴趣,因此我使用Spark的窗口和分析功能
lag
获取每个传感器每天的第一个读数,并且仅获取传感器读数变化的时间:

>>> df1 = df\
  .withColumn('previous_reading',
              F.lag(df.reading, 1)
              .over(Window.partitionBy('integerdate', 'sensor_id')
                    .orderBy(df.event_timestamp)))\
  .filter((F.col('previous_reading').isNull()) | (F.col('reading') != F.col('previous_reading')))\
  .withColumn('reading_change', F.bround(df.reading - F.col('previous_reading'), 2))\
  .withColumn('previous_timestamp',
              F.lag(df.event_timestamp, 1)
              .over(Window
                    .partitionBy('integerdate', 'sensor_id')
                    .orderBy(df.event_timestamp)))\
  .withColumn('seconds_elapsed',
              time_elapsed_udf(F.struct(df.event_timestamp,
                                        F.col('previous_timestamp'))))

>>> df1.show(10, False)
+-----------+-----------------------+-----------+-------+----------------+--------------+-----------------------+---------------+
|integerdate|event_timestamp        |sensor_id  |reading|previous_reading|reading_change|previous_timestamp     |seconds_elapsed|
+-----------+-----------------------+-----------+-------+----------------+--------------+-----------------------+---------------+
|20180703   |2018-07-03 09:32:00.972|Back       |  0.365|null            |null          |null                   |null           |
|20180703   |2018-07-03 09:36:04.096|Anter      |  0.210|null            |null          |null                   |null           |
|20180703   |2018-07-03 11:59:17.118|Anter      |  0.250|0.21            |0.04          |2018-07-03 09:36:04.096|8593           |
|20180703   |2018-07-03 12:47:40.309|Alloc      |  47.99|null            |null          |null                   |null           |
|20180703   |2018-07-03 08:00:13.931|Bore       |  2.730|null            |null          |null                   |null           |
|20180703   |2018-07-03 09:30:00.003|Bore       |  2.750|2.73            |0.02          |2018-07-03 08:00:13.931|5386           |
|20180703   |2018-07-03 09:30:00.003|Bore       |  2.710|2.75            |-0.04         |2018-07-03 09:30:00.003|0              |
|20180703   |2018-07-03 09:30:00.697|Bore       |  2.780|2.71            |0.07          |2018-07-03 09:30:00.003|0              |
|20180703   |2018-07-03 09:32:47.269|Bore       |  2.730|2.78            |-0.05         |2018-07-03 09:30:00.697|166            |
|20180703   |2018-07-03 09:34:50.814|Bore       |  2.760|2.73            |0.03          |2018-07-03 09:32:47.269|123            |
+-----------+-----------------------+-----------+-------+----------------+--------------+-----------------------+---------------+
这将行的总数减少到大约2000万行,我可以在熊猫中轻松处理这些行

>>> pd_df = df1.toPandas()
>>> pd_df.head(10)

     integerdate  event_timestamp           sensor_id  reading    previous_reading    reading_change        previous_timestamp     seconds_elapsed
0    20180703     2018-07-03 09:32:00.972        Back    0.365                 NaN               NaN                       NaT                 NaN
1    20180703     2018-07-03 09:36:04.096       Anter    0.210                 NaN               NaN                       NaT                 NaN
2    20180703     2018-07-03 11:59:17.118       Anter    0.250                0.21              0.04   2018-07-03 09:36:04.096                8593 
3    20180703     2018-07-03 12:47:40.309       Alloc    47.99                 NaN               NaN                       NaT                 NaN  
4    20180703     2018-07-03 08:00:13.931        Bore    2.730                 NaN               NaN                       NaT                 NaN  
5    20180703     2018-07-03 09:30:00.003        Bore    2.750                2.73              0.02   2018-07-03 08:00:13.931                5386 
6    20180703     2018-07-03 09:30:00.003        Bore    2.710                2.75             -0.04   2018-07-03 09:30:00.003                   0 
7    20180703     2018-07-03 09:30:00.697        Bore    2.780                2.71              0.07   2018-07-03 09:30:00.003                   0 
8    20180703     2018-07-03 09:32:47.269        Bore    2.730                2.78             -0.05   2018-07-03 09:30:00.697                 166  
9    20180703     2018-07-03 09:34:50.814        Bore    2.760                2.73              0.03   2018-07-03 09:32:47.269                 123  
我想我只需要
event\u timestamp
sensor\u id
读取
,然后使用pandas
resample()
apply()
每10秒读取一次

我决定在Spark转换中查看
previous\u reading
previous\u timestamp
time\u passed
,以确保窗口和
lag()
正常工作

现在的挑战是,对于某些传感器,读数每隔几微秒或几秒钟就会改变一次,但对于某些传感器,读数在许多小时内不会改变

如何使用pandas
resample()
每10秒获取读数变化,然后每10秒查找传感器读数变化的平均变化和标准偏差

最终输出应采用以下格式:

event_timestamp     avg_change  std_dev
2018-07-03 09:00:10       0.05     0.02
2018-07-03 09:00:20       0.21     0.01
2018-07-03 09:00:30       0.58     0.12
2018-07-03 09:00:40       0.71     0.45
2018-07-03 09:00:50       1.14     0.78
2018-07-03 09:01:00       1.05     0.79
2018-07-03 09:01:10       5.05     0.24
2018-07-03 09:01:20       1.96     0.30
2018-07-03 09:01:30       0.51     0.01
2018-07-03 09:01:40       0.14     0.02

如果您需要我提供更多信息,请告诉我?

为了随着时间的推移获得更改,听起来您可能想使用它而不是重新采样?@brennan我已经通过这样的方式取得了一些进展:
pd_df.groupby(['sensor_id'])。重新采样('10S',label='right',on='event_timestamp')。last()['reading'].ffill().agg(['diff','pct_change']))
-我一直在努力计算总平均值和标准偏差,以备变化。