General functions
now
Added in revision 1
Function now
returns the current time. Time is constant across all the script, so that all operations and queries have the same reference time.
>>> now()
2019-09-01T14:05:10Z
length
Added in revision 1
Function length
returns the number of elements in a str, a timeseries or a dict.
The first and only argument is a str, timeseries or dict
>>> length(`analytics:/path/to/data`[0])
1
merge
Added in revision 1
Function merge
returns a union of all the dicts contained in a timeseries. In case of key collision, the latest entry is kept.
The first and only argument is a timeseries of dicts
>>> `analytics:/path/to/data`[1]
timeseries{
tstamp1: dict{key1: val1, key2: val2, key3: val3}
tstamp2: dict{key1: val4, key2: val5}
}
>>> merge(_)
dict{key1: val4, key2: val5, key: val3}
deletes
Added in revision 1
Function deletes
returns a timeseries of dicts used as sets of the delete keys from the input timeseries.
Only works with unfiltered timeseries, as most filters remove the deletes entries. An empty dict as value means the update is a DeleteAll
The first and only parameter is the timeseries
>>> deletes(`analytics:/path/to/data`[200])
timeseries{
tstamp1: dict{key1: nil, key2: nil}
tstamp2: dict{} # this deletes all keys
}
equal
Added in revision 1
Function equal
performs a cross-type equality check on the given arguments using type coercions.
The first argument is a value of any type
The second argument is a value of any type
>>> equal("1", 1)
true
>>> equal(1, true)
true
>>> equal(0, true)
false
complexKey
Added in revision 1
Function complexKey
parses a string containing a literal or json object.
Numerical values without floating-point will produce an integer.
Numerical values with a floating point will produce a float64 (num).
Boolean literals will produce a boolean (bool).
Values surrounded with {} or [] will be parsed as JSON.
For all cases except float64 (num) and bool, the returned value will be of type unknown (internal interpreter type), but can be used to access complex keys in dicts.
The first and only parameter is the str to parse
>>> complexKey("1")
int(1) # AQL type is unknown
>>> complexKey("1.2")
float64(1.2) # AQL type is num
>>> complexKey("{\"key1\": 1, \"key2\": true}")
{"key1":1,"key2":true}# AQL type is unknown
>>> complexKey("[1, 2, true]")
[1,2,true] # AQL type is unknown
Dicts functions
newDict
Added in revision 1
Function newDict
returns a new empty dict.
>>> newDict()
dict{}
dictRemove
Added in revision 1
Function dictRemove
removes a given key from a dict.
The first argument is the dict
The second argument is the key to remove
>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictRemove(d, "key")
>>> d
dict{"key2": 2}
dictHasKey
Added in revision 1
Function dictHasKey
returns true if a dict contains the specified key, false if it doesn’t.
The first parameter is the dict
The second parameter is the key
>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictHasKey(d, "key")
true
>>> dictHasKey(d, "key3")
false
dictKeys
Added in revision 1
Function dictKeys
returns a timeseries with the list of keys in a dict.
The first and only parameter is the dict
>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictKeys(d)
timeseries{
0000-00-00 00:00:00.000000001: "key"
0000-00-00 00:00:00.000000002: "key2"
}
unnestTimeseries
Added in revision 4
Function unnestTimeseries
merges multiple timeseries nested in dicts, pushes them to the top level,
and returns a single flattened timeseries where the former top-level dicts are now nested within
the timeseries’ values. The input data is typically what a query using *
wildcards would return.
The first and only parameter is a dict that contains timeseries, either directly in the value, or nested in more levels of dict.
Example
>>> let ts = `analytics:/Devices/*/versioned-data/interfaces/data/*/aggregate/hardware/xcvr/1m`[1m] | recmap(2, _value | field("temperature") | field("avg"))
>>> let d = newDict() | setFields("AA", ts)
>>> d
dict{AA: dict{
HSH14280171: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
}
}
JAS17070003: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
}
}
}}
>>> unnestTimeseries(d)
timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: dict{AA: dict{
HSH14280171: dict{
Ethernet50: 34.184087816704434
Ethernet51: 34.84759166533158
}
JAS17070003: dict{
Ethernet50: 30.65325390983907
Ethernet51: 27.58473123455124
}
}}
2022-08-16 17:11:00 +0200 CEST: dict{AA: dict{
HSH14280171: dict{
Ethernet50: 34.18519049983288
Ethernet51: 34.84247911778802
}
JAS17070003: dict{
Ethernet50: 30.65664047328105
Ethernet51: 27.597529745280074
}
}}
}
>>> let b = `analytics:/Devices/JPE17191574/versioned-data/interfaces/data/Ethernet50/aggregate/hardware/xcvr/1m`[2m] | field("voltage") | field("max")
>>> let dd = newDict() | setFields("BB", b)
>>> let ddd = newDict() | setFields("DD", ts, "EE", dd)
>>> d["FF"]=ddd
>>> d
dict{
AA: dict{
HSH14280171: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
}
}
JAS17070003: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
}
}
}
FF: dict{
DD: dict{
HSH14280171: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
}
}
JAS17070003: dict{
Ethernet50: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
}
Ethernet51: timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:11:21.217673 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
}
}
}
EE: dict{BB: timeseries{
start: 2022-08-16 17:14:06.794969 +0200 CEST
end: 2022-08-16 17:16:06.794969 +0200 CEST
2022-08-16 17:14:00 +0200 CEST: 3.2909
2022-08-16 17:15:00 +0200 CEST: 3.2909
2022-08-16 17:16:00 +0200 CEST: 3.2909
}}
}
}
>>> unnestTimeseries(d)
timeseries{
start: 2022-08-16 17:10:21.217673 +0200 CEST
end: 2022-08-16 17:16:06.794969 +0200 CEST
2022-08-16 17:10:00 +0200 CEST: dict{
AA: dict{
HSH14280171: dict{
Ethernet50: 34.184087816704434
Ethernet51: 34.84759166533158
}
JAS17070003: dict{
Ethernet50: 30.65325390983907
Ethernet51: 27.58473123455124
}
}
FF: dict{DD: dict{
HSH14280171: dict{
Ethernet50: 34.184087816704434
Ethernet51: 34.84759166533158
}
JAS17070003: dict{
Ethernet50: 30.65325390983907
Ethernet51: 27.58473123455124
}
}}
}
2022-08-16 17:11:00 +0200 CEST: dict{
AA: dict{
HSH14280171: dict{
Ethernet50: 34.18519049983288
Ethernet51: 34.84247911778802
}
JAS17070003: dict{
Ethernet50: 30.65664047328105
Ethernet51: 27.597529745280074
}
}
FF: dict{DD: dict{
HSH14280171: dict{
Ethernet50: 34.18519049983288
Ethernet51: 34.84247911778802
}
JAS17070003: dict{
Ethernet50: 30.65664047328105
Ethernet51: 27.597529745280074
}
}}
}
2022-08-16 17:14:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
2022-08-16 17:15:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
2022-08-16 17:16:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
}
Data Analysis Functions
groupby
Added in revision 1
Function groupby
, applied to a timeseries, returns a dict with keys corresponding to the ‘group by field’ parameter,
and values corresponding to the associate method and field.
The function takes 4 parameters:
A timeseries of dicts to apply this function to
The name of the ‘group by field’ (a str)
The name of one of the supported associative methods (a str)
The name of the field whose values will be operated on by the associative method (a str)
The entries in the timeseries are grouped by the values of the field from parameter 1. For each entry, the value corresponding to the associative field of parameter 4 is obtained. This results in a map with entries of the following format:
key: values of the ‘group by field’
value: lists of values of the ‘associative field’
On each of these lists, the following associative methods can be applied:
count
: returns the length of the list (i.e. the item count)max
: returns the max entry in the listmean
: returns the mean of the values in the listmin
: returns the min entry in the listsum
: returns the sum of the entries in the list
>>> `analytics:/path/to/data`[3]
timeseries{
tstamp1: dict{"name": "name1", "value": 1}
tstamp2: dict{"name": "name2", "value": 10}
tstamp3: dict{"name": "name1", "value": 2}
tstamp4: dict{"name": "name2", "value": 11}
}
>>> let ts = _
>>> groupby(ts, "name", "mean", "value")
dict{
"name1": 1.5
"name2": 10.5
}
>>> groupby(ts, "name", "count", "value")
dict{
"name1": 2
"name2": 2
}
>>> groupby(ts, "name", "sum", "value")
dict{
"name1": 3
"name2": 21
}
histogram
Added in revision 1
Function histogram
, for a given timeseries of non-dict values, returns a dict with entries of the following format:
key: value in the timeseries (range if a timeseries of num values)
value: time-weighted frequency in the timeseries
Arguments:
A timeseries of non-dict values is the only argument to this function
>>> `analytics:/path/to/data`[3] | field("strfield")
timeseries{
start: 2019-08-31 00:00:00
end: 2019-08-31 00:12:00
2019-08-31 00:00:00: "string1"
2019-08-31 00:01:00: "string2"
2019-08-31 00:10:00: "string1"
2019-08-31 00:11:00: "string1"
}
>>> histogram(_)
dict{
"string1": 0.25
"string2": 0.75
} # the count is weighted accordingly to the intervals
>>> `analytics:/path/to/data`[5] | field("numfield")
timeseries{
start: 2019-08-31 00:00:00
end: 2019-08-31 01:00:00
2019-08-31 00:00:00: 1
2019-08-31 00:01:00: 1.01
2019-08-31 00:10:00: 1.011
2019-08-31 00:30:00: 5.2
2019-08-31 00:44:00: 5.22
2019-08-31 00:56:00: 5.23
}
>>> histogram(_)
dict{
"1.0-1.011": 0.5
"5.2-5.23": 0.5
} # the count is weighted accordingly to the intervals
dhistogram
Added in revision 1
Function dhistogram
, has a similar behaviour as histogram but its result is not time-weighted.
For a given timeseries of non-dict values, returns a dict with entries of the following format:
key: value in the timeseries (range if a timeseries of num values)
value: frequency (non-weighted count of occurences) in the timeseries
Arguments:
A timeseries of non-dict values is the only argument to this function
>>> `analytics:/path/to/data`[3] | field("strfield")
timeseries{
start: 2019-08-31 00:00:00
end: 2019-08-31 00:05:00
2019-08-31 00:00:00: "string1"
2019-08-31 00:01:00: "string2"
2019-08-31 00:10:00: "string1"
2019-08-31 00:11:00: "string1"
} # the count does not depend of the time intervals between the updates
>>> dhistogram(_)
dict{
"string1": 3
"string2": 1
} # the count does not depend of the time intervals between the updates
>>> `analytics:/path/to/data`[5] | field("numfield")
timeseries{
2019-08-31 00:00:00: 1
2019-08-31 00:01:00: 1.01
2019-08-31 00:10:00: 1.011
2019-08-31 00:30:00: 5.2
2019-08-31 00:44:12: 5.22
2019-08-31 02:01:34: 5.23
}
>>> dhistogram(_)
dict{
"1.0-1.011": 3
"5.2-5.23": 3
} # the count does not depend of the time intervals between the updates
aggregate
Added in revision 4
Function aggregate
merges multiple timeseries contained in a dict (like the result of a
wildcarded query) using the associative method specified in the second parameter. The dict must
contain timeseries, all of which must contain identical timestamps.
If one of the timeseries is empty, it will be ignored.
If some values’ timestamps are not matched in all the other non-empty timeseries of the dict, these timestamp-value pairs will not be present in the output timeseries.
aggregate
returns a simple timeseries with the aggregated data of all the input timeseries.
The first argument is the dict containing timeseries to aggregate
The second argument is the name of the associative method to apply
Like with groupby, the following associative methods can be applied:
count
: returns the length of the list (i.e. the item count)max
: returns the max entry in the list (requires the timeseries to be numerical)mean
: returns the mean of the values in the list (requires the timeseries to be numerical)min
: returns the min entry in the list (requires the timeseries to be numerical)sum
: returns the sum of the entries in the list (requires the timeseries to be numerical)
>>> let data = `analytics:/Devices/*/versioned-data/interfaces/data/*/aggregate/hardware/xcvr/15m`[1h]
>>> let avg = data | recmap(2, _value | field("temperature") | field("avg"))
>>> avg
JPE123456: dict{
Ethernet1: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 28.64315689104305
2021-11-09 13:15:00 +0000 GMT: 28.64771549594622
2021-11-09 13:30:00 +0000 GMT: 28.647003241959368
}
Ethernet2: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 26.52073192182222
2021-11-09 13:15:00 +0000 GMT: 26.57132998707
2021-11-09 13:30:00 +0000 GMT: 26.562415784963335
}
[...]
}
JPE654321: dict{
Ethernet1: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 27.872056741171672
2021-11-09 13:15:00 +0000 GMT: 26.422506200403397
2021-11-09 13:30:00 +0000 GMT: 27.889330661612725
}
Ethernet2: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 25.501376131906685
2021-11-09 13:15:00 +0000 GMT: 24.06172043150084
2021-11-09 13:30:00 +0000 GMT: 25.520567819910998
}
[...]
}
[...]
>>> let deviceAvg = avg | map(aggregate(_value, "mean"))
>>> deviceAvg
JPE123456: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 29.46781924765547
2021-11-09 13:15:00 +0000 GMT: 28.739134103556832
2021-11-09 13:30:00 +0000 GMT: 29.756429823529587
}
JPE654321: timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 27.581944406432633
2021-11-09 13:15:00 +0000 GMT: 27.60952274150811
2021-11-09 13:30:00 +0000 GMT: 27.60470951346135
}
[...]
>>> aggregate(deviceAvg, "mean") # average temp accross all interfaces of all devices
timeseries{
start: 2021-11-09 13:02:18.923904 +0000 GMT
end: 2021-11-09 13:32:18.923904 +0000 GMT
2021-11-09 13:00:00 +0000 GMT: 33.261383897237806
2021-11-09 13:15:00 +0000 GMT: 33.16722874112898
2021-11-09 13:30:00 +0000 GMT: 33.37487749955894
}
Math functions
abs
Added in revision 1
Function abs
returns the absolute value (num) of the given value.
The first and only argument \(x\) is the value (num) of which the absolute value \(\lvert x \lvert\) is wanted
>>> abs(-11)
11
>>> abs(200)
200
ceil
Added in revision 1
Function ceil
returns the closest integer (num) succeeding the given value.
The first and only argument \(x\) is the value (num) of which the ceil \(\lceil x \rceil\) is wanted
>>> ceil(12)
12
>>> ceil(12.1)
13
>>> ceil(-12.1)
-12
floor
Added in revision 1
Function floor
returns the closest integer (num) preceding the given value.
The first and only argument \(x\) is the value (num) of which the floor \(\lfloor x \rfloor\) is wanted
>>> floor(3)
3
>>> floor(3.2)
3
>>> floor(-3.2)
-4
trunc
Added in revision 1
Function trunc
returns the truncated (num) given value.
The first and only argument is the value (num) to be truncated
>>> trunc(2.6)
2
>>> trunc(-2.49)
-2
exp
Added in revision 1
Function exp
returns the exponential (num) of the given value.
The first and only argument \(x\) is the value (num) of which the exp \(e^x\) is wanted
>>> exp(0)
1
>>> exp(12.1)
179871.86225375105
factorial
Added in revision 1
Function factorial
returns the factorial (num) of the given value.
The first and only argument \(x\) is the value (num) of which the factorial \(x!\) is wanted
>>> factorial(3)
6
gcd
Added in revision 1
Function gcd
returns the greatest common divisor (num) of two given integers.
The first two arguments are the integers (num) of which the GCD is wanted
>>> gcd(25, 30)
5
log
Added in revision 1
Function log
returns the natural log (num) of the given value.
The first and only argument \(x\) is the value (num) of which the natural log \(log_e x\) is wanted
>>> log(10)
2.302585092994046
log10
Added in revision 1
Function log10
returns the decimal log (num) of the given value.
The first and only argument \(x\) is the value (num) of which the decimal log \(log_{10} x\) is wanted
>>> log10(10)
1
pow
Added in revision 1
Function pow
returns the first given value (num) to the power of the second given value.
>>> pow(3, 2)
9
>>> pow(9, 1/2)
3
round
Added in revision 1
Function round
returns the rounded (num) given value.
The first and only argument \(x\) is the value used to compute \(\lfloor x\rceil\) i.e. the rounded value (num)
>>> round(2.5)
3
>>> round(2.49)
2
sqrt
Added in revision 1
Function sqrt
returns the square root (num) of the given value.
The first and only argument \(x\) is the value (num) of which the square root \(\sqrt{x}\) is wanted
>>> sqrt(9)
3
max
Added in revision 1
Function max
returns the max value (num) in a timeseries or a dict.
The first and only argument is a timeseries or dict containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> max(_)
200
min
Added in revision 1
Function min
returns the min value (num) in a timeseries or a dict.
The first and only argument is a timeseries or dict containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> min(_)
1
formatInt
Added in revision 4
Function formatInt
formats a num into a str using the specified base. The num will be treated
as an integer and any decimal part will be truncated.
>>> formatInt(4, 2)
100
>>> formatInt(4.5, 2)
100
>>> formatInt(33, 2)
100001
>>> formatInt(15, 16)
f
>>> formatInt(29, 16)
1d
>>> type(_)
str
formatFloat
Added in revision 4
Function formatFloat
formats a num (float64
) into a str, according to the specified format and
precision.
The first argument is the num to convert
The second argument is a str of one letter describing the format:
'b'
: binary exponent'e'
: decimal exponent'f'
: no exponent'x'
: hexadecimal fraction and binary exponent
The third argument is :ref:a num specifying the precision, i.e. the number of digits after the decimal point
>>> formatFloat(15682.8729, "e", 10)
1.5682872900e+04
>>> formatFloat(15682.8729, "f", 10)
15682.8729000000
>>> formatFloat(15, "x", 3)
0x1.e00p+03
>>> formatFloat(15, "b", 3)
8444249301319680p-49
>>> type(_)
str
Stats functions
dsum
Added in revision 1
Function dsum
returns the non-weighted sum of values (num) in a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dsum(_)
216
dmean
Added in revision 1
Function dmean
returns the non-weighted mean value (num) of a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dmean(_)
54
dmedian
Added in revision 1
Function dmedian
returns the non-weighted median (num) of a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dmedian(_)
2
dpercentile
Added in revision 1
Function dpercentile
returns the non-weighted nth percentile (num) of a timeseries.
The first argument is a timeseries containing plain num values
The second argument is a num specifying the percentile. If it is greater than 100 or lower than 0, the return value will be 0.
>>> let a = `analytics:/path/to/data`[3] | field("numfield")
>>> a
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dpercentile(a, 50)
2
>>> dpercentile(a, 90)
200
dvariance
Added in revision 1
Function dvariance
returns the non-weighted statistical variance (num) of a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dvariance(_)
9503.333333333334
dstddev
Added in revision 1
Function dstddev
returns the non-weighted standard deviation (num) of a timeseries.
The first and only argument is a timeseries containing plain num values
>>> let a = `analytics:/path/to/data`[3] | field("numfield")
>>> a
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dstddev(a)
97.48504158758581
>>> sqrt(dvariance(a))
97.48504158758581
dskew
Added in revision 1
Function dskew
returns the non-weighted skewness of distribution (num) for data in a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dskew(_)
0.7431002727844832
dkurtosis
Added in revision 1
Function dkurtosis
returns the non-weighted kurtosis of distribution (num) for data in a timeseries.
The first and only argument is a timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> dkurtosis(_)
-1.6923313578244437
sum
Added in revision 1
Function sum
returns the sum of the num values in a timeseries or a dict.
If applied to a timeseries, the result is time-weighted.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> sum(_)
216
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> sum(d)
216
mean
Added in revision 1
Function mean
returns the mean of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> mean(_)
54 # will be different from dmean if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> mean(d)
54
median
Added in revision 1
Function median
returns the median of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> median(_)
2 # will be different from dmedian if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> median(d)
2
percentile
Added in revision 1
Function percentile
returns the time-weighted nth percentile (num) of a timeseries or a dict.
If applied to a timeseries, the result is time-weighted.
The first argument is a timeseries or a dict containing plain num values
The second argument is a num specifying the percentile. If it is greater than \(100\) or lower than \(0\), the return value will be \(0\).
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> percentile(_, 90)
200 # will be different from dpercentile if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> percentile(d, 90)
200
variance
Added in revision 1
Function variance
returns the statistical variance of the num values in a timeseries or a dict.
If applied to a timeseries, the result is time-weighted.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> variance(_)
9503.333333333334 # will be different from dvariance if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> variance(d, 90)
9503.33333333
stddev
Added in revision 1
Function stddev
returns the standard deviation of the num values in a timeseries or a dict.
If applied to a timeseries, the result is time-weighted.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> stddev(_)
97.485041588 # will be different from dstddev if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> stddev(d, 90)
97.485041588
skew
Added in revision 1
Function skew
returns the skewness of dist.n of the num values in a timeseries or a dict.
If applied to a timeseries, the result is time-weighted. If the timeseries has exactly one element, \(0\) is returned.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> skew(_)
0.7431002727844832 # will be different from dskew if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> skew(d, 90)
0.7431002727844832
kurtosis
Added in revision 1
Function kurtosis
returns the kurtosis of dist.n of the num values in a timeseries or a dict.
If applied to a timeseries, the result is time-weighted. If the timeseries has exactly one element, \(0\) is returned.
The first and only argument is a dict or timeseries containing plain num values
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
tstamp1: 13
tstamp2: 1
tstamp3: 2
tstamp4: 200
}
>>> skew(_)
0.7431002727844832 # will be different from dskew if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> skew(d, 90)
0.7431002727844832
rate
Added in revision 1
Function rate
returns a timeseries of rates computed from the initial timeseries’ num values.
The first and only argument is the input timeseries of num
>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
2019-08-31 00:00:00: 1
2019-08-31 00:01:00: 10
2019-08-31 00:02:00: 50
2019-08-31 00:03:00: 110
2019-08-31 00:04:00: 230
}
>>> rate(_)
timeseries{
2019-08-31 00:00:00: 0.016666666666666666
2019-08-31 00:01:00: 0.15
2019-08-31 00:02:00: 0.6666666666666666
2019-08-31 00:03:00: 1
2019-08-31 00:04:00: 2
}
linregression
Added in revision 3
Function linregression
produces a linear fit of a timeseries of num.
The first and only argument is the input timeseries of num
It returns a dict with 4 entries slope
, intercept
, R2
and fit
. The fit
entry is a timeseries
with num values corresponding to the fitted line on the input timeseries’ timestamps. The slope
and intercept
are in seconds.
>>> `analytics:/path/to/data`[5m] | field("numfield")
timeseries{
start: 2021-10-14 13:57:55.000545 +0100 IST
end: 2021-10-14 14:02:55.000545 +0100 IST
2021-10-14 13:57:00 +0100 IST: 3.801633107494212e-05
2021-10-14 13:58:00 +0100 IST: 7.653320559746086e-05
2021-10-14 13:59:00 +0100 IST: 3.971200542852744e-05
2021-10-14 14:00:00 +0100 IST: 3.981215360110563e-05
2021-10-14 14:01:00 +0100 IST: 5.2121957107961934e-05
2021-10-14 14:02:00 +0100 IST: 3.838672949594982e-05
}
>>> linregression(_)
dict{
R2: 0.06273653863866613
fit: timeseries{
start: 2021-10-14 13:57:00 +0100 IST
end: 2021-10-14 14:02:00 +0100 IST
2021-10-14 13:57:00 +0100 IST: 5.252194027605128e-05
2021-10-14 13:58:00 +0100 IST: 5.0485322987015024e-05
2021-10-14 13:59:00 +0100 IST: 4.844870569797877e-05
2021-10-14 14:00:00 +0100 IST: 4.641208840183708e-05
2021-10-14 14:01:00 +0100 IST: 4.4375471112800824e-05
2021-10-14 14:02:00 +0100 IST: 4.2338853823764566e-05
}
intercept: 55.47126937459381
slope: -3.39436215194667e-08
}
ewlinregression
Added in revision 3
Function ewlinregression
produces a linear fit of a timeseries of num using exponentially
decaying weights. The older the value in the timeseries the smaller the weight. The latest value is
always given a weight of \(1\).
The first argument is the input timeseries of num
The second argument is the desired weight that a point with time x seconds in the past would have
the third argument is how long ago that time \(x\) is, in seconds
It returns a dict with 4 entries slope
, intercept
, R2
and fit
. The fit
entry is a timeseries
with num values corresponding to the fitted line on the input timeseries’ timestamps. The slope
and intercept
are in seconds.
>>> `analytics:/path/to/data`[5m] | field("numfield")
timeseries{
start: 2021-10-14 13:57:55.000545 +0100 IST
end: 2021-10-14 14:02:55.000545 +0100 IST
2021-10-14 13:57:00 +0100 IST: 3.801633107494212e-05
2021-10-14 13:58:00 +0100 IST: 7.653320559746086e-05
2021-10-14 13:59:00 +0100 IST: 3.971200542852744e-05
2021-10-14 14:00:00 +0100 IST: 3.981215360110563e-05
2021-10-14 14:01:00 +0100 IST: 5.2121957107961934e-05
2021-10-14 14:02:00 +0100 IST: 3.838672949594982e-05
}
>>> ewlinregression(_, 0.01, 100.0)
dict{
R2: 0.34201204121343765
fit: timeseries{
start: 2021-10-14 14:03:00 +0100 IST
end: 2021-10-14 14:08:00 +0100 IST
2021-10-14 14:03:00 +0100 IST: 4.5425229615148055e-05
2021-10-14 14:04:00 +0100 IST: 4.4509288322558405e-05
2021-10-14 14:05:00 +0100 IST: 4.359334702641604e-05
2021-10-14 14:06:00 +0100 IST: 4.267740573382639e-05
2021-10-14 14:07:00 +0100 IST: 4.176146444123674e-05
2021-10-14 14:08:00 +0100 IST: 4.0845523145094376e-05
}
intercept: 24.94748623552414
slope: -1.526568822982724e-08
}
String manipulation
strToUpper
Added in revision 1
Function strToUpper
returns uppercase version of given str.
The first and only parameter is a str to convert to uppercase
>>> strToUpper("ToUpper")
"TOUPPER"
strToLower
Added in revision 1
Function strToLower
returns lowercase version of given str.
The first and only parameter is a str to convert to lowercase
>>> strToLower("ToLower")
"TOLOWER"
strContains
Added in revision 1
Function strContains
returns whether the first str contains the second str.
Both arguments to the function are str
>>> strContains("thatistext", "is")
true
strCount
Added in revision 1
Function strCount
returns the number of occurrences of the second str in the first str.
Both arguments to the function are str
>>> strCount("tertarter", "te")
2
strIndex
Added in revision 1
Function strIndex
returns the index of the first occurrence of the second str in the first str, and -1 if it is not present.
Both arguments to the function are str
>>> strIndex("thatistext", "is")
4
strReplace
Added in revision 1
Function strReplace
returns a copy of the first str, where occurrences of the second str are replaced by the third str.
The three arguments to the function are str
>>> strReplace("thatistext", "is", "was")
"thatwastext"
strHasPrefix
Added in revision 1
Function strHasPrefix
returns whether the first str starts with the second str.
Both arguments to the function are str
>>> strHasPrefix("thatistext", "is")
false
>>> strHasPrefix("thatistext", "that")
true
strHasSuffix
Added in revision 1
Function strHasSuffix
returns whether the first str ends with the second str.
Both arguments to the function are str
>>> strHasSuffix("thatistext", "xt")
true
strSplit
Added in revision 1
Function strSplit
returns a timeseries of str. The function splits the first str into substrings, separated by the second str.
Both arguments to the function are str
>>> strSplit("that./is.text", "./")
timeseries{
0000-00-00 00:00:00.000000001: "that"
0000-00-00 00:00:00.000000002: "is.text"
}
strCut
Added in revision 4
Function strCut
returns the portion of a str between two indexes (excluding ending index).
Negative indexes start from the end of the input str.
The first argument (str) is the string from which the portion is returned
The second argument (num) is the starting index
The third argument (num) is the ending index
>>> strCut("0123456789", 1, 4)
123
>>> strCut("0123456789", -8, -2)
234567
>>> strCut("abcd", 1, 3)
bc
reFindAll
Added in revision 1
Function reFindAll
returns a timeseries of str which contains matches of the second str (regex) in the first str.
Both arguments to the function are str
>>> reFindAll("i am a string with text", "i[a-z]+")
timeseries{
0000-00-00 00:00:00.000000001: "ing"
0000-00-00 00:00:00.000000002: "ith"
}
reMatch
Added in revision 1
Function reMatch
returns whether the first str contains matches of the second str (regex).
Both arguments to the function are str
>>> reMatch("i am a string with text", "i[a-z]+")
true
reFindCaptures
Added in revision 1
Function reFindCaptures
returns a timeseries of str lists. Each list contains the full match followed by each capture
Both arguments to the function are str. The first one is the str to match, and the second is the regular expression
>>> reFindCaptures("foobarbaztootartaz", "foo")
timeseries{
0000-00-00 00:00:00.000000001: ["foo"]
}
>>> reFindCaptures("foobarbaztootartaz", "(foo)")
timeseries{
0000-00-00 00:00:00.000000001: ["foo", "foo"]
}
>>> reFindCaptures("foobarbaztootartaz", "f(oo)")
timeseries{
0000-00-00 00:00:00.000000001: ["foo", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "(oo)")
timeseries{
0000-00-00 00:00:00.000000001: ["oo", "oo"]
0000-00-00 00:00:00.000000002: ["oo", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "[ft](oo)")
timeseries{
0000-00-00 00:00:00.000000001: ["foo", "oo"]
0000-00-00 00:00:00.000000002: ["too", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "([ft])(oo)")
timeseries{
0000-00-00 00:00:00.000000001: ["foo", "f", "oo"]
0000-00-00 00:00:00.000000002: ["too", "t", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "[ft](oo).*(az)")
timeseries{
0000-00-00 00:00:00.000000001: ["foobarbaztootartaz", "oo", "az"]
}
CLI-only Functions
Warning
The functions described in this section can only be used in CLI. They cannot be called from a service or through a Web interface.
help
Added in revision 1
Function help
returns the help of all filters and functions as a formatted str.
>>> help()
# Functions
## now
- Function `now` returns the current time. Time is constant across all the script, so that all operations and queries have the same reference time
[...]
dump
Added in revision 1
Function dump
attempts to dump variables from the interpreter into a file.
The first and only argument is the path to the file (str)
>>> let myVar = 2
>>> dump("file.dump")
load
Added in revision 1
Function load
attempts to load variables into the interpreter from a file.
The first and only argument is the path to the file (str)
>>> load("file.dump")
true
>>> myVar
2
>>> let myVar = 5
>>> if load("file.dump") {
... myVar
... }
2
plot
Added in revision 1
Function plot
plots a timeseries or dict of num values.
The first argument is the timeseries or dict of num values to plot
The second argument (optional) is the path (str) to the image PNG file to write the plot to. If not specified, defaults to
plot.png
>>> plot(myTimeseriesOrDict, "myplotimg.png")