df-script 1.5.0 → 1.6.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 +124 -8
- package/dist/api.d.ts +1 -1
- package/dist/columnExpressions/ColumnExpr.d.ts +2 -2
- package/dist/columnExpressions/functions/coalesce.d.ts +2 -2
- package/dist/columnExpressions/functions/element.d.ts +1 -1
- package/dist/columnExpressions/functions/when.d.ts +2 -2
- package/dist/columnExpressions/index.d.ts +1 -1
- package/dist/columnExpressions/mixins/AggregationExpr.d.ts +2 -2
- package/dist/columnExpressions/mixins/ArithmeticExpr.d.ts +11 -10
- package/dist/columnExpressions/mixins/ArrayExpr.d.ts +39 -0
- package/dist/columnExpressions/mixins/ListExpr.d.ts +2 -2
- package/dist/columnExpressions/mixins/StringExpr.d.ts +2 -2
- package/dist/columnExpressions/types.d.ts +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/dataframe/dataframe.d.ts +1 -1
- package/dist/datatypes/index.d.ts +3 -2
- package/dist/datatypes/types.d.ts +7 -7
- package/dist/index.js +6 -6
- package/dist/types.d.ts +4 -2
- package/dist/utils/array.d.ts +217 -0
- package/dist/utils/binary.d.ts +3 -0
- package/dist/utils/date.d.ts +21 -35
- package/dist/utils/guards.d.ts +11 -10
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/list.d.ts +23 -1
- package/dist/utils/number.d.ts +14 -29
- package/dist/utils/object.d.ts +26 -0
- package/dist/utils/string.d.ts +3 -5
- package/package.json +2 -2
- package/dist/api.js +0 -26
- package/dist/bundle.min.js +0 -1
- package/dist/columnExpressions/ColumnExpr.js +0 -219
- package/dist/columnExpressions/ExprBase.js +0 -92
- package/dist/columnExpressions/constants.js +0 -7
- package/dist/columnExpressions/functions/all.js +0 -11
- package/dist/columnExpressions/functions/coalesce.js +0 -44
- package/dist/columnExpressions/functions/element.js +0 -11
- package/dist/columnExpressions/functions/exclude.js +0 -13
- package/dist/columnExpressions/functions/implode.js +0 -7
- package/dist/columnExpressions/functions/lit.js +0 -17
- package/dist/columnExpressions/functions/repeat.d.ts +0 -47
- package/dist/columnExpressions/functions/repeat.js +0 -131
- package/dist/columnExpressions/functions/seq_range.js +0 -91
- package/dist/columnExpressions/functions/when.js +0 -85
- package/dist/columnExpressions/index.js +0 -38
- package/dist/columnExpressions/mixins/AggregationExpr.js +0 -76
- package/dist/columnExpressions/mixins/ArithmeticExpr.js +0 -131
- package/dist/columnExpressions/mixins/BooleanExpr.d.ts +0 -40
- package/dist/columnExpressions/mixins/BooleanExpr.js +0 -67
- package/dist/columnExpressions/mixins/ComparisonExpr.js +0 -250
- package/dist/columnExpressions/mixins/ListExpr.js +0 -224
- package/dist/columnExpressions/mixins/LogicalExpr.js +0 -53
- package/dist/columnExpressions/mixins/ManipulationExpr.js +0 -71
- package/dist/columnExpressions/mixins/NumericExpr.d.ts +0 -92
- package/dist/columnExpressions/mixins/NumericExpr.js +0 -259
- package/dist/columnExpressions/mixins/StringExpr.js +0 -237
- package/dist/columnExpressions/mixins/StructExpr.js +0 -139
- package/dist/columnExpressions/mixins/TemporalExpr.js +0 -126
- package/dist/columnExpressions/mixins/WindowExpr.js +0 -151
- package/dist/columnExpressions/types.js +0 -2
- package/dist/columnExpressions/utils.js +0 -45
- package/dist/dataframe/constants.js +0 -7
- package/dist/dataframe/dataframe.js +0 -990
- package/dist/dataframe/grouped/grouped.js +0 -114
- package/dist/dataframe/index.js +0 -20
- package/dist/dataframe/types.js +0 -2
- package/dist/dataframe/utils.js +0 -307
- package/dist/datatypes/DataType.js +0 -76
- package/dist/datatypes/index.js +0 -46
- package/dist/datatypes/types/Binary.d.ts +0 -9
- package/dist/datatypes/types/Binary.js +0 -18
- package/dist/datatypes/types/Boolean.d.ts +0 -9
- package/dist/datatypes/types/Boolean.js +0 -19
- package/dist/datatypes/types/Date.d.ts +0 -8
- package/dist/datatypes/types/Date.js +0 -21
- package/dist/datatypes/types/Datetime.d.ts +0 -8
- package/dist/datatypes/types/Datetime.js +0 -17
- package/dist/datatypes/types/Decimal.d.ts +0 -10
- package/dist/datatypes/types/Decimal.js +0 -28
- package/dist/datatypes/types/Duration.d.ts +0 -8
- package/dist/datatypes/types/Duration.js +0 -17
- package/dist/datatypes/types/Float32.d.ts +0 -8
- package/dist/datatypes/types/Float32.js +0 -17
- package/dist/datatypes/types/Float64.d.ts +0 -8
- package/dist/datatypes/types/Float64.js +0 -17
- package/dist/datatypes/types/Int16.d.ts +0 -8
- package/dist/datatypes/types/Int16.js +0 -17
- package/dist/datatypes/types/Int32.d.ts +0 -8
- package/dist/datatypes/types/Int32.js +0 -17
- package/dist/datatypes/types/Int64.d.ts +0 -8
- package/dist/datatypes/types/Int64.js +0 -17
- package/dist/datatypes/types/Int8.d.ts +0 -8
- package/dist/datatypes/types/Int8.js +0 -17
- package/dist/datatypes/types/List.d.ts +0 -10
- package/dist/datatypes/types/List.js +0 -31
- package/dist/datatypes/types/Null.d.ts +0 -9
- package/dist/datatypes/types/Null.js +0 -17
- package/dist/datatypes/types/Object.d.ts +0 -9
- package/dist/datatypes/types/Object.js +0 -17
- package/dist/datatypes/types/Struct.d.ts +0 -14
- package/dist/datatypes/types/Struct.js +0 -39
- package/dist/datatypes/types/Time.d.ts +0 -8
- package/dist/datatypes/types/Time.js +0 -29
- package/dist/datatypes/types/UInt16.d.ts +0 -8
- package/dist/datatypes/types/UInt16.js +0 -17
- package/dist/datatypes/types/UInt32.d.ts +0 -8
- package/dist/datatypes/types/UInt32.js +0 -17
- package/dist/datatypes/types/UInt64.d.ts +0 -8
- package/dist/datatypes/types/UInt64.js +0 -17
- package/dist/datatypes/types/UInt8.d.ts +0 -8
- package/dist/datatypes/types/UInt8.js +0 -17
- package/dist/datatypes/types/Utf8.d.ts +0 -10
- package/dist/datatypes/types/Utf8.js +0 -20
- package/dist/datatypes/types.js +0 -290
- package/dist/exceptions/index.js +0 -46
- package/dist/exceptions/utils.js +0 -28
- package/dist/functions/concat.js +0 -260
- package/dist/functions/index.js +0 -9
- package/dist/functions/read_csv.js +0 -53
- package/dist/functions/read_json.js +0 -21
- package/dist/functions/transpose.d.ts +0 -7
- package/dist/functions/transpose.js +0 -84
- package/dist/types.js +0 -2
- package/dist/utils/boolean.d.ts +0 -1
- package/dist/utils/boolean.js +0 -18
- package/dist/utils/csv.js +0 -313
- package/dist/utils/date.js +0 -348
- package/dist/utils/guards.js +0 -112
- package/dist/utils/index.js +0 -23
- package/dist/utils/json.js +0 -217
- package/dist/utils/list.js +0 -361
- package/dist/utils/number.js +0 -401
- package/dist/utils/string.js +0 -209
|
@@ -1,990 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataFrame = void 0;
|
|
4
|
-
const columnExpressions_1 = require("../columnExpressions");
|
|
5
|
-
const grouped_1 = require("./grouped/grouped");
|
|
6
|
-
const constants_1 = require("./constants");
|
|
7
|
-
const json_1 = require("../utils/json");
|
|
8
|
-
const datatypes_1 = require("../datatypes");
|
|
9
|
-
const utils_1 = require("../utils");
|
|
10
|
-
const exceptions_1 = require("../exceptions");
|
|
11
|
-
const concat_1 = require("../functions/concat");
|
|
12
|
-
const utils_2 = require("./utils");
|
|
13
|
-
class DataFrame {
|
|
14
|
-
_columns;
|
|
15
|
-
_height;
|
|
16
|
-
_schema = {};
|
|
17
|
-
static _createDirect(columns, schema, height) {
|
|
18
|
-
(0, exceptions_1.assertHeight)(columns, height);
|
|
19
|
-
const df = Object.create(DataFrame.prototype);
|
|
20
|
-
df._columns = columns;
|
|
21
|
-
df._schema = schema;
|
|
22
|
-
df._height = height;
|
|
23
|
-
return df;
|
|
24
|
-
}
|
|
25
|
-
constructor(data, schema, height) {
|
|
26
|
-
if (Array.isArray(data)) {
|
|
27
|
-
const { columns, height: h } = (0, utils_2.rowsToColumns)(data);
|
|
28
|
-
this._columns = columns;
|
|
29
|
-
this._height = h;
|
|
30
|
-
schema ? this.applySchema(schema) : this.inferSchema();
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if ((0, utils_1.isObj)(data)) {
|
|
34
|
-
this._columns = data;
|
|
35
|
-
this._height = (0, exceptions_1.assertHeight)(data, height);
|
|
36
|
-
schema ? this.applySchema(schema) : this.inferSchema();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
this._columns = {};
|
|
40
|
-
this._height = 0;
|
|
41
|
-
schema ? this.applySchema(schema) : (this._schema = {});
|
|
42
|
-
}
|
|
43
|
-
inferSchema() {
|
|
44
|
-
const schema = {};
|
|
45
|
-
const keys = Object.keys(this._columns);
|
|
46
|
-
const numKeys = keys.length;
|
|
47
|
-
for (let i = 0; i < numKeys; i++) {
|
|
48
|
-
const key = keys[i];
|
|
49
|
-
schema[key] = (0, utils_2.inferColumnType)(this._columns[key]);
|
|
50
|
-
}
|
|
51
|
-
this.applySchema(schema);
|
|
52
|
-
}
|
|
53
|
-
applySchema(schema) {
|
|
54
|
-
this._schema = schema;
|
|
55
|
-
const keys = Object.keys(schema);
|
|
56
|
-
const newColumns = {};
|
|
57
|
-
for (const key of keys) {
|
|
58
|
-
const type = schema[key];
|
|
59
|
-
const oldCol = this._columns[key];
|
|
60
|
-
newColumns[key] = oldCol
|
|
61
|
-
? (0, utils_2.coerceColumn)(oldCol, type, this._height)
|
|
62
|
-
: (0, utils_2.coerceColumn)(new Array(this._height).fill(null), type, this._height);
|
|
63
|
-
}
|
|
64
|
-
this._columns = newColumns;
|
|
65
|
-
}
|
|
66
|
-
get columns() {
|
|
67
|
-
return Object.keys(this._columns);
|
|
68
|
-
}
|
|
69
|
-
concat(items, options = {}) {
|
|
70
|
-
const arrayItems = (0, utils_1.isArrayOfType)(items, DataFrame, { mode: "every", allowEmpty: false })
|
|
71
|
-
? items
|
|
72
|
-
: [items];
|
|
73
|
-
return (0, concat_1.concat)([this, ...arrayItems], options);
|
|
74
|
-
}
|
|
75
|
-
drop(...args) {
|
|
76
|
-
const columnsToDrop = new Set(args.flat());
|
|
77
|
-
const newColumns = {};
|
|
78
|
-
const outSchema = {};
|
|
79
|
-
for (const key of Object.keys(this._columns)) {
|
|
80
|
-
if (!columnsToDrop.has(key)) {
|
|
81
|
-
newColumns[key] = this._columns[key];
|
|
82
|
-
outSchema[key] = this._schema[key];
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return DataFrame._createDirect(newColumns, outSchema, this._height);
|
|
86
|
-
}
|
|
87
|
-
drop_nulls(subset) {
|
|
88
|
-
if (this._height === 0)
|
|
89
|
-
return this;
|
|
90
|
-
return this.filter(subset ? new columnExpressions_1.ColumnExpr(subset).is_not_null() : (0, columnExpressions_1.all)().is_not_null());
|
|
91
|
-
}
|
|
92
|
-
get dtypes() {
|
|
93
|
-
const keys = Object.keys(this._columns);
|
|
94
|
-
const len = keys.length;
|
|
95
|
-
const result = new Array(len);
|
|
96
|
-
for (let i = 0; i < len; i++) {
|
|
97
|
-
result[i] = this._schema[keys[i]];
|
|
98
|
-
}
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
explode(columns, options) {
|
|
102
|
-
const expr = columnExpressions_1.ColumnExpr.toColExpr(columns);
|
|
103
|
-
const colNames = expr.colNames || [expr.colName || expr.outputName];
|
|
104
|
-
const colsToExplode = new Set();
|
|
105
|
-
const numCols = colNames.length;
|
|
106
|
-
for (let i = 0; i < numCols; i++) {
|
|
107
|
-
const name = colNames[i];
|
|
108
|
-
if (!name) {
|
|
109
|
-
throw new exceptions_1.DataFrameError("Expression passed to explode must have a column name.");
|
|
110
|
-
}
|
|
111
|
-
(0, exceptions_1.assertColumnExists)(name, this._columns, "Explode column");
|
|
112
|
-
colsToExplode.add(name);
|
|
113
|
-
}
|
|
114
|
-
const keys = Object.keys(this._columns);
|
|
115
|
-
const selectList = [];
|
|
116
|
-
const numKeys = keys.length;
|
|
117
|
-
for (let i = 0; i < numKeys; i++) {
|
|
118
|
-
const key = keys[i];
|
|
119
|
-
selectList.push(colsToExplode.has(key)
|
|
120
|
-
? new columnExpressions_1.ColumnExpr(key).list.explode(options)
|
|
121
|
-
: new columnExpressions_1.ColumnExpr(key));
|
|
122
|
-
}
|
|
123
|
-
return this.select(...selectList);
|
|
124
|
-
}
|
|
125
|
-
fill_null(options = {}) {
|
|
126
|
-
if (this._height === 0)
|
|
127
|
-
return this;
|
|
128
|
-
return this.with_columns((0, columnExpressions_1.all)().fill_null(options));
|
|
129
|
-
}
|
|
130
|
-
filter(...exprs) {
|
|
131
|
-
if (this._height === 0)
|
|
132
|
-
return DataFrame._createDirect({}, this._schema, 0);
|
|
133
|
-
const height = this._height;
|
|
134
|
-
const keys = Object.keys(this._columns);
|
|
135
|
-
const numKeys = keys.length;
|
|
136
|
-
const evaluatedExprs = [];
|
|
137
|
-
const funcPredicates = [];
|
|
138
|
-
const exprSelectors = [];
|
|
139
|
-
const numExprs = exprs.length;
|
|
140
|
-
for (let i = 0; i < numExprs; i++) {
|
|
141
|
-
const expr = exprs[i];
|
|
142
|
-
if (typeof expr === "function") {
|
|
143
|
-
funcPredicates.push(expr);
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
exprSelectors.push(expr);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const expandedExprs = (0, columnExpressions_1.resolveColumnSelectors)(exprSelectors, keys, undefined, this._schema, this._columns);
|
|
150
|
-
const numExpanded = expandedExprs.length;
|
|
151
|
-
for (let i = 0; i < numExpanded; i++) {
|
|
152
|
-
evaluatedExprs.push(expandedExprs[i].evaluate(this._columns, height));
|
|
153
|
-
}
|
|
154
|
-
const matchingIndices = [];
|
|
155
|
-
let currentIndex = 0;
|
|
156
|
-
let rowObj = null;
|
|
157
|
-
if (funcPredicates.length > 0) {
|
|
158
|
-
const columns = this._columns;
|
|
159
|
-
rowObj = {};
|
|
160
|
-
for (let k = 0; k < numKeys; k++) {
|
|
161
|
-
const key = keys[k];
|
|
162
|
-
const col = columns[key];
|
|
163
|
-
Object.defineProperty(rowObj, key, {
|
|
164
|
-
get() {
|
|
165
|
-
const val = col[currentIndex];
|
|
166
|
-
return val === undefined ? null : val;
|
|
167
|
-
},
|
|
168
|
-
enumerable: true,
|
|
169
|
-
configurable: true
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
for (let i = 0; i < height; i++) {
|
|
174
|
-
let keep = true;
|
|
175
|
-
for (let j = 0; j < evaluatedExprs.length; j++) {
|
|
176
|
-
if (!evaluatedExprs[j][i]) {
|
|
177
|
-
keep = false;
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (!keep)
|
|
182
|
-
continue;
|
|
183
|
-
if (rowObj) {
|
|
184
|
-
currentIndex = i;
|
|
185
|
-
for (let j = 0; j < funcPredicates.length; j++) {
|
|
186
|
-
if (!funcPredicates[j](rowObj)) {
|
|
187
|
-
keep = false;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (!keep)
|
|
193
|
-
continue;
|
|
194
|
-
matchingIndices.push(i);
|
|
195
|
-
}
|
|
196
|
-
const newColumns = (0, utils_2.gatherColumnsByIndices)(this._columns, matchingIndices);
|
|
197
|
-
const newHeight = matchingIndices.length;
|
|
198
|
-
return DataFrame._createDirect(newColumns, this._schema, newHeight);
|
|
199
|
-
}
|
|
200
|
-
get_schema() {
|
|
201
|
-
return this._schema;
|
|
202
|
-
}
|
|
203
|
-
groupby(keys) {
|
|
204
|
-
const keysArr = (0, utils_1.toValidArray)(keys);
|
|
205
|
-
const groups = new Map();
|
|
206
|
-
const len = this._height;
|
|
207
|
-
const keysStr = (0, utils_1.toValidStringArray)(keys);
|
|
208
|
-
for (let j = 0; j < keysStr.length; j++) {
|
|
209
|
-
(0, exceptions_1.assertColumnExists)(keysStr[j], this._columns, "Grouping key");
|
|
210
|
-
}
|
|
211
|
-
for (let i = 0; i < len; i++) {
|
|
212
|
-
const hash = (0, utils_2.computeRowHash)(this._columns, keysStr, i);
|
|
213
|
-
let group = groups.get(hash);
|
|
214
|
-
if (group === undefined) {
|
|
215
|
-
groups.set(hash, group = []);
|
|
216
|
-
}
|
|
217
|
-
group.push(i);
|
|
218
|
-
}
|
|
219
|
-
const allKeys = Object.keys(this._columns);
|
|
220
|
-
return new grouped_1.GroupedData(groups, keysArr, allKeys, this._columns, this._height, this._schema);
|
|
221
|
-
}
|
|
222
|
-
head(n = 10) {
|
|
223
|
-
return this.limit(n, { offset: 0, from: "start" });
|
|
224
|
-
}
|
|
225
|
-
get height() {
|
|
226
|
-
return this._height;
|
|
227
|
-
}
|
|
228
|
-
hstack(other, options = {}) {
|
|
229
|
-
return this.concat(other, { how: "horizontal", horizontal: options });
|
|
230
|
-
}
|
|
231
|
-
insert_column(index, name, expr) {
|
|
232
|
-
const colExpr = columnExpressions_1.ColumnExpr.toColExpr(expr).alias(name);
|
|
233
|
-
const keys = Object.keys(this._columns);
|
|
234
|
-
const keysLen = keys.length;
|
|
235
|
-
const selectList = [];
|
|
236
|
-
for (let i = 0; i < keysLen; i++) {
|
|
237
|
-
const k = keys[i];
|
|
238
|
-
if (k !== name) {
|
|
239
|
-
selectList.push(k);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
const targetIndex = Math.max(0, Math.min(index, selectList.length));
|
|
243
|
-
selectList.splice(targetIndex, 0, colExpr);
|
|
244
|
-
return this.select(...selectList);
|
|
245
|
-
}
|
|
246
|
-
item(row, column) {
|
|
247
|
-
const height = this._height;
|
|
248
|
-
const keys = Object.keys(this._columns);
|
|
249
|
-
const width = keys.length;
|
|
250
|
-
if (row === undefined && column === undefined) {
|
|
251
|
-
if (height !== 1 || width !== 1) {
|
|
252
|
-
throw new Error("DataFrame.item() can only be called without arguments if the shape is (1, 1).");
|
|
253
|
-
}
|
|
254
|
-
return this._columns[keys[0]][0];
|
|
255
|
-
}
|
|
256
|
-
if (row === undefined || column === undefined) {
|
|
257
|
-
throw new Error("DataFrame.item() requires both row and column to be specified if not empty.");
|
|
258
|
-
}
|
|
259
|
-
if (row < 0 || row >= height) {
|
|
260
|
-
throw new Error(`Row index ${row} is out of bounds for DataFrame height ${height}.`);
|
|
261
|
-
}
|
|
262
|
-
let colName;
|
|
263
|
-
if (typeof column === "number") {
|
|
264
|
-
if (column < 0 || column >= width) {
|
|
265
|
-
throw new Error(`Column index ${column} is out of bounds for DataFrame width ${width}.`);
|
|
266
|
-
}
|
|
267
|
-
colName = keys[column];
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
colName = column;
|
|
271
|
-
if (this._columns[colName] === undefined) {
|
|
272
|
-
throw new Error(`Column "${colName}" does not exist.`);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return this._columns[colName][row];
|
|
276
|
-
}
|
|
277
|
-
*iter_columns() {
|
|
278
|
-
const keys = Object.keys(this._columns);
|
|
279
|
-
const keysLen = keys.length;
|
|
280
|
-
const columns = this._columns;
|
|
281
|
-
for (let j = 0; j < keysLen; j++) {
|
|
282
|
-
yield columns[keys[j]];
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
*iter_rows({ named = false } = {}) {
|
|
286
|
-
const keys = Object.keys(this._columns);
|
|
287
|
-
const keysLen = keys.length;
|
|
288
|
-
const columns = this._columns;
|
|
289
|
-
const height = this._height;
|
|
290
|
-
const colArrays = new Array(keysLen);
|
|
291
|
-
for (let j = 0; j < keysLen; j++) {
|
|
292
|
-
colArrays[j] = columns[keys[j]];
|
|
293
|
-
}
|
|
294
|
-
if (named) {
|
|
295
|
-
for (let i = 0; i < height; i++) {
|
|
296
|
-
const row = {};
|
|
297
|
-
for (let j = 0; j < keysLen; j++) {
|
|
298
|
-
row[keys[j]] = colArrays[j][i];
|
|
299
|
-
}
|
|
300
|
-
yield row;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
for (let i = 0; i < height; i++) {
|
|
305
|
-
const row = new Array(keysLen);
|
|
306
|
-
for (let j = 0; j < keysLen; j++) {
|
|
307
|
-
row[j] = colArrays[j][i];
|
|
308
|
-
}
|
|
309
|
-
yield row;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
join(config) {
|
|
314
|
-
const { other, on, how = "inner", suffixes = ["", "_right"] } = config;
|
|
315
|
-
const joinKeysStr = (0, utils_1.toValidStringArray)(on);
|
|
316
|
-
for (let i = 0; i < joinKeysStr.length; i++) {
|
|
317
|
-
const keyStr = joinKeysStr[i];
|
|
318
|
-
(0, exceptions_1.assertColumnExists)(keyStr, this._columns, "Join key", " in the left DataFrame.");
|
|
319
|
-
(0, exceptions_1.assertColumnExists)(keyStr, other._columns, "Join key", " in the right DataFrame.");
|
|
320
|
-
}
|
|
321
|
-
const [leftSuffix, rightSuffix] = suffixes;
|
|
322
|
-
const leftKeys = Object.keys(this._columns);
|
|
323
|
-
const rightKeys = Object.keys(other._columns);
|
|
324
|
-
const joinKeySet = new Set(joinKeysStr);
|
|
325
|
-
const leftLen = leftKeys.length;
|
|
326
|
-
const rightLen = rightKeys.length;
|
|
327
|
-
const getColumnHashAt = (columns, idx) => {
|
|
328
|
-
const len = joinKeysStr.length;
|
|
329
|
-
for (let i = 0; i < len; i++) {
|
|
330
|
-
if (columns[joinKeysStr[i]][idx] == null)
|
|
331
|
-
return null;
|
|
332
|
-
}
|
|
333
|
-
return (0, utils_2.computeRowHash)(columns, joinKeysStr, idx);
|
|
334
|
-
};
|
|
335
|
-
const rightHash = new Map();
|
|
336
|
-
const rightHeight = other._height;
|
|
337
|
-
const rightCols = other._columns;
|
|
338
|
-
for (let i = 0; i < rightHeight; i++) {
|
|
339
|
-
const hash = getColumnHashAt(rightCols, i);
|
|
340
|
-
if (hash === null)
|
|
341
|
-
continue;
|
|
342
|
-
let list = rightHash.get(hash);
|
|
343
|
-
if (list === undefined) {
|
|
344
|
-
list = [];
|
|
345
|
-
rightHash.set(hash, list);
|
|
346
|
-
}
|
|
347
|
-
list.push(i);
|
|
348
|
-
}
|
|
349
|
-
const leftHeight = this._height;
|
|
350
|
-
const leftCols = this._columns;
|
|
351
|
-
const leftIndices = [];
|
|
352
|
-
const rightIndices = [];
|
|
353
|
-
const trackRight = how === "outer" || how === "right";
|
|
354
|
-
const matchedRightIndices = trackRight ? new Set() : null;
|
|
355
|
-
for (let i = 0; i < leftHeight; i++) {
|
|
356
|
-
const hash = getColumnHashAt(leftCols, i);
|
|
357
|
-
const matches = hash === null ? undefined : rightHash.get(hash);
|
|
358
|
-
if (matches === undefined) {
|
|
359
|
-
if (how === "left" || how === "outer") {
|
|
360
|
-
leftIndices.push(i);
|
|
361
|
-
rightIndices.push(null);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
for (let m = 0; m < matches.length; m++) {
|
|
366
|
-
const rIdx = matches[m];
|
|
367
|
-
if (trackRight) {
|
|
368
|
-
matchedRightIndices.add(rIdx);
|
|
369
|
-
}
|
|
370
|
-
leftIndices.push(i);
|
|
371
|
-
rightIndices.push(rIdx);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (trackRight) {
|
|
376
|
-
for (let j = 0; j < rightHeight; j++) {
|
|
377
|
-
if (!matchedRightIndices.has(j)) {
|
|
378
|
-
leftIndices.push(-1);
|
|
379
|
-
rightIndices.push(j);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
const outHeight = leftIndices.length;
|
|
384
|
-
const newColumns = {};
|
|
385
|
-
const outSchema = {};
|
|
386
|
-
for (let i = 0; i < leftLen; i++) {
|
|
387
|
-
const k = leftKeys[i];
|
|
388
|
-
const mappedName = (k in other._columns && !joinKeySet.has(k)) ? `${k}${leftSuffix}` : k;
|
|
389
|
-
const leftCol = this._columns[k];
|
|
390
|
-
const isJoinKey = joinKeySet.has(k);
|
|
391
|
-
const outCol = new Array(outHeight);
|
|
392
|
-
if (isJoinKey) {
|
|
393
|
-
const rightCol = other._columns[k];
|
|
394
|
-
for (let r = 0; r < outHeight; r++) {
|
|
395
|
-
const leftIdx = leftIndices[r];
|
|
396
|
-
if (leftIdx !== -1) {
|
|
397
|
-
outCol[r] = leftCol[leftIdx];
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
const rightIdx = rightIndices[r];
|
|
401
|
-
outCol[r] = rightIdx !== null ? rightCol[rightIdx] : null;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
for (let r = 0; r < outHeight; r++) {
|
|
407
|
-
const leftIdx = leftIndices[r];
|
|
408
|
-
outCol[r] = leftIdx !== -1 ? leftCol[leftIdx] : null;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
newColumns[mappedName] = outCol;
|
|
412
|
-
if (this._schema[k]) {
|
|
413
|
-
outSchema[mappedName] = this._schema[k];
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
for (let i = 0; i < rightLen; i++) {
|
|
417
|
-
const k = rightKeys[i];
|
|
418
|
-
if (!joinKeySet.has(k)) {
|
|
419
|
-
const mappedName = k in this._columns ? `${k}${rightSuffix}` : k;
|
|
420
|
-
const rightCol = other._columns[k];
|
|
421
|
-
const outCol = new Array(outHeight);
|
|
422
|
-
for (let r = 0; r < outHeight; r++) {
|
|
423
|
-
const rightIdx = rightIndices[r];
|
|
424
|
-
outCol[r] = rightIdx !== null ? rightCol[rightIdx] : null;
|
|
425
|
-
}
|
|
426
|
-
newColumns[mappedName] = outCol;
|
|
427
|
-
if (other._schema[k]) {
|
|
428
|
-
outSchema[mappedName] = other._schema[k];
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
return DataFrame._createDirect(newColumns, outSchema, outHeight);
|
|
433
|
-
}
|
|
434
|
-
limit(n, { offset = 0, from = "start" } = {}) {
|
|
435
|
-
const len = this._height;
|
|
436
|
-
const safeN = (0, utils_1.clamp)(Math.floor(n), { min: 0, max: len });
|
|
437
|
-
const safeOffset = (0, utils_1.clamp)(Math.floor(offset), { min: 0, max: len });
|
|
438
|
-
let actualStart = safeOffset;
|
|
439
|
-
let actualEnd = Math.min(safeOffset + safeN, len);
|
|
440
|
-
if (from === "end") {
|
|
441
|
-
actualEnd = len - safeOffset;
|
|
442
|
-
actualStart = Math.max(actualEnd - safeN, 0);
|
|
443
|
-
}
|
|
444
|
-
const newHeight = actualEnd - actualStart;
|
|
445
|
-
const newColumns = {};
|
|
446
|
-
const keys = Object.keys(this._columns);
|
|
447
|
-
const keysLen = keys.length;
|
|
448
|
-
for (let i = 0; i < keysLen; i++) {
|
|
449
|
-
const key = keys[i];
|
|
450
|
-
newColumns[key] = this._columns[key].slice(actualStart, actualEnd);
|
|
451
|
-
}
|
|
452
|
-
return DataFrame._createDirect(newColumns, this._schema, newHeight);
|
|
453
|
-
}
|
|
454
|
-
pivot(config) {
|
|
455
|
-
if (this._height === 0)
|
|
456
|
-
return DataFrame._createDirect({}, {}, 0);
|
|
457
|
-
const { index, columns, values } = config;
|
|
458
|
-
const indexStr = (0, utils_1.toValidStringArray)(index);
|
|
459
|
-
const indexLen = indexStr.length;
|
|
460
|
-
for (let j = 0; j < indexLen; j++) {
|
|
461
|
-
(0, exceptions_1.assertColumnExists)(indexStr[j], this._columns, "Pivot index key");
|
|
462
|
-
}
|
|
463
|
-
const colKey = String(columns);
|
|
464
|
-
const valKey = String(values);
|
|
465
|
-
(0, exceptions_1.assertColumnExists)(colKey, this._columns, "Pivot column key");
|
|
466
|
-
(0, exceptions_1.assertColumnExists)(valKey, this._columns, "Pivot values key");
|
|
467
|
-
const groups = new Map();
|
|
468
|
-
const firstRowIdxs = [];
|
|
469
|
-
const colNames = new Set();
|
|
470
|
-
const height = this._height;
|
|
471
|
-
const pivotCol = this._columns[colKey];
|
|
472
|
-
const valCol = this._columns[valKey];
|
|
473
|
-
for (let i = 0; i < height; i++) {
|
|
474
|
-
const rowKey = (0, utils_2.computeRowHash)(this._columns, indexStr, i);
|
|
475
|
-
colNames.add(String(pivotCol[i]));
|
|
476
|
-
if (groups.get(rowKey) === undefined) {
|
|
477
|
-
groups.set(rowKey, groups.size);
|
|
478
|
-
firstRowIdxs.push(i);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
const outHeight = groups.size;
|
|
482
|
-
const indexColsDict = {};
|
|
483
|
-
const outSchema = {};
|
|
484
|
-
for (let j = 0; j < indexLen; j++) {
|
|
485
|
-
const idxKey = indexStr[j];
|
|
486
|
-
indexColsDict[idxKey] = this._columns[idxKey];
|
|
487
|
-
if (this._schema[idxKey]) {
|
|
488
|
-
outSchema[idxKey] = this._schema[idxKey];
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
const newColumns = (0, utils_2.gatherColumnsByIndices)(indexColsDict, firstRowIdxs);
|
|
492
|
-
const allCols = Array.from(colNames);
|
|
493
|
-
const valType = this._schema[valKey] || datatypes_1.DataTypeRegistry.Utf8;
|
|
494
|
-
for (let j = 0; j < allCols.length; j++) {
|
|
495
|
-
const colName = allCols[j];
|
|
496
|
-
newColumns[colName] = new Array(outHeight).fill(null);
|
|
497
|
-
outSchema[colName] = valType;
|
|
498
|
-
}
|
|
499
|
-
for (let i = 0; i < height; i++) {
|
|
500
|
-
const rowKey = (0, utils_2.computeRowHash)(this._columns, indexStr, i);
|
|
501
|
-
const groupIdx = groups.get(rowKey);
|
|
502
|
-
const pivotColName = String(pivotCol[i]);
|
|
503
|
-
newColumns[pivotColName][groupIdx] = valCol[i];
|
|
504
|
-
}
|
|
505
|
-
return DataFrame._createDirect(newColumns, outSchema, outHeight);
|
|
506
|
-
}
|
|
507
|
-
rename(mapping) {
|
|
508
|
-
const renameMapping = mapping || {};
|
|
509
|
-
const newColumns = {};
|
|
510
|
-
const outSchema = {};
|
|
511
|
-
const originalKeys = Object.keys(this._columns);
|
|
512
|
-
for (const key of originalKeys) {
|
|
513
|
-
const newKey = renameMapping[key] || key;
|
|
514
|
-
newColumns[newKey] = this._columns[key];
|
|
515
|
-
outSchema[newKey] = this._schema[key];
|
|
516
|
-
}
|
|
517
|
-
const finalKeys = Object.keys(newColumns);
|
|
518
|
-
if (finalKeys.length < originalKeys.length) {
|
|
519
|
-
throw new exceptions_1.DataFrameError("Rename collision: Multiple columns mapped to the same output name.");
|
|
520
|
-
}
|
|
521
|
-
return DataFrame._createDirect(newColumns, outSchema, this._height);
|
|
522
|
-
}
|
|
523
|
-
reverse() {
|
|
524
|
-
if (this._height === 0)
|
|
525
|
-
return this;
|
|
526
|
-
const newColumns = {};
|
|
527
|
-
const keys = Object.keys(this._columns);
|
|
528
|
-
const len = keys.length;
|
|
529
|
-
for (let i = 0; i < len; i++) {
|
|
530
|
-
const key = keys[i];
|
|
531
|
-
newColumns[key] = this._columns[key].slice().reverse();
|
|
532
|
-
}
|
|
533
|
-
return DataFrame._createDirect(newColumns, this._schema, this._height);
|
|
534
|
-
}
|
|
535
|
-
get schema() {
|
|
536
|
-
return this._schema;
|
|
537
|
-
}
|
|
538
|
-
select(...args) {
|
|
539
|
-
const exprs = this._normalizeArgs(args);
|
|
540
|
-
const allKeys = Object.keys(this._columns);
|
|
541
|
-
const expandedExprs = (0, columnExpressions_1.resolveColumnSelectors)(exprs, allKeys, undefined, this._schema, this._columns);
|
|
542
|
-
const numExprs = expandedExprs.length;
|
|
543
|
-
if (numExprs === 0) {
|
|
544
|
-
return DataFrame._createDirect({}, {}, this._height);
|
|
545
|
-
}
|
|
546
|
-
const newColumns = {};
|
|
547
|
-
const outSchema = {};
|
|
548
|
-
const evaluatedCols = new Array(numExprs);
|
|
549
|
-
const targetKeys = new Array(numExprs);
|
|
550
|
-
const selectedKeys = new Set();
|
|
551
|
-
let activeRowMap = null;
|
|
552
|
-
for (let i = 0; i < numExprs; i++) {
|
|
553
|
-
const expr = expandedExprs[i];
|
|
554
|
-
const targetKey = expr.outputName || expr.colName || columnExpressions_1.ALL_COLUMNS_MARKER;
|
|
555
|
-
if (selectedKeys.has(targetKey)) {
|
|
556
|
-
throw new exceptions_1.DataFrameError(`Duplicate column selection: "${targetKey}" is selected multiple times.`);
|
|
557
|
-
}
|
|
558
|
-
selectedKeys.add(targetKey);
|
|
559
|
-
const col = (0, columnExpressions_1.evaluateExpression)(expr, this._columns, this._height);
|
|
560
|
-
evaluatedCols[i] = col;
|
|
561
|
-
targetKeys[i] = targetKey;
|
|
562
|
-
const rowMap = col && col.rowMap;
|
|
563
|
-
if (rowMap) {
|
|
564
|
-
if (activeRowMap) {
|
|
565
|
-
const len = rowMap.length;
|
|
566
|
-
if (len !== activeRowMap.length) {
|
|
567
|
-
throw new exceptions_1.ShapeError(`Mismatched explode heights: Column "${targetKey}" has length ${len}, but another exploded column has length ${activeRowMap.length}`);
|
|
568
|
-
}
|
|
569
|
-
for (let j = 0; j < len; j++) {
|
|
570
|
-
if (rowMap[j] !== activeRowMap[j]) {
|
|
571
|
-
throw new exceptions_1.ShapeError(`Mismatched explode heights: Column "${targetKey}" has mismatched row lengths compared to another exploded column.`);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
activeRowMap = rowMap;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
let targetHeight = activeRowMap ? activeRowMap.length : this._height;
|
|
581
|
-
let shouldCollapse = numExprs > 0;
|
|
582
|
-
for (let i = 0; i < numExprs; i++) {
|
|
583
|
-
const expr = expandedExprs[i];
|
|
584
|
-
const isGlobalAgg = expr.aggFn != null && (expr.partitionBy == null || expr.partitionBy.length === 0);
|
|
585
|
-
const isLit = !!expr.isLiteral;
|
|
586
|
-
if (!isGlobalAgg && !isLit) {
|
|
587
|
-
shouldCollapse = false;
|
|
588
|
-
break;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
for (let i = 0; i < numExprs; i++) {
|
|
592
|
-
const targetKey = targetKeys[i];
|
|
593
|
-
let col = evaluatedCols[i];
|
|
594
|
-
const colObj = col;
|
|
595
|
-
const hasRowMap = colObj && colObj.rowMap;
|
|
596
|
-
const len = (0, utils_1.isArrayOrTypedArray)(col) ? col.length : 0;
|
|
597
|
-
const expectedLen = (activeRowMap && !hasRowMap) ? this._height : targetHeight;
|
|
598
|
-
if (len !== expectedLen) {
|
|
599
|
-
throw new exceptions_1.ShapeError(`Column height mismatch: Column "${targetKey}" has length ${len}, but expected ${expectedLen}`);
|
|
600
|
-
}
|
|
601
|
-
if (activeRowMap && !hasRowMap) {
|
|
602
|
-
const mapLen = activeRowMap.length;
|
|
603
|
-
if ((0, utils_1.isTypedArray)(col)) {
|
|
604
|
-
const newCol = new colObj.constructor(mapLen);
|
|
605
|
-
for (let j = 0; j < mapLen; j++) {
|
|
606
|
-
newCol[j] = colObj[activeRowMap[j]];
|
|
607
|
-
}
|
|
608
|
-
col = newCol;
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
const newCol = new Array(mapLen);
|
|
612
|
-
for (let j = 0; j < mapLen; j++) {
|
|
613
|
-
newCol[j] = colObj[activeRowMap[j]];
|
|
614
|
-
}
|
|
615
|
-
col = newCol;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
evaluatedCols[i] = col;
|
|
619
|
-
}
|
|
620
|
-
if (shouldCollapse) {
|
|
621
|
-
targetHeight = 1;
|
|
622
|
-
}
|
|
623
|
-
for (let i = 0; i < numExprs; i++) {
|
|
624
|
-
const expr = expandedExprs[i];
|
|
625
|
-
const targetKey = targetKeys[i];
|
|
626
|
-
const col = evaluatedCols[i];
|
|
627
|
-
const originalKey = expr.colName || targetKey;
|
|
628
|
-
const isPureCol = expr instanceof columnExpressions_1.ColumnExpr && expr.ops.length === 0 && !expr.isWindow && !expr.aggFn;
|
|
629
|
-
const type = (isPureCol && this._schema[originalKey]) || (0, utils_2.inferColumnType)(col);
|
|
630
|
-
outSchema[targetKey] = type;
|
|
631
|
-
newColumns[targetKey] = (0, utils_2.coerceColumn)(col, type, targetHeight);
|
|
632
|
-
}
|
|
633
|
-
return DataFrame._createDirect(newColumns, outSchema, targetHeight);
|
|
634
|
-
}
|
|
635
|
-
get shape() {
|
|
636
|
-
return [this.height, this.width];
|
|
637
|
-
}
|
|
638
|
-
slice(start, end) {
|
|
639
|
-
const total = this._height;
|
|
640
|
-
const actualStart = start < 0 ? Math.max(total + start, 0) : Math.min(start, total);
|
|
641
|
-
const actualEnd = end === undefined
|
|
642
|
-
? total
|
|
643
|
-
: (end < 0 ? Math.max(total + end, 0) : Math.min(end, total));
|
|
644
|
-
const n = Math.max(actualEnd - actualStart, 0);
|
|
645
|
-
return this.limit(n, { offset: actualStart });
|
|
646
|
-
}
|
|
647
|
-
sort(config) {
|
|
648
|
-
if (!config || !config.by || this._height === 0)
|
|
649
|
-
return this;
|
|
650
|
-
const { by, descending = false, nullsLast = true, custom } = config;
|
|
651
|
-
const sortKeys = (0, utils_1.toValidArray)(by);
|
|
652
|
-
for (let i = 0; i < sortKeys.length; i++) {
|
|
653
|
-
const expr = columnExpressions_1.ColumnExpr.toColExpr(sortKeys[i]);
|
|
654
|
-
if (expr.colName) {
|
|
655
|
-
(0, exceptions_1.assertColumnExists)(expr.colName, this._columns, "Sort key");
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
const descArray = Array.isArray(descending)
|
|
659
|
-
? descending
|
|
660
|
-
: new Array(sortKeys.length).fill(descending);
|
|
661
|
-
const sortKeysLen = sortKeys.length;
|
|
662
|
-
const plan = new Array(sortKeysLen);
|
|
663
|
-
for (let i = 0; i < sortKeysLen; i++) {
|
|
664
|
-
const keyOrExpr = sortKeys[i];
|
|
665
|
-
const isDesc = descArray[i] ? -1 : 1;
|
|
666
|
-
const customComp = (custom && typeof keyOrExpr === "string") ? custom[keyOrExpr] : null;
|
|
667
|
-
const values = columnExpressions_1.ColumnExpr.toColExpr(keyOrExpr).evaluate(this._columns, this._height);
|
|
668
|
-
plan[i] = {
|
|
669
|
-
values,
|
|
670
|
-
isDesc,
|
|
671
|
-
customComp
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
const planLen = plan.length;
|
|
675
|
-
const nullMultiplier = nullsLast ? 1 : -1;
|
|
676
|
-
const indices = new Array(this._height);
|
|
677
|
-
for (let i = 0; i < this._height; i++) {
|
|
678
|
-
indices[i] = i;
|
|
679
|
-
}
|
|
680
|
-
indices.sort((idxA, idxB) => {
|
|
681
|
-
for (let i = 0; i < planLen; i++) {
|
|
682
|
-
const { values, isDesc, customComp } = plan[i];
|
|
683
|
-
const vA = values[idxA];
|
|
684
|
-
const vB = values[idxB];
|
|
685
|
-
if (customComp) {
|
|
686
|
-
const res = customComp(vA, vB);
|
|
687
|
-
if (res !== 0)
|
|
688
|
-
return res * isDesc;
|
|
689
|
-
continue;
|
|
690
|
-
}
|
|
691
|
-
if (vA == null || vB == null) {
|
|
692
|
-
if (vA === vB)
|
|
693
|
-
continue;
|
|
694
|
-
return (vA == null ? 1 : -1) * nullMultiplier;
|
|
695
|
-
}
|
|
696
|
-
if (vA === vB)
|
|
697
|
-
continue;
|
|
698
|
-
const res = vA < vB ? -1 : 1;
|
|
699
|
-
return res * isDesc;
|
|
700
|
-
}
|
|
701
|
-
return 0;
|
|
702
|
-
});
|
|
703
|
-
const newColumns = (0, utils_2.gatherColumnsByIndices)(this._columns, indices);
|
|
704
|
-
return DataFrame._createDirect(newColumns, this._schema, this._height);
|
|
705
|
-
}
|
|
706
|
-
tail(n = 10) {
|
|
707
|
-
return this.limit(n, { offset: 0, from: 'end' });
|
|
708
|
-
}
|
|
709
|
-
to_dict() {
|
|
710
|
-
return { ...this._columns };
|
|
711
|
-
}
|
|
712
|
-
to_dicts() {
|
|
713
|
-
return (0, utils_2.columnsToRows)(this._columns, this._height);
|
|
714
|
-
}
|
|
715
|
-
to_list(nameOrExpr) {
|
|
716
|
-
if (this._height === 0)
|
|
717
|
-
return [];
|
|
718
|
-
if (nameOrExpr == null) {
|
|
719
|
-
return new Array(this._height).fill(null);
|
|
720
|
-
}
|
|
721
|
-
const expr = columnExpressions_1.ColumnExpr.toColExpr(nameOrExpr);
|
|
722
|
-
const colData = expr.evaluate(this._columns, this._height);
|
|
723
|
-
return Array.isArray(colData) ? colData : Array.from(colData);
|
|
724
|
-
}
|
|
725
|
-
transpose({ include_header: includeHeader = false, header_name: headerName = "column", column_names: colNamesOpt } = {}) {
|
|
726
|
-
if (this._height === 0) {
|
|
727
|
-
const cols = {};
|
|
728
|
-
const schema = {};
|
|
729
|
-
if (includeHeader) {
|
|
730
|
-
cols[headerName] = (0, utils_2.coerceColumn)([], datatypes_1.DataTypeRegistry.Utf8, 0);
|
|
731
|
-
schema[headerName] = datatypes_1.DataTypeRegistry.Utf8;
|
|
732
|
-
}
|
|
733
|
-
return DataFrame._createDirect(cols, schema, 0);
|
|
734
|
-
}
|
|
735
|
-
let dataColumns = this.columns;
|
|
736
|
-
if (typeof colNamesOpt === "string") {
|
|
737
|
-
(0, exceptions_1.assertColumnExists)(colNamesOpt, this._columns, "column_names");
|
|
738
|
-
dataColumns = dataColumns.filter(c => c !== colNamesOpt);
|
|
739
|
-
}
|
|
740
|
-
let newColNames = [];
|
|
741
|
-
if (typeof colNamesOpt === "string") {
|
|
742
|
-
const keyCol = this._columns[colNamesOpt];
|
|
743
|
-
newColNames = new Array(this._height);
|
|
744
|
-
for (let i = 0; i < this._height; i++) {
|
|
745
|
-
const val = keyCol[i];
|
|
746
|
-
if (val == null) {
|
|
747
|
-
throw new exceptions_1.DataFrameError(`Transpose column_names column "${colNamesOpt}" contains null/undefined at index ${i}`);
|
|
748
|
-
}
|
|
749
|
-
newColNames[i] = String(val);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
else if (colNamesOpt != null && typeof colNamesOpt !== "string" && Symbol.iterator in Object(colNamesOpt)) {
|
|
753
|
-
const colNamesArr = Array.from(colNamesOpt);
|
|
754
|
-
if (colNamesArr.length !== this._height) {
|
|
755
|
-
throw new exceptions_1.DataFrameError(`column_names length (${colNamesArr.length}) must match the height of the DataFrame (${this._height})`);
|
|
756
|
-
}
|
|
757
|
-
newColNames = new Array(this._height);
|
|
758
|
-
for (let i = 0; i < this._height; i++) {
|
|
759
|
-
newColNames[i] = String(colNamesArr[i]);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
else {
|
|
763
|
-
newColNames = new Array(this._height);
|
|
764
|
-
for (let i = 0; i < this._height; i++) {
|
|
765
|
-
newColNames[i] = `column_${i}`;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
const uniqueNames = new Set();
|
|
769
|
-
if (includeHeader) {
|
|
770
|
-
uniqueNames.add(headerName);
|
|
771
|
-
}
|
|
772
|
-
for (let i = 0; i < newColNames.length; i++) {
|
|
773
|
-
const name = newColNames[i];
|
|
774
|
-
if (uniqueNames.has(name)) {
|
|
775
|
-
throw new exceptions_1.DataFrameError(`Duplicate column name in transposed DataFrame: "${name}"`);
|
|
776
|
-
}
|
|
777
|
-
uniqueNames.add(name);
|
|
778
|
-
}
|
|
779
|
-
const numDataCols = dataColumns.length;
|
|
780
|
-
const newCols = {};
|
|
781
|
-
const newSchema = {};
|
|
782
|
-
if (includeHeader) {
|
|
783
|
-
newCols[headerName] = (0, utils_2.coerceColumn)(dataColumns, datatypes_1.DataTypeRegistry.Utf8, numDataCols);
|
|
784
|
-
newSchema[headerName] = datatypes_1.DataTypeRegistry.Utf8;
|
|
785
|
-
}
|
|
786
|
-
for (let i = 0; i < this._height; i++) {
|
|
787
|
-
const colName = newColNames[i];
|
|
788
|
-
const rawVals = new Array(numDataCols);
|
|
789
|
-
for (let j = 0; j < numDataCols; j++) {
|
|
790
|
-
rawVals[j] = this._columns[dataColumns[j]][i];
|
|
791
|
-
}
|
|
792
|
-
const type = (0, utils_2.inferColumnType)(rawVals);
|
|
793
|
-
newCols[colName] = (0, utils_2.coerceColumn)(rawVals, type, numDataCols);
|
|
794
|
-
newSchema[colName] = type;
|
|
795
|
-
}
|
|
796
|
-
return DataFrame._createDirect(newCols, newSchema, numDataCols);
|
|
797
|
-
}
|
|
798
|
-
unique(columns) {
|
|
799
|
-
if (this._height === 0)
|
|
800
|
-
return DataFrame._createDirect({}, this._schema, 0);
|
|
801
|
-
const colsArr = (0, utils_1.toValidArray)(columns);
|
|
802
|
-
const colsStr = colsArr.length === 0
|
|
803
|
-
? Object.keys(this._columns)
|
|
804
|
-
: colsArr.map(String);
|
|
805
|
-
for (const colKey of colsStr) {
|
|
806
|
-
(0, exceptions_1.assertColumnExists)(colKey, this._columns, "Unique column key");
|
|
807
|
-
}
|
|
808
|
-
const seen = new Set();
|
|
809
|
-
const matchingIndices = [];
|
|
810
|
-
const height = this._height;
|
|
811
|
-
for (let i = 0; i < height; i++) {
|
|
812
|
-
const hash = (0, utils_2.computeRowHash)(this._columns, colsStr, i);
|
|
813
|
-
if (!seen.has(hash)) {
|
|
814
|
-
seen.add(hash);
|
|
815
|
-
matchingIndices.push(i);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
const newColumns = (0, utils_2.gatherColumnsByIndices)(this._columns, matchingIndices);
|
|
819
|
-
const newHeight = matchingIndices.length;
|
|
820
|
-
return DataFrame._createDirect(newColumns, this._schema, newHeight);
|
|
821
|
-
}
|
|
822
|
-
unpivot(config) {
|
|
823
|
-
const { idVars, valueVars, varName = "variable", valueName = "value" } = config;
|
|
824
|
-
const idVarsStr = (0, utils_1.toValidStringArray)(idVars);
|
|
825
|
-
const valueVarsStr = (0, utils_1.toValidStringArray)(valueVars);
|
|
826
|
-
const idVarsLen = idVarsStr.length;
|
|
827
|
-
const valueVarsLen = valueVarsStr.length;
|
|
828
|
-
for (const idKey of idVarsStr) {
|
|
829
|
-
(0, exceptions_1.assertColumnExists)(idKey, this._columns, "Unpivot id variable key");
|
|
830
|
-
}
|
|
831
|
-
for (const vKey of valueVarsStr) {
|
|
832
|
-
(0, exceptions_1.assertColumnExists)(vKey, this._columns, "Unpivot value variable key");
|
|
833
|
-
}
|
|
834
|
-
const newHeight = this._height * valueVarsLen;
|
|
835
|
-
const newColumns = {};
|
|
836
|
-
for (let k = 0; k < idVarsLen; k++) {
|
|
837
|
-
newColumns[idVarsStr[k]] = new Array(newHeight);
|
|
838
|
-
}
|
|
839
|
-
newColumns[varName] = new Array(newHeight);
|
|
840
|
-
newColumns[valueName] = new Array(newHeight);
|
|
841
|
-
let outIdx = 0;
|
|
842
|
-
for (let i = 0; i < this._height; i++) {
|
|
843
|
-
for (let j = 0; j < valueVarsLen; j++) {
|
|
844
|
-
const vVar = valueVarsStr[j];
|
|
845
|
-
for (let k = 0; k < idVarsLen; k++) {
|
|
846
|
-
const idKey = idVarsStr[k];
|
|
847
|
-
newColumns[idKey][outIdx] = this._columns[idKey][i];
|
|
848
|
-
}
|
|
849
|
-
newColumns[varName][outIdx] = vVar;
|
|
850
|
-
newColumns[valueName][outIdx] = this._columns[vVar][i];
|
|
851
|
-
outIdx++;
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
const outSchema = {};
|
|
855
|
-
for (const key of idVarsStr) {
|
|
856
|
-
outSchema[key] = this._schema[key];
|
|
857
|
-
}
|
|
858
|
-
outSchema[varName] = datatypes_1.DataTypeRegistry.Utf8;
|
|
859
|
-
outSchema[valueName] = (0, utils_2.inferColumnType)(newColumns[valueName]);
|
|
860
|
-
return DataFrame._createDirect(newColumns, outSchema, newHeight);
|
|
861
|
-
}
|
|
862
|
-
vstack(other) {
|
|
863
|
-
return this.concat(other, { how: "vertical" });
|
|
864
|
-
}
|
|
865
|
-
get width() {
|
|
866
|
-
return Object.keys(this._columns).length;
|
|
867
|
-
}
|
|
868
|
-
_normalizeArgs(args) {
|
|
869
|
-
const flatArgs = args.flat();
|
|
870
|
-
const exprs = [];
|
|
871
|
-
for (const arg of flatArgs) {
|
|
872
|
-
if (typeof arg === "string") {
|
|
873
|
-
exprs.push(new columnExpressions_1.ColumnExpr(arg));
|
|
874
|
-
}
|
|
875
|
-
else if (columnExpressions_1.ColumnExpr.isColExpr(arg)) {
|
|
876
|
-
exprs.push(arg);
|
|
877
|
-
}
|
|
878
|
-
else if ((0, utils_1.isObj)(arg)) {
|
|
879
|
-
const keys = Object.keys(arg);
|
|
880
|
-
const numKeys = keys.length;
|
|
881
|
-
for (let i = 0; i < numKeys; i++) {
|
|
882
|
-
const key = keys[i];
|
|
883
|
-
const val = arg[key];
|
|
884
|
-
if (columnExpressions_1.ColumnExpr.isColExpr(val)) {
|
|
885
|
-
exprs.push(val.alias(key));
|
|
886
|
-
}
|
|
887
|
-
else {
|
|
888
|
-
const staticExpr = new columnExpressions_1.ColumnExpr(key);
|
|
889
|
-
staticExpr.evaluate = (_cols, h) => new Array(h).fill(val);
|
|
890
|
-
exprs.push(staticExpr);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
return exprs;
|
|
896
|
-
}
|
|
897
|
-
with_columns(...args) {
|
|
898
|
-
if (args.length === 0)
|
|
899
|
-
return this;
|
|
900
|
-
const exprs = this._normalizeArgs(args);
|
|
901
|
-
const allKeys = Object.keys(this._columns);
|
|
902
|
-
const expandedExprs = (0, columnExpressions_1.resolveColumnSelectors)(exprs, allKeys, undefined, this._schema, this._columns);
|
|
903
|
-
const numEntries = expandedExprs.length;
|
|
904
|
-
if (numEntries === 0)
|
|
905
|
-
return this;
|
|
906
|
-
const overrides = new Map();
|
|
907
|
-
for (let j = 0; j < numEntries; j++) {
|
|
908
|
-
const expr = expandedExprs[j];
|
|
909
|
-
const name = expr.outputName || expr.colName || columnExpressions_1.ALL_COLUMNS_MARKER;
|
|
910
|
-
overrides.set(name, expr);
|
|
911
|
-
}
|
|
912
|
-
const selectList = [];
|
|
913
|
-
const numKeys = allKeys.length;
|
|
914
|
-
for (let i = 0; i < numKeys; i++) {
|
|
915
|
-
const key = allKeys[i];
|
|
916
|
-
selectList.push(overrides.get(key) || new columnExpressions_1.ColumnExpr(key));
|
|
917
|
-
overrides.delete(key);
|
|
918
|
-
}
|
|
919
|
-
for (const expr of overrides.values()) {
|
|
920
|
-
selectList.push(expr);
|
|
921
|
-
}
|
|
922
|
-
return this.select(...selectList);
|
|
923
|
-
}
|
|
924
|
-
with_row_index(name = "index", offset = 0) {
|
|
925
|
-
const expr = (0, columnExpressions_1.seq_range)(offset, {
|
|
926
|
-
mode: "independent",
|
|
927
|
-
dtype: datatypes_1.DataTypeRegistry.UInt32,
|
|
928
|
-
step: 1
|
|
929
|
-
});
|
|
930
|
-
const df = this.insert_column(0, name, expr);
|
|
931
|
-
df._schema[name] = datatypes_1.DataTypeRegistry.UInt32;
|
|
932
|
-
return df;
|
|
933
|
-
}
|
|
934
|
-
write_json(file, { format = "json", replacerOptions } = {}) {
|
|
935
|
-
if (format !== "json" && format !== "ndjson") {
|
|
936
|
-
throw new TypeError(`Unsupported JSON format: "${format}". Expected "json" or "ndjson".`);
|
|
937
|
-
}
|
|
938
|
-
const safeReplacer = replacerOptions?.replacer === null
|
|
939
|
-
? undefined
|
|
940
|
-
: (0, json_1.createSafeJsonReplacer)(replacerOptions);
|
|
941
|
-
let jsonStr;
|
|
942
|
-
if (format === "ndjson") {
|
|
943
|
-
const dicts = this.to_dicts();
|
|
944
|
-
const len = dicts.length;
|
|
945
|
-
const lines = new Array(len);
|
|
946
|
-
for (let i = 0; i < len; i++) {
|
|
947
|
-
lines[i] = JSON.stringify(dicts[i], safeReplacer);
|
|
948
|
-
}
|
|
949
|
-
jsonStr = lines.join(constants_1.NEWLINE);
|
|
950
|
-
}
|
|
951
|
-
else {
|
|
952
|
-
jsonStr = JSON.stringify(this.to_dicts(), safeReplacer);
|
|
953
|
-
}
|
|
954
|
-
(0, utils_2.writeStringToFileOrStream)(file, jsonStr);
|
|
955
|
-
return jsonStr;
|
|
956
|
-
}
|
|
957
|
-
write_csv(file, options = {}) {
|
|
958
|
-
if (file) {
|
|
959
|
-
if (typeof file === "string") {
|
|
960
|
-
const fs = require("fs");
|
|
961
|
-
const fd = fs.openSync(file, "w");
|
|
962
|
-
try {
|
|
963
|
-
(0, utils_1.stringifyCSV)(this._columns, this._height, {
|
|
964
|
-
...options,
|
|
965
|
-
onRow: (str) => {
|
|
966
|
-
fs.writeSync(fd, str, null, "utf8");
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
finally {
|
|
971
|
-
fs.closeSync(fd);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
else if (typeof file === "object" && typeof file.write === "function") {
|
|
975
|
-
(0, utils_1.stringifyCSV)(this._columns, this._height, {
|
|
976
|
-
...options,
|
|
977
|
-
onRow: (str) => {
|
|
978
|
-
file.write(str);
|
|
979
|
-
}
|
|
980
|
-
});
|
|
981
|
-
}
|
|
982
|
-
else {
|
|
983
|
-
throw new TypeError("Invalid file argument. Expected a file path string or a writable stream/object with a write method.");
|
|
984
|
-
}
|
|
985
|
-
return "";
|
|
986
|
-
}
|
|
987
|
-
return (0, utils_1.stringifyCSV)(this._columns, this._height, options);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
exports.DataFrame = DataFrame;
|