gnuplot统计范围可能吗?

问题描述 投票:3回答:2

我希望gnuplot只对给定范围的数据执行stats功能。

我的数据如下:

24.12.2014-08:00,34,35,44
25.12.2014-08:00,33,35,44
26.12.2014-08:00,32,32,48
27.12.2014-08:00,31,36,41
28.12.2014-08:00,34,35,44

我现在在我的剧情剧本中有这个:

...
set datafile separator ","
stats 'out.csv' u 2 prefix "A"
set xdata time
set timefmt "%d.%m.%Y-%H:%M"
set format x "%d.%m"
set xrange["24.12.2014":"28.12.2014"]
set label 1 gprintf("Max = %g", A_max) font "-Bold" at "24.12.2014",A_max-1
...

但这会计算所有日期的统计数据。但是我只想要从26.12到28.12的范围进行统计计算以及我实际图表的整个范围,因为我想在不同的时间段内分割我的图表统计数据。

statistics range gnuplot
2个回答
3
投票

统计功能不喜欢时间数据†,但您可以使用各种功能来强制它使用时间数据来操作时间。提供了两种方法。

方法1

startrange = strptime("%d.%m.%Y","26.12.2014")
endrange = strptime("%d.%m.%Y","29.12.2014")
validdate(x) = (curdate=strptime("%d.%m.%Y-%H:%M",x),curdate>=startrange&&curdate<endrange)
stats 'out.csv' u (validdate(strcol(1))?$2:1/0) prefix "A"

哪个产生

* FILE: 
  Records:           3
  Out of range:      0
  Invalid:           2
  Blank:             0
  Data Blocks:       1

* COLUMN: 
  Mean:              32.3333
  Std Dev:            1.2472
  Sample StdDev:      1.5275
  Skewness:           0.3818
  Kurtosis:           1.5000
  Avg Dev:            1.1111
  Sum:               97.0000
  Sum Sq.:         3141.0000

  Mean Err.:          0.7201
  Std Dev Err.:       0.5092
  Skewness Err.:      1.4142
  Kurtosis Err.:      2.8284

  Minimum:           31.0000 [1]
  Maximum:           34.0000 [2]
  Quartile:          31.0000 
  Median:            32.0000 
  Quartile:          34.0000

在您的样本数据上(前两行超出范围,后三行不是)。这里我们强制超出范围值无效,因此我们显示0超出范围。

这种方法的工作方式是我们使用strptime函数将日期转换为内部表示(在gnuplot 5中,这是自Unix Epoch以来的秒数,并且是自2000年1月1日以来版本中的秒数) )。因此,前两行获得2014年12月26日午夜和2014年12月29日午夜的内部值(我们调整到第二天,以便我们可以适应所有12月28日的范围)。

有效日期函数将感兴趣的日期转换为内部表示,并将其与这些标记进行比较。如果它在范围内,我们返回1(真),如果不在,则返回0(假)。请注意,第一次比较使用大于或等于测试日期是否至少等于开始日期的午夜,第二次使用严格小于检查日期是否在第二天开始之前。如果您在那些日子有特定的时间,可以进行细微的修改。

最后,我们对条件值运行stats命令。如果第一列中的日期(我们需要使用strcol函数将其加载为字符串以提供给validdate函数)在范围内,我们使用第二列值。如果日期不在范围内,我们使用无效值1/0。统计功能不会在分析中使用无效值。


另外,如果更方便的话,我们可以接受开始和结束日期作为函数中的参数:

validdate(x,start,end) = (startrange=strptime("%d.%m.%Y",start),endrange=strptime("%d.%m.%Y",end),curdate=strptime("%d.%m.%Y-%H:%M",x),curdate>=startrange&&curdate<endrange)

并调用stats函数

stats 'out.csv' u (validdate(strcol(1),"26.12.2014","29.12.2014")?$2:1/0) prefix "A"

方法2

Gnuplot有一个时间列函数,可以读取列作为时间和日期。这为我们提供了一种更简单的替代方法,但不一定非常强大。

我们可以做的

set timefmt "%d.%m.%Y-%H:%M"
stats [startrange:endrange] 'out.csv' u (timecolumn(1)):2

这将使用timefmt将第一列读取为时间。‡

这个版本与上面的版本类似,只是接受endrange值而不是拒绝(如果我们需要更复杂的日期和时间测试,上面的版本会更强大)并且丢弃的值被列为“超出范围”而不是“无效”。

我们还可以使用内联指定开始和结束范围

stats [strptime("%d.%m.%Y","26.12.2014"):strptime("%d.%m.%Y","29.12.2014")] 'out.csv' u (timecolumn(1)):2

†请注意,您不能在时间模式下使用统计功能,否则只会抱怨。因此,必须在调用set xdata time之前或在使用set xdata恢复正常模式之后运行上述内容。

‡在版本5中,timecolumn函数还可以使用另一个参数来指定要使用的格式(例如timecolumn(1,"%d.%m.%Y-%H:%M")而不是使用timefmt命令,在这种情况下不需要)

请注意,在版本5中,只记录了两个参数形式,并且文档中仅提供了一个参数形式作为先前的格式,但不是可接受的替代形式。一个参数形式现在继续工作,但是,由于它仅作为先前格式而不是可接受的替代格式列出,因此一个参数形式可能在某个更高版本中停止工作。但是,我希望这不太可能,因为gnuplot倾向于保持向后兼容性,并且一个参数形式在上述情况下很有用(因此时间格式规范只能在脚本中的一个位置发生)。


0
投票

这是我的情况:

2019-04-16 03:00 11.428
2019-04-16 06:00 13.952
2019-04-16 09:00 17.715
2019-04-16 12:00 18.901
2019-04-16 15:00 18.25 
2019-04-16 18:00 13.735
2019-04-16 21:00 12.05 
2019-04-17 00:00 11.297
2019-04-17 03:00 10.85 
2019-04-17 06:00 13.75 
2019-04-17 09:00 17.55 
2019-04-17 12:00 18.75 
2019-04-17 15:00 17.35 
2019-04-17 18:00 13.35 
2019-04-17 21:00 11.85 
2019-04-18 00:00 11.685
2019-04-18 03:00 11.379
2019-04-18 06:00 13.772
2019-04-18 09:00 17.359
2019-04-18 12:00 19.059
2019-04-18 15:00 18.101
2019-04-18 18:00 13.549
2019-04-18 21:00 12.75 
2019-04-19 00:00 12.622
2019-04-19 03:00 12.55 
2019-04-19 06:00 14.95 
2019-04-19 09:00 18.15 
2019-04-19 12:00 19.15 
2019-04-19 15:00 17.914
2019-04-19 18:00 14.114
2019-04-19 21:00 13.371
2019-04-20 00:00 12.977
2019-04-20 03:00 12.959
2019-04-20 06:00 15.331
2019-04-20 09:00 19.112
2019-04-20 12:00 20.271
2019-04-20 15:00 19.25 
2019-04-20 18:00 14.337
2019-04-20 21:00 12.216
2019-04-21 00:00 11.584
2019-04-21 03:00 10.945
2019-04-21 06:00 15.281
2019-04-21 09:00 18.093
2019-04-21 12:00 18.85 

正如马修所说,我根据日期格式使用了类似的东西:

set timefmt "%Y-%m-%d %H:%M"
stats [time(0):time(0) + 5*24*60*60] 'out.csv' u (timecolumn(1)):2

time(0)是起点,最后一点是通过将86400秒加到起点来计算的。

最后,我获得了这些统计数据:

* FILE:
  Records:           40
  Out of range:       4
  Invalid:            0
  Blank:              0
  Data Blocks:        1

* COLUMNS:
  Mean:          1.55562e+09             2.5214
  Std Dev:       124668.6809             2.0668
  Sample StdDev: 126256.8810             2.0931
  Skewness:           0.0000            -0.2736
  Kurtosis:           1.7985             2.3318
  Avg Dev:       108000.0000             1.7471
  Sum:           6.22246e+10           100.8571
  Sum Sq.:       9.67976e+19           425.1651

  Mean Err.:      19711.8492             0.3268
  Std Dev Err.:   13938.3823             0.2311
  Skewness Err.:      0.3873             0.3873
  Kurtosis Err.:      0.7746             0.7746

  Minimum:       1.55541e+09 [ 0]       -1.8791 [ 0]
  Maximum:       1.55583e+09 [39]        6.6000 [38]
  Quartile:      1.55551e+09             1.4092
  Median:        1.55562e+09             2.7873
  Quartile:      1.55572e+09             4.2904

  Linear Model:       y = 4.758e-06 x - 7399
  Slope:              4.758e-06 +- 2.576e-06
  Intercept:          -7399 +- 4008
  Correlation:        r = 0.287
  Sum xy:             1.569e+11

正如您所看到的,在统计数据中,日期以1970年1月1日的秒数表示。现在我可以知道最大/最小值和其他有用值的位置。

© www.soinside.com 2019 - 2024. All rights reserved.