【问题标题】:gnuplot stats range possible?gnuplot 统计范围可能吗?
【发布时间】:2019-04-16 16:17:08
【问题描述】:

我希望 gnuplot 仅针对给定的数据范围执行统计功能。

我的数据如下:

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 的范围用于统计计算以及我的实际图表的整个范围,因为我想将我的图表拆分为不同的时间段统计。

【问题讨论】:

  • 您可以尝试使用set table 'temp_data.dat' 和plot 'data.csv u 2 将过滤后的数据保存在表格中,然后执行stat 'temp_data.dat'
  • 我用这个数据试过这个:见编辑
  • 我尝试了您的建议,它创建了文件 temp_data.dat,但它包含所有值,但带有一个新字段,指示“o”和“i”进出记录。但是当我统计这个文件时,超出范围为零并且仍然可以识别。

标签: statistics range gnuplot


【解决方案1】:

stats 函数不喜欢时间数据†,但您可以使用各种函数来强制它使用时间数据来操作时间。提供了两种执行此操作的方法。

方法一

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 纪元以来的秒数,是自 2000 年 1 月 1 日以来的秒数在之前的版本中)。因此,前两行获得了 2014 年 12 月 26 日午夜和 2014 年 12 月 29 日午夜的内部值(我们调整到第二天,以便我们可以将 12 月 28 日的所有时间都放在范围内)。

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

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


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

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 'out.csv' u (validdate(strcol(1),"26.12.2014","29.12.2014")?$2:1/0) prefix "A"

方法二

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

我们可以的

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 倾向于保持向后兼容性,并且在上述情况下,一种参数形式很有用(因此时间格式规范只能出现在脚本中的一个位置)。

【讨论】:

  • 但是如果我们从 26 日 00:00 到 28 日 00:00 计算,为什么你的最大值是“34”?不应该是“44”吗?还是您使用了不同的数据?
  • @PaulG。我使用了您在问题中使用的原始问题和第 2 列的数据。该列具有值34 33 32 31 34。 44 唯一出现在第 4 列中。
  • 如果我对上面的数据运行你的 4 行代码,我只会得到:“plot”,第 4 行:在文件中找不到有效的数据点。我需要别的东西来计算统计数据吗?
  • @PaulG。确保首先运行“设置数据文件分隔符逗号”。
  • 还是同样的错误:我运行:set datafile separator "," startrange = strptime("%d.%m.%Y","26.12.2014") endrange = strptime("%d .%m.%Y","29.12.2014") 有效日期(x) = (curdate=strptime("%d.%m.%Y",x),x>=startrange&&x
【解决方案2】:

这是我的情况:

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 日的秒数表示。现在我有可能知道最大/最小值和其他有用值的位置。

【讨论】:

    猜你喜欢
    • 2015-09-08
    • 1970-01-01
    • 2011-01-11
    • 2018-12-26
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多