Skip to content

Commit de1cc29

Browse files
committed
Add default support for Datetime
1 parent 039e518 commit de1cc29

File tree

11 files changed

+2872
-2685
lines changed

11 files changed

+2872
-2685
lines changed

src/danfojs-base/core/generic.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ export default class NDframe implements NDframeInterface {
7979
} else if (utils.is1DArray(data)) {
8080
this.loadArrayIntoNdframe({ data, index, columns, dtypes });
8181
} else {
82-
8382
if (Array.isArray(data) && utils.isObject(data[0])) {
8483
this.loadObjectIntoNdframe({ data, type: 1, index, columns, dtypes });
8584

@@ -92,6 +91,8 @@ export default class NDframe implements NDframeInterface {
9291
utils.isString((data)[0])
9392
) {
9493
this.loadArrayIntoNdframe({ data, index, columns, dtypes });
94+
} else if (Array.isArray(data) && data.length > 0 && utils.isDate(data[0])) {
95+
this.loadArrayIntoNdframe({ data, index, columns, dtypes });
9596
} else {
9697
throw new Error("File format not supported!");
9798
}
@@ -504,4 +505,4 @@ export default class NDframe implements NDframeInterface {
504505
print() {
505506
console.log(this + "");
506507
}
507-
}
508+
}

src/danfojs-base/core/series.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,7 +1962,7 @@ export default class Series extends NDframe implements SeriesInterface {
19621962
* ```
19631963
*/
19641964
get dt() {
1965-
if (this.dtypes[0] == "string") {
1965+
if (["string", "datetime"].includes(this.dtypes[0])) {
19661966
return new Dt(this)
19671967
} else {
19681968
throw new Error("Cannot call accessor dt on non-string type");
@@ -2184,4 +2184,4 @@ export default class Series extends NDframe implements SeriesInterface {
21842184
throw new Error("Not supported in NodeJS");
21852185
}
21862186
}
2187-
}
2187+
}

src/danfojs-base/shared/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default class Configs {
3636
tableDisplayConfig: {},
3737
tableMaxRow: 10,
3838
tableMaxColInConsole: 10,
39-
dtypeTestLim: 20,
39+
dtypeTestLim: 500,
4040
lowMemoryMode: false,
4141
...options
4242
}

src/danfojs-base/shared/defaults.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ export const BASE_CONFIG = {
2323
lowMemoryMode: false,
2424
}
2525

26-
export const DATA_TYPES = ["float32", "int32", "string", "boolean", 'undefined'];
26+
export const DATA_TYPES = ["float32", "int32", "string", "boolean", "datetime",'undefined'];

src/danfojs-base/shared/utils.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ export default class Utils {
9494
return value === undefined || value === null || (isNaN(value as any) && typeof value !== "string");
9595
}
9696

97+
/**
98+
* Checks if a value is a date object
99+
* @param value A date object
100+
* @returns boolean
101+
*/
102+
isDate(value: any): boolean {
103+
return value instanceof Date;
104+
}
105+
97106
/**
98107
* Generates an array of integers between specified range
99108
* @param start The starting number.
@@ -259,6 +268,7 @@ export default class Utils {
259268
let floatTracker: Array<boolean> = [];
260269
let stringTracker: Array<boolean> = [];
261270
let boolTracker: Array<boolean> = [];
271+
let dateTracker: Array<boolean> = [];
262272

263273
if (arr.length < config.getDtypeTestLim) {
264274
lim = arr.length;
@@ -275,28 +285,39 @@ export default class Utils {
275285
intTracker.push(false);
276286
stringTracker.push(false);
277287
boolTracker.push(true);
288+
dateTracker.push(false);
278289
} else if (this.isEmpty(ele)) {
279290
floatTracker.push(true);
280291
intTracker.push(false);
281292
stringTracker.push(false);
282293
boolTracker.push(false);
294+
dateTracker.push(false);
295+
} else if (this.isDate(ele)) {
296+
floatTracker.push(false);
297+
intTracker.push(false);
298+
stringTracker.push(false);
299+
boolTracker.push(false);
300+
dateTracker.push(true);
283301
} else if (!isNaN(Number(ele))) {
284302
if ((ele as unknown as string).toString().includes(".")) {
285303
floatTracker.push(true);
286304
intTracker.push(false);
287305
stringTracker.push(false);
288306
boolTracker.push(false);
307+
dateTracker.push(false);
289308
} else {
290309
floatTracker.push(false);
291310
intTracker.push(true);
292311
stringTracker.push(false);
293312
boolTracker.push(false);
313+
dateTracker.push(false);
294314
}
295-
} else {
315+
} else {
296316
floatTracker.push(false);
297317
intTracker.push(false);
298318
stringTracker.push(true);
299319
boolTracker.push(false);
320+
dateTracker.push(false);
300321
}
301322
}
302323

@@ -310,6 +331,8 @@ export default class Utils {
310331
dtypes = "int32";
311332
} else if (boolTracker.some(even)) {
312333
dtypes = "boolean";
334+
} else if (dateTracker.some(even)) {
335+
dtypes = "datetime";
313336
} else {
314337
dtypes = "undefined";
315338
}
@@ -819,4 +842,4 @@ export default class Utils {
819842

820843
return sortedValues;
821844
}
822-
}
845+
}

src/danfojs-browser/tests/core/frame.test.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,4 +2999,60 @@ describe("DataFrame", function () {
29992999
});
30003000

30013001
});
3002+
3003+
describe("DateTime datetime is supported", function () {
3004+
it("DateTime datetime is supported", function () {
3005+
let data = [ [ "Alice", 2, new Date(2029, 1, 1) ],
3006+
[ "Bob", 5, new Date(2019, 1, 2) ],
3007+
[ "Charlie", 30, new Date(2019, 1, 3) ],
3008+
[ "Dennis", 89, new Date(2019, 1, 4) ] ];
3009+
3010+
let columns = [ "Name", "Count", "Date" ];
3011+
3012+
let df = new dfd.DataFrame(data, { columns: columns });
3013+
assert.deepEqual(df.dtypes, [ "string", "int32", "datetime" ]);
3014+
3015+
const dateValues = [ new Date(2029, 1, 1), new Date(2019, 1, 2), new Date(2019, 1, 3), new Date(2019, 1, 4) ];
3016+
assert.deepEqual(df["Date"].values, dateValues);
3017+
});
3018+
3019+
it("datetime column properties can be accessed", function () {
3020+
let data = [ [ "Alice", 2, new Date("2029-01-01 01:00:00") ],
3021+
[ "Bob", 5, new Date("2019-01-02") ],
3022+
[ "Charlie", 30, new Date("2020-01-03 01:00:20") ],
3023+
[ "Dennis", 89, new Date("2022-02-04 02:16:00") ] ];
3024+
3025+
let columns = [ "Name", "Count", "Date" ];
3026+
3027+
let df = new dfd.DataFrame(data, { columns: columns });
3028+
3029+
assert.deepEqual(df["Date"].dt.year().values, [ 2029, 2019, 2020, 2022 ]);
3030+
assert.deepEqual(df["Date"].dt.month().values, [ 0, 0, 0, 1 ]);
3031+
assert.deepEqual(df["Date"].dt.dayOfMonth().values, [ 1, 2, 3, 4 ]);
3032+
assert.deepEqual(df["Date"].dt.hours().values, [ 1, 0, 1, 2 ]);
3033+
assert.deepEqual(df["Date"].dt.minutes().values, [ 0, 0, 0, 16 ]);
3034+
assert.deepEqual(df["Date"].dt.seconds().values, [ 0, 0, 20, 0 ]);
3035+
3036+
});
3037+
3038+
it("datetime column created from dtype passed", function () {
3039+
let data = [ [ "Alice", 2, "2029-01-01 01:00:00" ],
3040+
[ "Bob", 5, "2019-01-02" ],
3041+
[ "Charlie", 30, "2020-01-03 01:00:20" ],
3042+
[ "Dennis", 89, "2022-02-04 02:16:00" ] ];
3043+
3044+
let columns = [ "Name", "Count", "Date" ];
3045+
let dtypes = [ "string", "int32", "datetime" ];
3046+
3047+
let df = new dfd.DataFrame(data, { columns, dtypes });
3048+
3049+
assert.deepEqual(df["Date"].dt.year().values, [ 2029, 2019, 2020, 2022 ]);
3050+
assert.deepEqual(df["Date"].dt.month().values, [ 0, 0, 0, 1 ]);
3051+
assert.deepEqual(df["Date"].dt.dayOfMonth().values, [ 1, 2, 3, 4 ]);
3052+
assert.deepEqual(df["Date"].dt.hours().values, [ 1, 0, 1, 2 ]);
3053+
assert.deepEqual(df["Date"].dt.minutes().values, [ 0, 0, 0, 16 ]);
3054+
assert.deepEqual(df["Date"].dt.seconds().values, [ 0, 0, 20, 0 ]);
3055+
3056+
});
3057+
});
30023058
});

src/danfojs-browser/tests/core/generic.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,4 +489,21 @@ describe("Generic (NDFrame)", function () {
489489

490490
});
491491

492+
describe("DataFrame supports date object", function () {
493+
it("Can successfully create a DataFrame from an Array with date object", function () {
494+
let data = [ [ "Alice", 2, new Date(2019, 1, 1) ],
495+
[ "Bob", 5, new Date(2019, 1, 2) ],
496+
[ "Charlie", 30, new Date(2019, 1, 3) ],
497+
[ "Dennis", 89, new Date(2019, 1, 4) ] ];
498+
let columns = [ "Name", "Count", "Date" ];
499+
500+
let df = new dfd.NDframe({ data, columns, isSeries: false });
501+
let dfDtypes = [ 'string', 'int32', 'datetime' ];
502+
assert.deepEqual(df.dtypes, dfDtypes);
503+
// @ts-ignore
504+
assert.deepEqual(df.values, data);
505+
assert.deepEqual(df.columns, columns);
506+
});
507+
});
508+
492509
});

0 commit comments

Comments
 (0)