跳至主要內容

...大约 14 分钟

采样函数

等数量分桶降采样函数

本函数对输入序列进行等数量分桶采样,即根据用户给定的降采样比例和降采样方法将输入序列按固定点数等分为若干桶。在每个桶内通过给定的采样方法进行采样。

等数量分桶随机采样

函数简介

对等数量分桶后,桶内进行随机采样。

函数名可接收的输入序列类型必要的属性参数输出序列类型功能类型
EQUAL_SIZE_BUCKET_RANDOM_SAMPLEINT32 / INT64 / FLOAT / DOUBLE降采样比例 proportion,取值范围为(0, 1],默认为0.1INT32 / INT64 / FLOAT / DOUBLE返回符合采样比例的等分桶随机采样
使用示例

输入序列:root.ln.wf01.wt01.temperature0.0-99.0100条数据。

IoTDB> select temperature from root.ln.wf01.wt01;
+-----------------------------+-----------------------------+
|                         Time|root.ln.wf01.wt01.temperature|
+-----------------------------+-----------------------------+
|1970-01-01T08:00:00.000+08:00|                          0.0|
|1970-01-01T08:00:00.001+08:00|                          1.0|
|1970-01-01T08:00:00.002+08:00|                          2.0|
|1970-01-01T08:00:00.003+08:00|                          3.0|
|1970-01-01T08:00:00.004+08:00|                          4.0|
|1970-01-01T08:00:00.005+08:00|                          5.0|
|1970-01-01T08:00:00.006+08:00|                          6.0|
|1970-01-01T08:00:00.007+08:00|                          7.0|
|1970-01-01T08:00:00.008+08:00|                          8.0|
|1970-01-01T08:00:00.009+08:00|                          9.0|
|1970-01-01T08:00:00.010+08:00|                         10.0|
|1970-01-01T08:00:00.011+08:00|                         11.0|
|1970-01-01T08:00:00.012+08:00|                         12.0|
|.............................|.............................|            
|1970-01-01T08:00:00.089+08:00|                         89.0|
|1970-01-01T08:00:00.090+08:00|                         90.0|
|1970-01-01T08:00:00.091+08:00|                         91.0|
|1970-01-01T08:00:00.092+08:00|                         92.0|
|1970-01-01T08:00:00.093+08:00|                         93.0|
|1970-01-01T08:00:00.094+08:00|                         94.0|
|1970-01-01T08:00:00.095+08:00|                         95.0|
|1970-01-01T08:00:00.096+08:00|                         96.0|
|1970-01-01T08:00:00.097+08:00|                         97.0|
|1970-01-01T08:00:00.098+08:00|                         98.0|
|1970-01-01T08:00:00.099+08:00|                         99.0|
+-----------------------------+-----------------------------+

sql:

select equal_size_bucket_random_sample(temperature,'proportion'='0.1') as random_sample from root.ln.wf01.wt01;

结果:

+-----------------------------+-------------+
|                         Time|random_sample|
+-----------------------------+-------------+
|1970-01-01T08:00:00.007+08:00|          7.0|
|1970-01-01T08:00:00.014+08:00|         14.0|
|1970-01-01T08:00:00.020+08:00|         20.0|
|1970-01-01T08:00:00.035+08:00|         35.0|
|1970-01-01T08:00:00.047+08:00|         47.0|
|1970-01-01T08:00:00.059+08:00|         59.0|
|1970-01-01T08:00:00.063+08:00|         63.0|
|1970-01-01T08:00:00.079+08:00|         79.0|
|1970-01-01T08:00:00.086+08:00|         86.0|
|1970-01-01T08:00:00.096+08:00|         96.0|
+-----------------------------+-------------+
Total line number = 10
It costs 0.024s

等数量分桶聚合采样

函数简介

采用聚合采样法对输入序列进行采样,用户需要另外提供一个聚合函数参数即

  • type:聚合类型,取值为avgmaxminsumextremevariance。在缺省情况下,采用avg。其中extreme表示等分桶中,绝对值最大的值。variance表示采样等分桶中的方差。

每个桶采样输出的时间戳为这个桶第一个点的时间戳

函数名可接收的输入序列类型必要的属性参数输出序列类型功能类型
EQUAL_SIZE_BUCKET_AGG_SAMPLEINT32 / INT64 / FLOAT / DOUBLEproportion取值范围为(0, 1],默认为0.1
type:取值类型有avg, max, min, sum, extreme, variance, 默认为avg
INT32 / INT64 / FLOAT / DOUBLE返回符合采样比例的等分桶聚合采样
使用示例

输入序列:root.ln.wf01.wt01.temperature0.0-99.0100条有序数据,同等分桶随机采样的测试数据。

sql:

select equal_size_bucket_agg_sample(temperature, 'type'='avg','proportion'='0.1') as agg_avg, equal_size_bucket_agg_sample(temperature, 'type'='max','proportion'='0.1') as agg_max, equal_size_bucket_agg_sample(temperature,'type'='min','proportion'='0.1') as agg_min, equal_size_bucket_agg_sample(temperature, 'type'='sum','proportion'='0.1') as agg_sum, equal_size_bucket_agg_sample(temperature, 'type'='extreme','proportion'='0.1') as agg_extreme, equal_size_bucket_agg_sample(temperature, 'type'='variance','proportion'='0.1') as agg_variance from root.ln.wf01.wt01;

结果:

+-----------------------------+-----------------+-------+-------+-------+-----------+------------+
|                         Time|          agg_avg|agg_max|agg_min|agg_sum|agg_extreme|agg_variance|
+-----------------------------+-----------------+-------+-------+-------+-----------+------------+
|1970-01-01T08:00:00.000+08:00|              4.5|    9.0|    0.0|   45.0|        9.0|        8.25|
|1970-01-01T08:00:00.010+08:00|             14.5|   19.0|   10.0|  145.0|       19.0|        8.25|
|1970-01-01T08:00:00.020+08:00|             24.5|   29.0|   20.0|  245.0|       29.0|        8.25|
|1970-01-01T08:00:00.030+08:00|             34.5|   39.0|   30.0|  345.0|       39.0|        8.25|
|1970-01-01T08:00:00.040+08:00|             44.5|   49.0|   40.0|  445.0|       49.0|        8.25|
|1970-01-01T08:00:00.050+08:00|             54.5|   59.0|   50.0|  545.0|       59.0|        8.25|
|1970-01-01T08:00:00.060+08:00|             64.5|   69.0|   60.0|  645.0|       69.0|        8.25|
|1970-01-01T08:00:00.070+08:00|74.50000000000001|   79.0|   70.0|  745.0|       79.0|        8.25|
|1970-01-01T08:00:00.080+08:00|             84.5|   89.0|   80.0|  845.0|       89.0|        8.25|
|1970-01-01T08:00:00.090+08:00|             94.5|   99.0|   90.0|  945.0|       99.0|        8.25|
+-----------------------------+-----------------+-------+-------+-------+-----------+------------+
Total line number = 10
It costs 0.044s

等数量分桶 M4 采样

函数简介

采用M4采样法对输入序列进行采样。即对于每个桶采样首、尾、最小和最大值。

函数名可接收的输入序列类型必要的属性参数输出序列类型功能类型
EQUAL_SIZE_BUCKET_M4_SAMPLEINT32 / INT64 / FLOAT / DOUBLEproportion取值范围为(0, 1],默认为0.1INT32 / INT64 / FLOAT / DOUBLE返回符合采样比例的等分桶M4采样
使用示例

输入序列:root.ln.wf01.wt01.temperature0.0-99.0100条有序数据,同等分桶随机采样的测试数据。

sql:

select equal_size_bucket_m4_sample(temperature, 'proportion'='0.1') as M4_sample from root.ln.wf01.wt01;

结果:

+-----------------------------+---------+
|                         Time|M4_sample|
+-----------------------------+---------+
|1970-01-01T08:00:00.000+08:00|      0.0|
|1970-01-01T08:00:00.001+08:00|      1.0|
|1970-01-01T08:00:00.038+08:00|     38.0|
|1970-01-01T08:00:00.039+08:00|     39.0|
|1970-01-01T08:00:00.040+08:00|     40.0|
|1970-01-01T08:00:00.041+08:00|     41.0|
|1970-01-01T08:00:00.078+08:00|     78.0|
|1970-01-01T08:00:00.079+08:00|     79.0|
|1970-01-01T08:00:00.080+08:00|     80.0|
|1970-01-01T08:00:00.081+08:00|     81.0|
|1970-01-01T08:00:00.098+08:00|     98.0|
|1970-01-01T08:00:00.099+08:00|     99.0|
+-----------------------------+---------+
Total line number = 12
It costs 0.065s

等数量分桶离群值采样

函数简介

本函数对输入序列进行等数量分桶离群值采样,即根据用户给定的降采样比例和桶内采样个数将输入序列按固定点数等分为若干桶,在每个桶内通过给定的离群值采样方法进行采样。

函数名可接收的输入序列类型必要的属性参数输出序列类型功能类型
EQUAL_SIZE_BUCKET_OUTLIER_SAMPLEINT32 / INT64 / FLOAT / DOUBLEproportion取值范围为(0, 1],默认为0.1
type取值为avgstendiscosprenextdis,默认为avg
number取值应大于0,默认3
INT32 / INT64 / FLOAT / DOUBLE返回符合采样比例和桶内采样个数的等分桶离群值采样

参数说明

  • proportion: 采样比例
    • number: 每个桶内的采样个数,默认3
  • type: 离群值采样方法,取值为
    • avg: 取桶内数据点的平均值,并根据采样比例,找到距离均值最远的top number
    • stendis: 取桶内每一个数据点距离桶的首末数据点连成直线的垂直距离,并根据采样比例,找到距离最大的top number
    • cos: 设桶内一个数据点为b,b左边的数据点为a,b右边的数据点为c,则取ab与bc向量的夹角的余弦值,值越小,说明形成的角度越大,越可能是异常值。找到cos值最小的top number
    • prenextdis: 设桶内一个数据点为b,b左边的数据点为a,b右边的数据点为c,则取ab与bc的长度之和作为衡量标准,和越大越可能是异常值,找到最大的top number
使用示例

测试数据:root.ln.wf01.wt01.temperature0.0-99.0100条数据,其中为了加入离群值,我们使得个位数为5的值自增100。

IoTDB> select temperature from root.ln.wf01.wt01;
+-----------------------------+-----------------------------+
|                         Time|root.ln.wf01.wt01.temperature|
+-----------------------------+-----------------------------+
|1970-01-01T08:00:00.000+08:00|                          0.0|
|1970-01-01T08:00:00.001+08:00|                          1.0|
|1970-01-01T08:00:00.002+08:00|                          2.0|
|1970-01-01T08:00:00.003+08:00|                          3.0|
|1970-01-01T08:00:00.004+08:00|                          4.0|
|1970-01-01T08:00:00.005+08:00|                        105.0|
|1970-01-01T08:00:00.006+08:00|                          6.0|
|1970-01-01T08:00:00.007+08:00|                          7.0|
|1970-01-01T08:00:00.008+08:00|                          8.0|
|1970-01-01T08:00:00.009+08:00|                          9.0|
|1970-01-01T08:00:00.010+08:00|                         10.0|
|1970-01-01T08:00:00.011+08:00|                         11.0|
|1970-01-01T08:00:00.012+08:00|                         12.0|
|1970-01-01T08:00:00.013+08:00|                         13.0|
|1970-01-01T08:00:00.014+08:00|                         14.0|
|1970-01-01T08:00:00.015+08:00|                        115.0|
|1970-01-01T08:00:00.016+08:00|                         16.0|
|.............................|.............................|
|1970-01-01T08:00:00.092+08:00|                         92.0|
|1970-01-01T08:00:00.093+08:00|                         93.0|
|1970-01-01T08:00:00.094+08:00|                         94.0|
|1970-01-01T08:00:00.095+08:00|                        195.0|
|1970-01-01T08:00:00.096+08:00|                         96.0|
|1970-01-01T08:00:00.097+08:00|                         97.0|
|1970-01-01T08:00:00.098+08:00|                         98.0|
|1970-01-01T08:00:00.099+08:00|                         99.0|
+-----------------------------+-----------------------------+

sql:

select equal_size_bucket_outlier_sample(temperature, 'proportion'='0.1', 'type'='avg', 'number'='2') as outlier_avg_sample, equal_size_bucket_outlier_sample(temperature, 'proportion'='0.1', 'type'='stendis', 'number'='2') as outlier_stendis_sample, equal_size_bucket_outlier_sample(temperature, 'proportion'='0.1', 'type'='cos', 'number'='2') as outlier_cos_sample, equal_size_bucket_outlier_sample(temperature, 'proportion'='0.1', 'type'='prenextdis', 'number'='2') as outlier_prenextdis_sample from root.ln.wf01.wt01;

结果:

+-----------------------------+------------------+----------------------+------------------+-------------------------+
|                         Time|outlier_avg_sample|outlier_stendis_sample|outlier_cos_sample|outlier_prenextdis_sample|
+-----------------------------+------------------+----------------------+------------------+-------------------------+
|1970-01-01T08:00:00.005+08:00|             105.0|                 105.0|             105.0|                    105.0|
|1970-01-01T08:00:00.015+08:00|             115.0|                 115.0|             115.0|                    115.0|
|1970-01-01T08:00:00.025+08:00|             125.0|                 125.0|             125.0|                    125.0|
|1970-01-01T08:00:00.035+08:00|             135.0|                 135.0|             135.0|                    135.0|
|1970-01-01T08:00:00.045+08:00|             145.0|                 145.0|             145.0|                    145.0|
|1970-01-01T08:00:00.055+08:00|             155.0|                 155.0|             155.0|                    155.0|
|1970-01-01T08:00:00.065+08:00|             165.0|                 165.0|             165.0|                    165.0|
|1970-01-01T08:00:00.075+08:00|             175.0|                 175.0|             175.0|                    175.0|
|1970-01-01T08:00:00.085+08:00|             185.0|                 185.0|             185.0|                    185.0|
|1970-01-01T08:00:00.095+08:00|             195.0|                 195.0|             195.0|                    195.0|
+-----------------------------+------------------+----------------------+------------------+-------------------------+
Total line number = 10
It costs 0.041s

M4函数

函数简介

M4用于在窗口内采样第一个点(first)、最后一个点(last)、最小值点(bottom)、最大值点(top):

  • 第一个点是拥有这个窗口内最小时间戳的点;
  • 最后一个点是拥有这个窗口内最大时间戳的点;
  • 最小值点是拥有这个窗口内最小值的点(如果有多个这样的点,M4只返回其中一个);
  • 最大值点是拥有这个窗口内最大值的点(如果有多个这样的点,M4只返回其中一个)。
image
函数名可接收的输入序列类型属性参数输出序列类型功能类型
M4INT32 / INT64 / FLOAT / DOUBLE包含固定点数的窗口和滑动时间窗口使用不同的属性参数。包含固定点数的窗口使用属性windowSizeslidingStep。滑动时间窗口使用属性timeIntervalslidingStepdisplayWindowBegindisplayWindowEnd。更多细节见下文。INT32 / INT64 / FLOAT / DOUBLE返回每个窗口内的第一个点(first)、最后一个点(last)、最小值点(bottom)、最大值点(top)。在一个窗口内的聚合点输出之前,M4会将它们按照时间戳递增排序并且去重。

属性参数

(1) 包含固定点数的窗口(SlidingSizeWindowAccessStrategy)使用的属性参数:

  • windowSize: 一个窗口内的点数。Int数据类型。必需的属性参数。
  • slidingStep: 按照设定的点数来滑动窗口。Int数据类型。可选的属性参数;如果没有设置,默认取值和windowSize一样。
image

(图片来源: https://iotdb.apache.org/UserGuide/Master/Process-Data/UDF-User-Defined-Function.html#udtf-user-defined-timeseries-generating-functionopen in new window)

(2) 滑动时间窗口(SlidingTimeWindowAccessStrategy)使用的属性参数:

  • timeInterval: 一个窗口的时间长度。Long数据类型。必需的属性参数。
  • slidingStep: 按照设定的时长来滑动窗口。Long数据类型。可选的属性参数;如果没有设置,默认取值和timeInterval一样。
  • displayWindowBegin: 窗口滑动的起始时间戳位置(包含在内)。Long数据类型。可选的属性参数;如果没有设置,默认取值为Long.MIN_VALUE,意为使用输入的时间序列的第一个点的时间戳作为窗口滑动的起始时间戳位置。
  • displayWindowEnd: 结束时间限制(不包含在内;本质上和WHERE time < displayWindowEnd起的效果是一样的)。Long数据类型。可选的属性参数;如果没有设置,默认取值为Long.MAX_VALUE,意为除了输入的时间序列自身数据读取完毕之外没有增加额外的结束时间过滤条件限制。
groupBy window

(图片来源: https://iotdb.apache.org/UserGuide/Master/Query-Data/Aggregate-Query.html#downsampling-aggregate-queryopen in new window)

使用示例

输入的时间序列:

+-----------------------------+------------------+
|                         Time|root.vehicle.d1.s1|
+-----------------------------+------------------+
|1970-01-01T08:00:00.001+08:00|               5.0|
|1970-01-01T08:00:00.002+08:00|              15.0|
|1970-01-01T08:00:00.005+08:00|              10.0|
|1970-01-01T08:00:00.008+08:00|               8.0|
|1970-01-01T08:00:00.010+08:00|              30.0|
|1970-01-01T08:00:00.020+08:00|              20.0|
|1970-01-01T08:00:00.025+08:00|               8.0|
|1970-01-01T08:00:00.027+08:00|              20.0|
|1970-01-01T08:00:00.030+08:00|              40.0|
|1970-01-01T08:00:00.033+08:00|               9.0|
|1970-01-01T08:00:00.035+08:00|              10.0|
|1970-01-01T08:00:00.040+08:00|              20.0|
|1970-01-01T08:00:00.045+08:00|              30.0|
|1970-01-01T08:00:00.052+08:00|               8.0|
|1970-01-01T08:00:00.054+08:00|              18.0|
+-----------------------------+------------------+

查询语句1:

select M4(s1,'timeInterval'='25','displayWindowBegin'='0','displayWindowEnd'='100') from root.vehicle.d1

输出结果1:

+-----------------------------+-----------------------------------------------------------------------------------------------+
|                         Time|M4(root.vehicle.d1.s1, "timeInterval"="25", "displayWindowBegin"="0", "displayWindowEnd"="100")|
+-----------------------------+-----------------------------------------------------------------------------------------------+
|1970-01-01T08:00:00.001+08:00|                                                                                            5.0|
|1970-01-01T08:00:00.010+08:00|                                                                                           30.0|
|1970-01-01T08:00:00.020+08:00|                                                                                           20.0|
|1970-01-01T08:00:00.025+08:00|                                                                                            8.0|
|1970-01-01T08:00:00.030+08:00|                                                                                           40.0|
|1970-01-01T08:00:00.045+08:00|                                                                                           30.0|
|1970-01-01T08:00:00.052+08:00|                                                                                            8.0|
|1970-01-01T08:00:00.054+08:00|                                                                                           18.0|
+-----------------------------+-----------------------------------------------------------------------------------------------+
Total line number = 8

查询语句2:

select M4(s1,'windowSize'='10') from root.vehicle.d1

输出结果2:

+-----------------------------+-----------------------------------------+
|                         Time|M4(root.vehicle.d1.s1, "windowSize"="10")|
+-----------------------------+-----------------------------------------+
|1970-01-01T08:00:00.001+08:00|                                      5.0|
|1970-01-01T08:00:00.030+08:00|                                     40.0|
|1970-01-01T08:00:00.033+08:00|                                      9.0|
|1970-01-01T08:00:00.035+08:00|                                     10.0|
|1970-01-01T08:00:00.045+08:00|                                     30.0|
|1970-01-01T08:00:00.052+08:00|                                      8.0|
|1970-01-01T08:00:00.054+08:00|                                     18.0|
+-----------------------------+-----------------------------------------+
Total line number = 7

推荐的使用场景

(1) 使用场景:保留极端点的降采样

由于M4为每个窗口聚合其第一个点(first)、最后一个点(last)、最小值点(bottom)、最大值点(top),因此M4通常保留了极值点,因此比其他下采样方法(如分段聚合近似 (PAA))能更好地保留模式。如果你想对时间序列进行下采样并且希望保留极值点,你可以试试 M4。

(2) 使用场景:基于数据缩约的大规模时间序列的零误差双色折线图可视化

参考论文: "M4: A Visualization-Oriented Time Series Data Aggregation"open in new window.

假设屏幕画布的像素宽乘高是w*h,假设时间序列root.vehicle.d1.s1要可视化的时间范围是[tqs,tqe)(在这个使用场景里面,需要请你自行将tqe自适应调整使得(tqe-tqs)是w的整数倍),那么落在第i个时间跨度Ii=[tqs+(tqe-tqs)/w*(i-1),tqs+(tqe-tqs)/w*i) 内的点将会被画在第i个像素列中,i=1,2,...,w。

于是从可视化驱动的角度出发,使用查询语句:"select M4(s1,'timeInterval'='(tqe-tqs)/w','displayWindowBegin'='tqs','displayWindowEnd'='tqe') from root.vehicle.d1",来采集每个时间跨度内的第一个点(first)、最后一个点(last)、最小值点(bottom)、最大值点(top)。最终结果点数不会超过4*w个,使用这些聚合点画出来的折线图与使用原始数据画出来的图在像素级别上是完全一致的。

和其它SQL的功能比较

SQL是否支持M4聚合滑动窗口类型示例相关文档
1. 带有Group By子句的内置聚合函数不支持,缺少BOTTOM_TIMETOP_TIME,即缺少最小值点和最大值点的时间戳。Time Windowselect count(status), max_value(temperature) from root.ln.wf01.wt01 group by ([2017-11-01 00:00:00, 2017-11-07 23:00:00), 3h, 1d)https://iotdb.apache.org/UserGuide/Master/Query-Data/Aggregate-Query.html#built-in-aggregate-functionsopen in new window
https://iotdb.apache.org/UserGuide/Master/Query-Data/Aggregate-Query.html#downsampling-aggregate-queryopen in new window
2. EQUAL_SIZE_BUCKET_M4_SAMPLE (内置UDF)支持*Size Window. windowSize = 4*(int)(1/proportion)select equal_size_bucket_m4_sample(temperature, 'proportion'='0.1') as M4_sample from root.ln.wf01.wt01https://iotdb.apache.org/UserGuide/Master/Query-Data/Select-Expression.html#time-series-generating-functionsopen in new window
3. M4 (内置UDF)支持*Size Window, Time Window(1) Size Window: select M4(s1,'windowSize'='10') from root.vehicle.d1
(2) Time Window: select M4(s1,'timeInterval'='25','displayWindowBegin'='0','displayWindowEnd'='100') from root.vehicle.d1
本文档
4. 扩展带有Group By子句的内置聚合函数来支持M4聚合未实施未实施未实施未实施

进一步比较EQUAL_SIZE_BUCKET_M4_SAMPLEM4

(1) 不同的M4聚合函数定义:

在每个窗口内,EQUAL_SIZE_BUCKET_M4_SAMPLE从排除了第一个点和最后一个点之后剩余的点中提取最小值点和最大值点。

M4则是从窗口内所有点中(包括第一个点和最后一个点)提取最小值点和最大值点,这个定义与元数据中保存的max_valuemin_value的语义更加一致。

值得注意的是,在一个窗口内的聚合点输出之前,EQUAL_SIZE_BUCKET_M4_SAMPLEM4都会将它们按照时间戳递增排序并且去重。

(2) 不同的滑动窗口:

EQUAL_SIZE_BUCKET_M4_SAMPLE使用SlidingSizeWindowAccessStrategy,并且通过采样比例(proportion)来间接控制窗口点数(windowSize),转换公式是windowSize = 4*(int)(1/proportion)

M4支持两种滑动窗口:SlidingSizeWindowAccessStrategy和SlidingTimeWindowAccessStrategy,并且M4通过相应的参数直接控制窗口的点数或者时长。

Copyright © 2024 The Apache Software Foundation.
Apache IoTDB, IoTDB, Apache, the Apache feather logo, and the Apache IoTDB project logo are either registered trademarks or trademarks of The Apache Software Foundation in all countries

Have a question? Connect with us on QQ, WeChat, or Slack. Join the community now.