You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gnuplot技术问题:从字符串提取日期配合timecolumn及stats使用

问题与解决方案

问题背景

数据中的日期编码在字符串字段(格式示例:subject_name/20221006085330_test_something),通过自定义函数get_date(c)提取日期部分时,遇到两个问题:

  1. 将get_date("string")传入timecolumn()配合stats命令时,触发unknown type in magnitude()错误;
  2. 调整脚本后能运行,但统计结果显示11条记录(实际仅10条有效数据)。

初始测试脚本

# Test script:
reset session

$DAT<<EOD
# cross
string    date     
subject001_name/20200203144309_session021_id     20200203
subject002_name/20200522103745_session079_id     20200522
subject003_name/20210521172330_session201_id     20210521
subject004_name/20220527130250_session047_id     20220527
subject005_name/20220701171757_session081_id     20220701
subject006_name/20220706102238_session003_id     20220706
subject007_name/20221006110417_session081_id     20221006
subject008_name/20230309144707_session901_id     20230309
subject009_name/20230907080602_session003_id     20230907
subject010_name/20240919143733_session022_id     20240919 
EOD

get_date(c) = substr( strcol(c), strstrt( strcol(c), "/" ) + 1, strstrt( strcol(c), "/" ) + 8 )

blocks              = "cross"
selected_block(i)   = word( blocks, i )

timeFmt             = "%Y%m%d"

stats $DAT i selected_block(1) u ( timecolumn( 2, timeFmt ) ) 

pause -1 

stats $DAT i selected_block(1) u ( timecolumn( get_date( "string" ), timeFmt ) ) 

调整后的测试脚本

# Test script:
reset session

$DAT<<EOD
# cross
string    date     
subject001_name/20200203144309_session021_id     20200203 
subject002_name/20200522103745_session079_id     20200522 
subject003_name/20210521172330_session201_id     20210521 
subject004_name/20220527130250_session047_id     20220527 
subject005_name/20220701171757_session081_id     20220701 
subject006_name/20220706102238_session003_id     20220706 
subject007_name/20221006110417_session081_id     20221006 
subject008_name/20230309144707_session901_id     20230309 
subject009_name/20230907080602_session003_id     20230907 
subject010_name/20240919143733_session022_id     20240919 
EOD

get_date(c) = substr( strcol(c), strstrt( strcol(c), "/" ) + 1, strstrt( strcol(c), "/" ) + 8 )

blocks              = "cross"
selected_block(i)   = word( blocks, i )

timeFmt             = "%Y%m%d"
date_column(col)    = strptime( timeFmt, get_date(col) )

stats $DAT i selected_block(1) u ( date_column("string") ) 

问题分析与解决

1. 解决unknown type in magnitude()错误

timecolumn()的第一个参数要求是列的索引或列名,而get_date("string")返回的是单条记录的日期字符串,不符合参数类型要求,因此触发类型错误。

正确的做法是先将提取到的日期字符串转换为时间戳(用strptime()),再传入stats命令,这也是你调整脚本时的正确方向。

2. 解决统计结果多一条的问题

统计结果多一条是因为表头行被纳入统计。数据块中的string date是列名行,stats默认会处理所有行,包括表头。

解决方法有两种:

  • 方法一:在stats命令中添加skip 1参数,直接跳过表头行;
  • 方法二:优化get_date函数,对不含/的行返回空值,让strptime()生成NaN,stats会自动忽略NaN值。

最终优化脚本

reset session

$DAT<<EOD
# cross
string    date     
subject001_name/20200203144309_session021_id     20200203 
subject002_name/20200522103745_session079_id     20200522 
subject003_name/20210521172330_session201_id     20210521 
subject004_name/20220527130250_session047_id     20220527 
subject005_name/20220701171757_session081_id     20220701 
subject006_name/20220706102238_session003_id     20220706 
subject007_name/20221006110417_session081_id     20221006 
subject008_name/20230309144707_session901_id     20230309 
subject009_name/20230907080602_session003_id     20230907 
subject010_name/20240919143733_session022_id     20240919 
EOD

# 优化后的get_date函数,处理不含/的行返回空值
get_date(c) = (pos = strstrt(strcol(c), "/"), pos > 0 ? substr(strcol(c), pos+1, pos+8) : "")

blocks              = "cross"
selected_block(i)   = word( blocks, i )

timeFmt             = "%Y%m%d"
date_column(col)    = strptime( timeFmt, get_date(col) )

# 添加skip 1确保跳过表头,双重保险
stats $DAT i selected_block(1) skip 1 u ( date_column("string") ) 

内容的提问来源于stack exchange,提问作者magfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:04:59