df-script 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -34
- package/dist/api.d.ts +16 -8
- package/dist/api.js +11 -3
- package/dist/columnExpressions/ColumnExpr.d.ts +26 -364
- package/dist/columnExpressions/ColumnExpr.js +199 -3
- package/dist/columnExpressions/ExprBase.d.ts +8 -11
- package/dist/columnExpressions/ExprBase.js +20 -61
- package/dist/columnExpressions/constants.d.ts +2 -0
- package/dist/columnExpressions/constants.js +3 -1
- package/dist/columnExpressions/functions/coalesce.js +8 -4
- package/dist/columnExpressions/functions/element.d.ts +5 -0
- package/dist/columnExpressions/functions/element.js +11 -0
- package/dist/columnExpressions/functions/implode.d.ts +3 -0
- package/dist/columnExpressions/functions/implode.js +7 -0
- package/dist/columnExpressions/functions/lit.d.ts +3 -1
- package/dist/columnExpressions/functions/lit.js +8 -13
- package/dist/columnExpressions/functions/repeat.d.ts +47 -0
- package/dist/columnExpressions/functions/repeat.js +131 -0
- package/dist/columnExpressions/functions/seq_range.d.ts +31 -0
- package/dist/columnExpressions/functions/seq_range.js +91 -0
- package/dist/columnExpressions/functions/when.js +8 -4
- package/dist/columnExpressions/index.d.ts +5 -2
- package/dist/columnExpressions/index.js +5 -48
- package/dist/columnExpressions/mixins/AggregationExpr.d.ts +25 -50
- package/dist/columnExpressions/mixins/AggregationExpr.js +69 -165
- package/dist/columnExpressions/mixins/ArithmeticExpr.d.ts +41 -66
- package/dist/columnExpressions/mixins/ArithmeticExpr.js +126 -138
- package/dist/columnExpressions/mixins/BooleanExpr.d.ts +40 -0
- package/dist/columnExpressions/mixins/BooleanExpr.js +67 -0
- package/dist/columnExpressions/mixins/ComparisonExpr.d.ts +31 -60
- package/dist/columnExpressions/mixins/ComparisonExpr.js +231 -370
- package/dist/columnExpressions/mixins/ListExpr.d.ts +15 -39
- package/dist/columnExpressions/mixins/ListExpr.js +124 -148
- package/dist/columnExpressions/mixins/LogicalExpr.d.ts +7 -33
- package/dist/columnExpressions/mixins/LogicalExpr.js +48 -49
- package/dist/columnExpressions/mixins/ManipulationExpr.d.ts +6 -31
- package/dist/columnExpressions/mixins/ManipulationExpr.js +61 -25
- package/dist/columnExpressions/mixins/NumericExpr.d.ts +92 -0
- package/dist/columnExpressions/mixins/NumericExpr.js +259 -0
- package/dist/columnExpressions/mixins/StringExpr.d.ts +5 -30
- package/dist/columnExpressions/mixins/StringExpr.js +37 -49
- package/dist/columnExpressions/mixins/StructExpr.d.ts +16 -0
- package/dist/columnExpressions/mixins/StructExpr.js +139 -0
- package/dist/columnExpressions/mixins/TemporalExpr.d.ts +4 -30
- package/dist/columnExpressions/mixins/TemporalExpr.js +28 -29
- package/dist/columnExpressions/mixins/WindowExpr.d.ts +27 -49
- package/dist/columnExpressions/mixins/WindowExpr.js +144 -274
- package/dist/columnExpressions/utils.d.ts +4 -0
- package/dist/columnExpressions/utils.js +45 -0
- package/dist/dataframe/constants.d.ts +3 -0
- package/dist/dataframe/constants.js +4 -1
- package/dist/dataframe/dataframe.d.ts +27 -10
- package/dist/dataframe/dataframe.js +461 -220
- package/dist/dataframe/grouped/grouped.d.ts +2 -3
- package/dist/dataframe/grouped/grouped.js +17 -16
- package/dist/dataframe/types.d.ts +65 -1
- package/dist/dataframe/utils.d.ts +11 -3
- package/dist/dataframe/utils.js +101 -9
- package/dist/datatypes/DataType.d.ts +2 -1
- package/dist/datatypes/DataType.js +29 -0
- package/dist/datatypes/index.d.ts +2 -2
- package/dist/datatypes/types.d.ts +37 -36
- package/dist/datatypes/types.js +15 -11
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +4 -1
- package/dist/exceptions/utils.d.ts +1 -0
- package/dist/exceptions/utils.js +19 -0
- package/dist/functions/concat.d.ts +1 -2
- package/dist/functions/concat.js +24 -12
- package/dist/functions/index.d.ts +3 -1
- package/dist/functions/index.js +7 -15
- package/dist/functions/read_csv.d.ts +8 -0
- package/dist/functions/read_csv.js +53 -0
- package/dist/functions/read_json.d.ts +10 -0
- package/dist/functions/read_json.js +21 -0
- package/dist/functions/transpose.d.ts +7 -0
- package/dist/functions/transpose.js +84 -0
- package/dist/index.js +6 -1
- package/dist/types.d.ts +31 -5
- package/dist/utils/csv.d.ts +77 -0
- package/dist/utils/csv.js +313 -0
- package/dist/utils/date.js +5 -6
- package/dist/utils/guards.d.ts +0 -2
- package/dist/utils/guards.js +0 -31
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/json.d.ts +120 -2
- package/dist/utils/json.js +204 -20
- package/dist/utils/list.d.ts +173 -1
- package/dist/utils/list.js +255 -22
- package/dist/utils/number.d.ts +61 -28
- package/dist/utils/number.js +248 -70
- package/dist/utils/string.d.ts +5 -0
- package/dist/utils/string.js +89 -0
- package/package.json +5 -1
|
@@ -1,45 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ExprBase = exports.derive =
|
|
4
|
-
const utils_1 = require("../utils");
|
|
3
|
+
exports.ExprBase = exports.derive = void 0;
|
|
5
4
|
const constants_1 = require("./constants");
|
|
6
|
-
const
|
|
7
|
-
return (vArray) => {
|
|
8
|
-
const height = vArray.length;
|
|
9
|
-
const result = new Array(height);
|
|
10
|
-
for (let i = 0; i < height; i++) {
|
|
11
|
-
const v = vArray[i];
|
|
12
|
-
result[i] = v == null ? null : fn(v);
|
|
13
|
-
}
|
|
14
|
-
return result;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
exports.kleeneUnary = kleeneUnary;
|
|
18
|
-
const kleeneBinary = (expr, other, fn) => {
|
|
19
|
-
return (vArray, columns) => {
|
|
20
|
-
const height = vArray.length;
|
|
21
|
-
const rResolved = expr._resolve(other, columns, height);
|
|
22
|
-
const result = new Array(height);
|
|
23
|
-
if ((0, utils_1.isArrayOrTypedArray)(rResolved)) {
|
|
24
|
-
for (let i = 0; i < height; i++) {
|
|
25
|
-
const v = vArray[i];
|
|
26
|
-
const r = rResolved[i];
|
|
27
|
-
result[i] = (v == null || r == null) ? null : fn(v, r);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
for (let i = 0; i < height; i++) {
|
|
32
|
-
const v = vArray[i];
|
|
33
|
-
result[i] = (v == null || rResolved == null) ? null : fn(v, rResolved);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
exports.kleeneBinary = kleeneBinary;
|
|
5
|
+
const exceptions_1 = require("../exceptions");
|
|
40
6
|
const derive = (instance, nextOp) => {
|
|
41
7
|
const Constructor = instance.constructor;
|
|
42
|
-
const
|
|
8
|
+
const colNameVal = instance.colNames || instance.colName || "";
|
|
9
|
+
const newInst = new Constructor(colNameVal);
|
|
43
10
|
Object.assign(newInst, instance);
|
|
44
11
|
newInst.ops = nextOp ? [...instance.ops, nextOp] : [...instance.ops];
|
|
45
12
|
return newInst;
|
|
@@ -48,12 +15,15 @@ exports.derive = derive;
|
|
|
48
15
|
class ExprBase {
|
|
49
16
|
ops = [];
|
|
50
17
|
outputName = "";
|
|
18
|
+
isLiteral;
|
|
19
|
+
literalValue;
|
|
51
20
|
aggFn = null;
|
|
52
21
|
groupingOpsIndex;
|
|
53
22
|
partitionOpsIndex;
|
|
54
23
|
partitionBy = null;
|
|
24
|
+
evaluateWindow;
|
|
55
25
|
_resolve(val, columns, height) {
|
|
56
|
-
if (val
|
|
26
|
+
if (val instanceof ExprBase) {
|
|
57
27
|
if (val.isLiteral && val.ops.length === 1) {
|
|
58
28
|
return val.literalValue;
|
|
59
29
|
}
|
|
@@ -62,9 +32,7 @@ class ExprBase {
|
|
|
62
32
|
return val;
|
|
63
33
|
}
|
|
64
34
|
alias(name) {
|
|
65
|
-
const
|
|
66
|
-
const newInst = new Constructor(this.colName || "");
|
|
67
|
-
Object.assign(newInst, this);
|
|
35
|
+
const newInst = (0, exports.derive)(this);
|
|
68
36
|
newInst.outputName = name;
|
|
69
37
|
return newInst;
|
|
70
38
|
}
|
|
@@ -84,11 +52,17 @@ class ExprBase {
|
|
|
84
52
|
return vArray;
|
|
85
53
|
});
|
|
86
54
|
}
|
|
87
|
-
|
|
55
|
+
_getInitialValue(columns, height) {
|
|
88
56
|
const name = this.colName;
|
|
89
|
-
|
|
57
|
+
if (name && name !== constants_1.ALL_COLUMNS_MARKER && !name.startsWith("*") && !(name in columns)) {
|
|
58
|
+
throw new exceptions_1.ColumnNotFoundError(name);
|
|
59
|
+
}
|
|
60
|
+
return name && name !== constants_1.ALL_COLUMNS_MARKER
|
|
90
61
|
? (columns[name] || new Array(height).fill(null))
|
|
91
62
|
: new Array(height).fill(null);
|
|
63
|
+
}
|
|
64
|
+
evaluate(columns, height) {
|
|
65
|
+
let value = this._getInitialValue(columns, height);
|
|
92
66
|
const ops = this.ops;
|
|
93
67
|
const len = ops.length;
|
|
94
68
|
for (let i = 0; i < len; i++) {
|
|
@@ -96,11 +70,8 @@ class ExprBase {
|
|
|
96
70
|
}
|
|
97
71
|
return value;
|
|
98
72
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
let value = name && name !== constants_1.ALL_COLUMNS_MARKER
|
|
102
|
-
? (columns[name] || new Array(height).fill(null))
|
|
103
|
-
: new Array(height).fill(null);
|
|
73
|
+
evaluatePre(opsIndex, columns, height) {
|
|
74
|
+
let value = this._getInitialValue(columns, height);
|
|
104
75
|
const ops = this.ops;
|
|
105
76
|
const idx = opsIndex !== undefined ? opsIndex : ops.length;
|
|
106
77
|
for (let i = 0; i < idx; i++) {
|
|
@@ -108,7 +79,7 @@ class ExprBase {
|
|
|
108
79
|
}
|
|
109
80
|
return value;
|
|
110
81
|
}
|
|
111
|
-
|
|
82
|
+
evaluatePost(opsIndex, aggregatedArray, columns) {
|
|
112
83
|
const ops = this.ops;
|
|
113
84
|
const idx = opsIndex !== undefined ? opsIndex : ops.length;
|
|
114
85
|
let value = aggregatedArray;
|
|
@@ -117,17 +88,5 @@ class ExprBase {
|
|
|
117
88
|
}
|
|
118
89
|
return value;
|
|
119
90
|
}
|
|
120
|
-
evaluatePrePartition(columns, height) {
|
|
121
|
-
return this._evaluatePre(this.partitionOpsIndex, columns, height);
|
|
122
|
-
}
|
|
123
|
-
evaluatePostPartition(aggregatedArray, columns) {
|
|
124
|
-
return this._evaluatePost(this.partitionOpsIndex, aggregatedArray, columns);
|
|
125
|
-
}
|
|
126
|
-
evaluatePreGrouping(columns, height) {
|
|
127
|
-
return this._evaluatePre(this.groupingOpsIndex, columns, height);
|
|
128
|
-
}
|
|
129
|
-
evaluatePostGrouping(aggregatedArray, columns) {
|
|
130
|
-
return this._evaluatePost(this.groupingOpsIndex, aggregatedArray, columns);
|
|
131
|
-
}
|
|
132
91
|
}
|
|
133
92
|
exports.ExprBase = ExprBase;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LITERAL_MARKER = exports.ALL_COLUMNS_MARKER = void 0;
|
|
3
|
+
exports.ELEMENT_MARKER = exports.COALESCE_MARKER = exports.LITERAL_MARKER = exports.ALL_COLUMNS_MARKER = void 0;
|
|
4
4
|
exports.ALL_COLUMNS_MARKER = "*";
|
|
5
5
|
exports.LITERAL_MARKER = "*literal*";
|
|
6
|
+
exports.COALESCE_MARKER = "*coalesce*";
|
|
7
|
+
exports.ELEMENT_MARKER = "*element*";
|
|
@@ -3,15 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.coalesce = coalesce;
|
|
4
4
|
const ColumnExpr_1 = require("../ColumnExpr");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
6
7
|
function coalesce(...exprs) {
|
|
7
8
|
const rawArgs = (exprs.length === 1 && Array.isArray(exprs[0]))
|
|
8
9
|
? exprs[0]
|
|
9
10
|
: exprs;
|
|
10
|
-
const expr = new ColumnExpr_1.ColumnExpr(
|
|
11
|
+
const expr = new ColumnExpr_1.ColumnExpr(constants_1.COALESCE_MARKER);
|
|
11
12
|
expr.ops.push((_, columns) => {
|
|
12
13
|
const height = _.length;
|
|
13
14
|
const evaluateArg = (arg) => {
|
|
14
|
-
if (arg
|
|
15
|
+
if (ColumnExpr_1.ColumnExpr.isColExpr(arg)) {
|
|
15
16
|
return arg.evaluate(columns, height);
|
|
16
17
|
}
|
|
17
18
|
if (typeof arg === "string") {
|
|
@@ -19,9 +20,12 @@ function coalesce(...exprs) {
|
|
|
19
20
|
}
|
|
20
21
|
return arg;
|
|
21
22
|
};
|
|
22
|
-
const
|
|
23
|
+
const exprCount = rawArgs.length;
|
|
24
|
+
const evaluatedArrays = new Array(exprCount);
|
|
25
|
+
for (let j = 0; j < exprCount; j++) {
|
|
26
|
+
evaluatedArrays[j] = evaluateArg(rawArgs[j]);
|
|
27
|
+
}
|
|
23
28
|
const result = new Array(height);
|
|
24
|
-
const exprCount = evaluatedArrays.length;
|
|
25
29
|
for (let i = 0; i < height; i++) {
|
|
26
30
|
let foundVal = null;
|
|
27
31
|
for (let j = 0; j < exprCount; j++) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.element = element;
|
|
4
|
+
const ColumnExpr_1 = require("../ColumnExpr");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
/**
|
|
7
|
+
* Creates an expression referencing the current element(s) of a list during evaluation.
|
|
8
|
+
*/
|
|
9
|
+
function element() {
|
|
10
|
+
return new ColumnExpr_1.ColumnExpr(constants_1.ELEMENT_MARKER);
|
|
11
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ColumnExpr } from "../ColumnExpr";
|
|
2
|
+
import type { SeqRangeOptions } from "./seq_range";
|
|
3
|
+
export type LitOptions = Pick<SeqRangeOptions, "dtype" | "name">;
|
|
2
4
|
/**
|
|
3
5
|
* Creates a literal column expression that repeats the given value for all rows.
|
|
4
6
|
*/
|
|
5
|
-
export declare function lit(value: any): ColumnExpr<any>;
|
|
7
|
+
export declare function lit(value: any, options?: LitOptions): ColumnExpr<any>;
|
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.lit = lit;
|
|
4
|
-
const
|
|
5
|
-
const constants_1 = require("../constants");
|
|
4
|
+
const seq_range_1 = require("./seq_range");
|
|
6
5
|
/**
|
|
7
6
|
* Creates a literal column expression that repeats the given value for all rows.
|
|
8
7
|
*/
|
|
9
|
-
function lit(value) {
|
|
10
|
-
const expr =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const result = new Array(height);
|
|
16
|
-
for (let i = 0; i < height; i++) {
|
|
17
|
-
result[i] = value;
|
|
18
|
-
}
|
|
19
|
-
return result;
|
|
8
|
+
function lit(value, options) {
|
|
9
|
+
const expr = (0, seq_range_1.seq_range)(value, {
|
|
10
|
+
strict: true,
|
|
11
|
+
mode: "constant",
|
|
12
|
+
dtype: options?.dtype,
|
|
13
|
+
name: options?.name,
|
|
20
14
|
});
|
|
15
|
+
expr.isLiteral = true;
|
|
21
16
|
return expr;
|
|
22
17
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ColumnExpr } from "../ColumnExpr";
|
|
2
|
+
import type { RegisteredDataType } from "../../types";
|
|
3
|
+
export type RepeatOptions = {
|
|
4
|
+
n?: number;
|
|
5
|
+
dtype?: RegisteredDataType;
|
|
6
|
+
name?: string;
|
|
7
|
+
} & ({
|
|
8
|
+
mode?: "constant";
|
|
9
|
+
} | {
|
|
10
|
+
mode: "cumulative" | "independent";
|
|
11
|
+
step?: number | ((prevOrIndex: any, index: number) => any);
|
|
12
|
+
}) & ({
|
|
13
|
+
strict?: true;
|
|
14
|
+
} | {
|
|
15
|
+
strict: false;
|
|
16
|
+
pad?: boolean;
|
|
17
|
+
truncate?: boolean;
|
|
18
|
+
padValue?: any;
|
|
19
|
+
startIndex?: number;
|
|
20
|
+
endIndex?: number;
|
|
21
|
+
});
|
|
22
|
+
export type SeqRangeOptions = {
|
|
23
|
+
n?: number;
|
|
24
|
+
dtype?: RegisteredDataType;
|
|
25
|
+
name?: string;
|
|
26
|
+
step?: number | ((prevOrIndex: any, index: number) => any);
|
|
27
|
+
mode?: "cumulative" | "independent";
|
|
28
|
+
} & ({
|
|
29
|
+
strict?: true;
|
|
30
|
+
} | {
|
|
31
|
+
strict: false;
|
|
32
|
+
pad?: boolean;
|
|
33
|
+
truncate?: boolean;
|
|
34
|
+
padValue?: any;
|
|
35
|
+
startIndex?: number;
|
|
36
|
+
endIndex?: number;
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Creates a literal column expression that repeats the given value.
|
|
40
|
+
* If n is specified, it repeats the value n times.
|
|
41
|
+
* If strict is true (default), a height mismatch with the DataFrame will throw a ShapeError.
|
|
42
|
+
*/
|
|
43
|
+
export declare function repeat(value: any, options?: RepeatOptions): ColumnExpr<any>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a column expression that generates a sequence of values starting from the given start value.
|
|
46
|
+
*/
|
|
47
|
+
export declare function seq_range(start: any, options?: SeqRangeOptions): ColumnExpr<any>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.repeat = repeat;
|
|
4
|
+
exports.seq_range = seq_range;
|
|
5
|
+
const ColumnExpr_1 = require("../ColumnExpr");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const exceptions_1 = require("../../exceptions");
|
|
8
|
+
const utils_1 = require("../../utils");
|
|
9
|
+
/**
|
|
10
|
+
* Creates a literal column expression that repeats the given value.
|
|
11
|
+
* If n is specified, it repeats the value n times.
|
|
12
|
+
* If strict is true (default), a height mismatch with the DataFrame will throw a ShapeError.
|
|
13
|
+
*/
|
|
14
|
+
function repeat(value, options = { strict: true }) {
|
|
15
|
+
const expr = new ColumnExpr_1.ColumnExpr(constants_1.LITERAL_MARKER);
|
|
16
|
+
expr.isLiteral = true;
|
|
17
|
+
expr.literalValue = value;
|
|
18
|
+
const opts = options;
|
|
19
|
+
if (opts.name) {
|
|
20
|
+
expr.outputName = opts.name;
|
|
21
|
+
}
|
|
22
|
+
expr.ops.push((vArray) => {
|
|
23
|
+
const targetHeight = vArray.length;
|
|
24
|
+
let start = opts.startIndex !== undefined ? opts.startIndex : 0;
|
|
25
|
+
if (start < 0) {
|
|
26
|
+
start = targetHeight + start;
|
|
27
|
+
}
|
|
28
|
+
const safeStart = (0, utils_1.clamp)(start, 0, targetHeight);
|
|
29
|
+
let end = opts.endIndex !== undefined ? opts.endIndex : targetHeight;
|
|
30
|
+
if (end < 0) {
|
|
31
|
+
end = targetHeight + end;
|
|
32
|
+
}
|
|
33
|
+
const safeEnd = (0, utils_1.clamp)(end, 0, targetHeight);
|
|
34
|
+
const sliceWidth = Math.max(0, safeEnd - safeStart);
|
|
35
|
+
const specifiedHeight = opts.n !== undefined ? opts.n : sliceWidth;
|
|
36
|
+
const strict = opts.strict !== false;
|
|
37
|
+
if (strict) {
|
|
38
|
+
if (specifiedHeight !== targetHeight) {
|
|
39
|
+
throw new exceptions_1.ShapeError(`Column height mismatch: repeat length ${specifiedHeight} does not match DataFrame height ${targetHeight}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const pad = opts.pad ?? false;
|
|
44
|
+
const truncate = opts.truncate ?? false;
|
|
45
|
+
if (pad && !truncate) {
|
|
46
|
+
if (specifiedHeight > sliceWidth) {
|
|
47
|
+
throw new exceptions_1.ShapeError(`Cannot pad repeat output: specified length ${specifiedHeight} starting at index ${safeStart} exceeds slice width ${sliceWidth} (requires truncation).`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (truncate && !pad) {
|
|
51
|
+
if (specifiedHeight < sliceWidth) {
|
|
52
|
+
throw new exceptions_1.ShapeError(`Cannot truncate repeat output: specified length ${specifiedHeight} starting at index ${safeStart} is less than slice width ${sliceWidth} (requires padding).`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const finalHeight = targetHeight;
|
|
57
|
+
const result = new Array(finalHeight);
|
|
58
|
+
const repeatEnd = Math.min(safeStart + specifiedHeight, safeEnd);
|
|
59
|
+
const rawFill = opts.padValue !== undefined ? opts.padValue : null;
|
|
60
|
+
const coercedFill = opts.dtype ? opts.dtype.coerce(rawFill) : rawFill;
|
|
61
|
+
const hasDtype = !!opts.dtype;
|
|
62
|
+
const mode = opts.mode || "constant";
|
|
63
|
+
const step = opts.step !== undefined ? opts.step : 1;
|
|
64
|
+
// Fast-path optimization for simple constant lit/repeat operations
|
|
65
|
+
if (mode === "constant" && safeStart === 0 && repeatEnd === finalHeight && !opts.dtype) {
|
|
66
|
+
for (let i = 0; i < finalHeight; i++) {
|
|
67
|
+
result[i] = value;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
const seqVals = new Array(specifiedHeight);
|
|
72
|
+
if (specifiedHeight > 0) {
|
|
73
|
+
if (mode === "constant") {
|
|
74
|
+
const finalVal = opts.dtype ? opts.dtype.coerce(value) : value;
|
|
75
|
+
for (let idx = 0; idx < specifiedHeight; idx++) {
|
|
76
|
+
seqVals[idx] = finalVal;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (mode === "independent") {
|
|
80
|
+
if (typeof step === "function") {
|
|
81
|
+
for (let idx = 0; idx < specifiedHeight; idx++) {
|
|
82
|
+
const val = step(idx, value);
|
|
83
|
+
seqVals[idx] = hasDtype ? opts.dtype.coerce(val) : val;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
for (let idx = 0; idx < specifiedHeight; idx++) {
|
|
88
|
+
const val = value + idx * step;
|
|
89
|
+
seqVals[idx] = hasDtype ? opts.dtype.coerce(val) : val;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// cumulative mode
|
|
95
|
+
let current = value;
|
|
96
|
+
seqVals[0] = hasDtype ? opts.dtype.coerce(current) : current;
|
|
97
|
+
if (typeof step === "function") {
|
|
98
|
+
for (let idx = 1; idx < specifiedHeight; idx++) {
|
|
99
|
+
current = step(current, idx);
|
|
100
|
+
seqVals[idx] = hasDtype ? opts.dtype.coerce(current) : current;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
for (let idx = 1; idx < specifiedHeight; idx++) {
|
|
105
|
+
current = current + step;
|
|
106
|
+
seqVals[idx] = hasDtype ? opts.dtype.coerce(current) : current;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
for (let i = 0; i < finalHeight; i++) {
|
|
112
|
+
if (i >= safeStart && i < repeatEnd) {
|
|
113
|
+
result[i] = seqVals[i - safeStart];
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
result[i] = coercedFill;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
});
|
|
121
|
+
return expr;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates a column expression that generates a sequence of values starting from the given start value.
|
|
125
|
+
*/
|
|
126
|
+
function seq_range(start, options = { strict: true }) {
|
|
127
|
+
return repeat(start, {
|
|
128
|
+
...options,
|
|
129
|
+
mode: options.mode || "cumulative"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ColumnExpr } from "../ColumnExpr";
|
|
2
|
+
import type { RegisteredDataType } from "../../types";
|
|
3
|
+
import { CumulativeStepContext, IndependentStepContext } from "../../utils";
|
|
4
|
+
export type SeqRangeOptions = {
|
|
5
|
+
n?: number;
|
|
6
|
+
dtype?: RegisteredDataType;
|
|
7
|
+
name?: string;
|
|
8
|
+
} & ({
|
|
9
|
+
mode: "constant";
|
|
10
|
+
} | {
|
|
11
|
+
mode?: "cumulative";
|
|
12
|
+
step?: number | ((context: CumulativeStepContext) => any);
|
|
13
|
+
} | {
|
|
14
|
+
mode: "independent";
|
|
15
|
+
step?: number | ((context: IndependentStepContext) => any);
|
|
16
|
+
}) & ({
|
|
17
|
+
strict?: true;
|
|
18
|
+
} | {
|
|
19
|
+
strict: false;
|
|
20
|
+
pad?: boolean;
|
|
21
|
+
truncate?: boolean;
|
|
22
|
+
padValue?: any;
|
|
23
|
+
startIndex?: number;
|
|
24
|
+
endIndex?: number;
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Creates a column expression that generates a range of values.
|
|
28
|
+
* If mode is "cumulative" (default) or "independent", it generates a sequence.
|
|
29
|
+
* If mode is "constant", it repeats the given value.
|
|
30
|
+
*/
|
|
31
|
+
export declare function seq_range(value: any, options?: SeqRangeOptions): ColumnExpr<any>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.seq_range = seq_range;
|
|
4
|
+
const ColumnExpr_1 = require("../ColumnExpr");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
const exceptions_1 = require("../../exceptions");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
/**
|
|
9
|
+
* Creates a column expression that generates a range of values.
|
|
10
|
+
* If mode is "cumulative" (default) or "independent", it generates a sequence.
|
|
11
|
+
* If mode is "constant", it repeats the given value.
|
|
12
|
+
*/
|
|
13
|
+
function seq_range(value, options = { strict: true }) {
|
|
14
|
+
const opts = options;
|
|
15
|
+
const expr = new ColumnExpr_1.ColumnExpr(constants_1.LITERAL_MARKER);
|
|
16
|
+
expr.literalValue = value;
|
|
17
|
+
if (opts.name) {
|
|
18
|
+
expr.outputName = opts.name;
|
|
19
|
+
}
|
|
20
|
+
expr.ops.push((vArray) => {
|
|
21
|
+
const targetHeight = vArray.length;
|
|
22
|
+
const getIdx = (val, def) => {
|
|
23
|
+
if (val === undefined)
|
|
24
|
+
return def;
|
|
25
|
+
return (0, utils_1.clamp)(val < 0 ? targetHeight + val : val, { min: 0, max: targetHeight });
|
|
26
|
+
};
|
|
27
|
+
const safeStart = getIdx(opts.startIndex, 0);
|
|
28
|
+
const safeEnd = getIdx(opts.endIndex, targetHeight);
|
|
29
|
+
const sliceWidth = Math.max(0, safeEnd - safeStart);
|
|
30
|
+
const specifiedHeight = opts.n !== undefined ? opts.n : sliceWidth;
|
|
31
|
+
const strict = opts.strict !== false;
|
|
32
|
+
if (strict) {
|
|
33
|
+
if (specifiedHeight !== targetHeight) {
|
|
34
|
+
throw new exceptions_1.ShapeError(`Column height mismatch: seq_range length ${specifiedHeight} does not match DataFrame height ${targetHeight}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const pad = opts.pad ?? false;
|
|
39
|
+
const truncate = opts.truncate ?? false;
|
|
40
|
+
if (pad && !truncate && specifiedHeight > sliceWidth) {
|
|
41
|
+
throw new exceptions_1.ShapeError(`Cannot pad seq_range output: specified length ${specifiedHeight} starting at index ${safeStart} exceeds slice width ${sliceWidth} (requires truncation).`);
|
|
42
|
+
}
|
|
43
|
+
if (truncate && !pad && specifiedHeight < sliceWidth) {
|
|
44
|
+
throw new exceptions_1.ShapeError(`Cannot truncate seq_range output: specified length ${specifiedHeight} starting at index ${safeStart} is less than slice width ${sliceWidth} (requires padding).`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const finalHeight = targetHeight;
|
|
48
|
+
const hasDtype = !!opts.dtype;
|
|
49
|
+
const mode = opts.mode || "cumulative";
|
|
50
|
+
const step = opts.step !== undefined ? opts.step : 1;
|
|
51
|
+
const coerceVal = hasDtype
|
|
52
|
+
? (val) => opts.dtype.coerce(val)
|
|
53
|
+
: (val) => val;
|
|
54
|
+
if (strict) {
|
|
55
|
+
const result = opts.dtype?.allocate
|
|
56
|
+
? opts.dtype.allocate(finalHeight)
|
|
57
|
+
: new Array(finalHeight);
|
|
58
|
+
(0, utils_1.fillSequence)(result, value, {
|
|
59
|
+
mode,
|
|
60
|
+
step,
|
|
61
|
+
coerce: coerceVal,
|
|
62
|
+
startIndex: 0,
|
|
63
|
+
endIndex: finalHeight
|
|
64
|
+
});
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
// Non-strict mode path:
|
|
68
|
+
const repeatEnd = Math.min(safeStart + specifiedHeight, safeEnd);
|
|
69
|
+
const rawFill = opts.padValue !== undefined ? opts.padValue : null;
|
|
70
|
+
const coercedFill = coerceVal(rawFill);
|
|
71
|
+
// Fast-path optimization for simple constant lit/repeat operations
|
|
72
|
+
if (mode === "constant" && safeStart === 0 && repeatEnd === finalHeight && !opts.dtype) {
|
|
73
|
+
const result = new Array(finalHeight);
|
|
74
|
+
for (let i = 0; i < finalHeight; i++) {
|
|
75
|
+
result[i] = value;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
const result = new Array(finalHeight);
|
|
80
|
+
result.fill(coercedFill);
|
|
81
|
+
(0, utils_1.fillSequence)(result, value, {
|
|
82
|
+
mode,
|
|
83
|
+
step,
|
|
84
|
+
coerce: coerceVal,
|
|
85
|
+
startIndex: safeStart,
|
|
86
|
+
endIndex: repeatEnd
|
|
87
|
+
});
|
|
88
|
+
return result;
|
|
89
|
+
});
|
|
90
|
+
return expr;
|
|
91
|
+
}
|
|
@@ -38,7 +38,7 @@ class WhenThen extends ColumnExpr_1.ColumnExpr {
|
|
|
38
38
|
this.ops.push((_, columns) => {
|
|
39
39
|
const height = _.length;
|
|
40
40
|
const evaluateArg = (arg) => {
|
|
41
|
-
if (arg
|
|
41
|
+
if (ColumnExpr_1.ColumnExpr.isColExpr(arg)) {
|
|
42
42
|
return arg.evaluate(columns, height);
|
|
43
43
|
}
|
|
44
44
|
if (typeof arg === "string" && (arg in columns)) {
|
|
@@ -46,11 +46,15 @@ class WhenThen extends ColumnExpr_1.ColumnExpr {
|
|
|
46
46
|
}
|
|
47
47
|
return arg;
|
|
48
48
|
};
|
|
49
|
-
const
|
|
50
|
-
const
|
|
49
|
+
const numConditions = this.predicates.length;
|
|
50
|
+
const evaluatedPreds = new Array(numConditions);
|
|
51
|
+
const evaluatedVals = new Array(numConditions);
|
|
52
|
+
for (let j = 0; j < numConditions; j++) {
|
|
53
|
+
evaluatedPreds[j] = evaluateArg(this.predicates[j]);
|
|
54
|
+
evaluatedVals[j] = evaluateArg(this.values[j]);
|
|
55
|
+
}
|
|
51
56
|
const evaluatedOtherwise = evaluateArg(this.otherwiseValue);
|
|
52
57
|
const result = new Array(height);
|
|
53
|
-
const numConditions = evaluatedPreds.length;
|
|
54
58
|
for (let i = 0; i < height; i++) {
|
|
55
59
|
let matched = false;
|
|
56
60
|
for (let j = 0; j < numConditions; j++) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { IExpr } from "../types";
|
|
2
1
|
export * from "./constants";
|
|
3
2
|
export * from "./types";
|
|
4
3
|
export * from "./ExprBase";
|
|
@@ -10,10 +9,14 @@ export * from "./mixins/AggregationExpr";
|
|
|
10
9
|
export * from "./mixins/WindowExpr";
|
|
11
10
|
export * from "./mixins/TemporalExpr";
|
|
12
11
|
export * from "./mixins/ListExpr";
|
|
12
|
+
export * from "./mixins/StructExpr";
|
|
13
13
|
export * from "./ColumnExpr";
|
|
14
14
|
export * from "./functions/lit";
|
|
15
15
|
export * from "./functions/all";
|
|
16
16
|
export * from "./functions/exclude";
|
|
17
17
|
export * from "./functions/coalesce";
|
|
18
18
|
export * from "./functions/when";
|
|
19
|
-
export
|
|
19
|
+
export * from "./functions/implode";
|
|
20
|
+
export * from "./functions/seq_range";
|
|
21
|
+
export * from "./functions/element";
|
|
22
|
+
export * from "./utils";
|