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.
Files changed (95) hide show
  1. package/README.md +83 -34
  2. package/dist/api.d.ts +16 -8
  3. package/dist/api.js +11 -3
  4. package/dist/columnExpressions/ColumnExpr.d.ts +26 -364
  5. package/dist/columnExpressions/ColumnExpr.js +199 -3
  6. package/dist/columnExpressions/ExprBase.d.ts +8 -11
  7. package/dist/columnExpressions/ExprBase.js +20 -61
  8. package/dist/columnExpressions/constants.d.ts +2 -0
  9. package/dist/columnExpressions/constants.js +3 -1
  10. package/dist/columnExpressions/functions/coalesce.js +8 -4
  11. package/dist/columnExpressions/functions/element.d.ts +5 -0
  12. package/dist/columnExpressions/functions/element.js +11 -0
  13. package/dist/columnExpressions/functions/implode.d.ts +3 -0
  14. package/dist/columnExpressions/functions/implode.js +7 -0
  15. package/dist/columnExpressions/functions/lit.d.ts +3 -1
  16. package/dist/columnExpressions/functions/lit.js +8 -13
  17. package/dist/columnExpressions/functions/repeat.d.ts +47 -0
  18. package/dist/columnExpressions/functions/repeat.js +131 -0
  19. package/dist/columnExpressions/functions/seq_range.d.ts +31 -0
  20. package/dist/columnExpressions/functions/seq_range.js +91 -0
  21. package/dist/columnExpressions/functions/when.js +8 -4
  22. package/dist/columnExpressions/index.d.ts +5 -2
  23. package/dist/columnExpressions/index.js +5 -48
  24. package/dist/columnExpressions/mixins/AggregationExpr.d.ts +25 -50
  25. package/dist/columnExpressions/mixins/AggregationExpr.js +69 -165
  26. package/dist/columnExpressions/mixins/ArithmeticExpr.d.ts +41 -66
  27. package/dist/columnExpressions/mixins/ArithmeticExpr.js +126 -138
  28. package/dist/columnExpressions/mixins/BooleanExpr.d.ts +40 -0
  29. package/dist/columnExpressions/mixins/BooleanExpr.js +67 -0
  30. package/dist/columnExpressions/mixins/ComparisonExpr.d.ts +31 -60
  31. package/dist/columnExpressions/mixins/ComparisonExpr.js +231 -370
  32. package/dist/columnExpressions/mixins/ListExpr.d.ts +15 -39
  33. package/dist/columnExpressions/mixins/ListExpr.js +124 -148
  34. package/dist/columnExpressions/mixins/LogicalExpr.d.ts +7 -33
  35. package/dist/columnExpressions/mixins/LogicalExpr.js +48 -49
  36. package/dist/columnExpressions/mixins/ManipulationExpr.d.ts +6 -31
  37. package/dist/columnExpressions/mixins/ManipulationExpr.js +61 -25
  38. package/dist/columnExpressions/mixins/NumericExpr.d.ts +92 -0
  39. package/dist/columnExpressions/mixins/NumericExpr.js +259 -0
  40. package/dist/columnExpressions/mixins/StringExpr.d.ts +5 -30
  41. package/dist/columnExpressions/mixins/StringExpr.js +37 -49
  42. package/dist/columnExpressions/mixins/StructExpr.d.ts +16 -0
  43. package/dist/columnExpressions/mixins/StructExpr.js +139 -0
  44. package/dist/columnExpressions/mixins/TemporalExpr.d.ts +4 -30
  45. package/dist/columnExpressions/mixins/TemporalExpr.js +28 -29
  46. package/dist/columnExpressions/mixins/WindowExpr.d.ts +27 -49
  47. package/dist/columnExpressions/mixins/WindowExpr.js +144 -274
  48. package/dist/columnExpressions/utils.d.ts +4 -0
  49. package/dist/columnExpressions/utils.js +45 -0
  50. package/dist/dataframe/constants.d.ts +3 -0
  51. package/dist/dataframe/constants.js +4 -1
  52. package/dist/dataframe/dataframe.d.ts +27 -10
  53. package/dist/dataframe/dataframe.js +461 -220
  54. package/dist/dataframe/grouped/grouped.d.ts +2 -3
  55. package/dist/dataframe/grouped/grouped.js +17 -16
  56. package/dist/dataframe/types.d.ts +65 -1
  57. package/dist/dataframe/utils.d.ts +11 -3
  58. package/dist/dataframe/utils.js +101 -9
  59. package/dist/datatypes/DataType.d.ts +2 -1
  60. package/dist/datatypes/DataType.js +29 -0
  61. package/dist/datatypes/index.d.ts +2 -2
  62. package/dist/datatypes/types.d.ts +37 -36
  63. package/dist/datatypes/types.js +15 -11
  64. package/dist/exceptions/index.d.ts +2 -0
  65. package/dist/exceptions/index.js +4 -1
  66. package/dist/exceptions/utils.d.ts +1 -0
  67. package/dist/exceptions/utils.js +19 -0
  68. package/dist/functions/concat.d.ts +1 -2
  69. package/dist/functions/concat.js +24 -12
  70. package/dist/functions/index.d.ts +3 -1
  71. package/dist/functions/index.js +7 -15
  72. package/dist/functions/read_csv.d.ts +8 -0
  73. package/dist/functions/read_csv.js +53 -0
  74. package/dist/functions/read_json.d.ts +10 -0
  75. package/dist/functions/read_json.js +21 -0
  76. package/dist/functions/transpose.d.ts +7 -0
  77. package/dist/functions/transpose.js +84 -0
  78. package/dist/index.js +6 -1
  79. package/dist/types.d.ts +31 -5
  80. package/dist/utils/csv.d.ts +77 -0
  81. package/dist/utils/csv.js +313 -0
  82. package/dist/utils/date.js +5 -6
  83. package/dist/utils/guards.d.ts +0 -2
  84. package/dist/utils/guards.js +0 -31
  85. package/dist/utils/index.d.ts +2 -0
  86. package/dist/utils/index.js +2 -0
  87. package/dist/utils/json.d.ts +120 -2
  88. package/dist/utils/json.js +204 -20
  89. package/dist/utils/list.d.ts +173 -1
  90. package/dist/utils/list.js +255 -22
  91. package/dist/utils/number.d.ts +61 -28
  92. package/dist/utils/number.js +248 -70
  93. package/dist/utils/string.d.ts +5 -0
  94. package/dist/utils/string.js +89 -0
  95. 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 = exports.kleeneBinary = exports.kleeneUnary = void 0;
4
- const utils_1 = require("../utils");
3
+ exports.ExprBase = exports.derive = void 0;
5
4
  const constants_1 = require("./constants");
6
- const kleeneUnary = (fn) => {
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 newInst = new Constructor(instance.colName || "");
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 && typeof val === "object" && "evaluate" in 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 Constructor = this.constructor;
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
- evaluate(columns, height) {
55
+ _getInitialValue(columns, height) {
88
56
  const name = this.colName;
89
- let value = name && name !== constants_1.ALL_COLUMNS_MARKER
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
- _evaluatePre(opsIndex, columns, height) {
100
- const name = this.colName;
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
- _evaluatePost(opsIndex, aggregatedArray, columns) {
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,2 +1,4 @@
1
1
  export declare const ALL_COLUMNS_MARKER = "*";
2
2
  export declare const LITERAL_MARKER = "*literal*";
3
+ export declare const COALESCE_MARKER = "*coalesce*";
4
+ export declare const ELEMENT_MARKER = "*element*";
@@ -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("*coalesce*");
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 && typeof arg === "object" && "evaluate" in 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 evaluatedArrays = rawArgs.map(evaluateArg);
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,5 @@
1
+ import { ColumnExpr } from "../ColumnExpr";
2
+ /**
3
+ * Creates an expression referencing the current element(s) of a list during evaluation.
4
+ */
5
+ export declare function element<T = any>(): ColumnExpr<T>;
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ import { ColumnExpr } from "../ColumnExpr";
2
+ import type { IntoExpr } from "../../types";
3
+ export declare function implode(column: IntoExpr | IntoExpr[]): ColumnExpr<any>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.implode = implode;
4
+ const ColumnExpr_1 = require("../ColumnExpr");
5
+ function implode(column) {
6
+ return ColumnExpr_1.ColumnExpr.toColExpr(column).implode();
7
+ }
@@ -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 ColumnExpr_1 = require("../ColumnExpr");
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 = new ColumnExpr_1.ColumnExpr(constants_1.LITERAL_MARKER);
11
- expr.isLiteral = true;
12
- expr.literalValue = value;
13
- expr.ops.push((vArray) => {
14
- const height = vArray.length;
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 && typeof arg === "object" && "evaluate" in 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 evaluatedPreds = this.predicates.map(evaluateArg);
50
- const evaluatedVals = this.values.map(evaluateArg);
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 declare function resolveColumnSelectors(exprs: any[], allKeys: string[], keysToExcludeFromAll?: string[]): IExpr[];
19
+ export * from "./functions/implode";
20
+ export * from "./functions/seq_range";
21
+ export * from "./functions/element";
22
+ export * from "./utils";