Skip to content

Commit b712f70

Browse files
authored
Merge pull request #417 from igonro/fix-empty-dataframe-not-adding-columns
Fix empty dataframe not adding columns information
2 parents 746c4cc + b97bc7d commit b712f70

File tree

6 files changed

+166
-5
lines changed

6 files changed

+166
-5
lines changed

src/danfojs-base/core/generic.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ export default class NDframe implements NDframeInterface {
7272
}
7373

7474
if (data === undefined || (Array.isArray(data) && data.length === 0)) {
75-
this.loadArrayIntoNdframe({ data: [], index: [], columns: [], dtypes: [] });
75+
if (columns === undefined) columns = [];
76+
if (dtypes === undefined) dtypes = [];
77+
if (columns.length === 0 && dtypes.length !== 0) ErrorThrower.throwDtypeWithoutColumnError();
78+
this.loadArrayIntoNdframe({ data: [], index: [], columns: columns, dtypes: dtypes });
7679
} else if (utils.is1DArray(data)) {
7780
this.loadArrayIntoNdframe({ data, index, columns, dtypes });
7881
} else {
@@ -306,6 +309,7 @@ export default class NDframe implements NDframeInterface {
306309
*/
307310
$setColumnNames(columns?: string[]) {
308311

312+
// console.log(columns);
309313
if (this.$isSeries) {
310314
if (columns) {
311315
if (this.$data.length != 0 && columns.length != 1 && typeof columns != 'string') {
@@ -322,7 +326,7 @@ export default class NDframe implements NDframeInterface {
322326

323327
ErrorThrower.throwColumnNamesLengthError(this, columns)
324328
}
325-
if (Array.from(new Set(columns)).length !== this.shape[1]) {
329+
if (Array.from(new Set(columns)).length !== columns.length) {
326330
ErrorThrower.throwColumnDuplicateError()
327331
}
328332

@@ -337,7 +341,10 @@ export default class NDframe implements NDframeInterface {
337341
* Returns the shape of the NDFrame. Shape is determined by [row length, column length]
338342
*/
339343
get shape(): Array<number> {
340-
if (this.$data.length === 0) return [0, 0]
344+
if (this.$data.length === 0) {
345+
if (this.$columns.length === 0) return [0, 0];
346+
else return [0, this.$columns.length];
347+
}
341348
if (this.$isSeries) {
342349
return [this.$data.length, 1];
343350
} else {

src/danfojs-base/shared/errors.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class ErrorThrower {
5151
throw new Error(msg)
5252
}
5353

54+
throwDtypeWithoutColumnError = (): void => {
55+
const msg = `DtypeError: columns parameter must be provided when dtypes parameter is provided`
56+
throw new Error(msg)
57+
}
58+
5459
throwColumnLengthError = (ndframe: NDframe | DataFrame, arrLen: number): void => {
5560
const msg = `ParamError: Column data length mismatch. You provided data with length ${arrLen} but Ndframe has column of length ${ndframe.shape[1]}`
5661
throw new Error(msg)

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,24 @@ describe("Generic (NDFrame)", function () {
407407
describe("Empty NDFrame", function () {
408408
it("Can successfully create an empty NDframe from empty array", function () {
409409
let data = [];
410-
let sf = new dfd.NDframe({ data, isSeries: false });
410+
let df = new dfd.NDframe({ data, isSeries: false });
411+
assert.deepEqual(df.shape, [ 0, 0 ]);
412+
assert.deepEqual(df.columns, []);
413+
assert.deepEqual(df.dtypes, []);
414+
assert.deepEqual(df.values, []);
415+
let sf = new dfd.NDframe({ data, isSeries: true });
411416
assert.deepEqual(sf.shape, [ 0, 0 ]);
412417
assert.deepEqual(sf.columns, []);
413418
assert.deepEqual(sf.dtypes, []);
414419
assert.deepEqual(sf.values, []);
415420
});
416421
it("Can successfully create an empty NDframe from undefined data", function () {
417422
let data = undefined;
423+
let df = new dfd.NDframe({ data, isSeries: false });
424+
assert.deepEqual(df.shape, [ 0, 0 ]);
425+
assert.deepEqual(df.columns, []);
426+
assert.deepEqual(df.dtypes, []);
427+
assert.deepEqual(df.values, []);
418428
let sf = new dfd.NDframe({ data, isSeries: true });
419429
assert.deepEqual(sf.shape, [ 0, 0 ]);
420430
assert.deepEqual(sf.columns, []);
@@ -423,12 +433,60 @@ describe("Generic (NDFrame)", function () {
423433
});
424434

425435
it("Can successfully create an empty NDframe", function () {
436+
let df = new dfd.NDframe({ isSeries: false });
437+
assert.deepEqual(df.shape, [ 0, 0 ]);
438+
assert.deepEqual(df.columns, []);
439+
assert.deepEqual(df.dtypes, []);
440+
assert.deepEqual(df.values, []);
426441
let sf = new dfd.NDframe({ isSeries: true });
427442
assert.deepEqual(sf.shape, [ 0, 0 ]);
428443
assert.deepEqual(sf.columns, []);
429444
assert.deepEqual(sf.dtypes, []);
430445
assert.deepEqual(sf.values, []);
431446
});
447+
448+
it("Can successfully create an empty NDframe with columns names", function () {
449+
let data = [];
450+
let df = new dfd.NDframe({ data, columns: [ "A", "B", "C" ], isSeries: false });
451+
assert.deepEqual(df.shape, [ 0, 3 ]);
452+
assert.deepEqual(df.columns, [ "A", "B", "C" ]);
453+
assert.deepEqual(df.dtypes, []);
454+
assert.deepEqual(df.values, []);
455+
let sf = new dfd.NDframe({ data, columns: [ "A" ], isSeries: true });
456+
assert.deepEqual(sf.shape, [ 0, 1 ]);
457+
assert.deepEqual(sf.columns, [ "A" ]);
458+
assert.deepEqual(sf.dtypes, []);
459+
assert.deepEqual(sf.values, []);
460+
});
461+
462+
it("Can successfully create an empty NDframe with columns names and dtypes", function () {
463+
let data = [];
464+
let df = new dfd.NDframe({ data, columns: [ "A", "B", "C" ], dtypes: [ "string", "string", "int32" ], isSeries: false });
465+
assert.deepEqual(df.shape, [ 0, 3 ]);
466+
assert.deepEqual(df.columns, [ "A", "B", "C" ]);
467+
assert.deepEqual(df.dtypes, [ "string", "string", "int32" ]);
468+
assert.deepEqual(df.values, []);
469+
let sf = new dfd.NDframe({ data, columns: [ "A" ], dtypes: [ "string" ], isSeries: true });
470+
assert.deepEqual(sf.shape, [ 0, 1 ]);
471+
assert.deepEqual(sf.columns, [ "A" ]);
472+
assert.deepEqual(sf.dtypes, [ "string" ]);
473+
assert.deepEqual(sf.values, []);
474+
});
475+
476+
it("Cannot successfully create an empty NDframe with only columns dtypes", function () {
477+
let data = [];
478+
assert.throws(
479+
() => new dfd.NDframe({ data, dtypes: [ "string", "string", "int32" ], isSeries: false }),
480+
Error,
481+
"DtypeError: columns parameter must be provided when dtypes parameter is provided"
482+
);
483+
assert.throws(
484+
() => new dfd.NDframe({ data, dtypes: [ "string" ], isSeries: true }),
485+
Error,
486+
"DtypeError: columns parameter must be provided when dtypes parameter is provided"
487+
);
488+
});
489+
432490
});
433491

434492
});

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,22 @@ describe("Iloc and Loc based Indexing", function () {
408408
assert.deepEqual(subDf.values, result);
409409

410410
});
411+
412+
it("loc with no matches create a Empty DataFrame conserving columns information", function () {
413+
const data = {
414+
"Name": [ "Apples", "Mango", "Banana", "Pear" ],
415+
"Count": [ 21, 5, 30, 10 ],
416+
"Price": [ 200, 300, 40, 250 ]
417+
};
418+
const df = new dfd.DataFrame(data);
419+
const subDf = df.loc({ rows: df["Count"].gt(50) });
420+
421+
assert.deepEqual(subDf.values, []);
422+
assert.deepEqual(subDf.shape, [ 0, 3 ]);
423+
assert.deepEqual(subDf.columns, [ "Name", "Count", "Price" ]);
424+
assert.deepEqual(subDf.dtypes, [ "string", "int32", "int32" ]);
425+
426+
});
411427
});
412428

413429
});

src/danfojs-node/test/core/generic.test.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,24 @@ describe("Generic (NDFrame)", function () {
344344
describe("Empty NDFrame", function () {
345345
it("Can successfully create an empty NDframe from empty array", function () {
346346
let data: any = [];
347-
let sf = new NDframe({ data, isSeries: false });
347+
let df = new NDframe({ data, isSeries: false });
348+
assert.deepEqual(df.shape, [0, 0]);
349+
assert.deepEqual(df.columns, []);
350+
assert.deepEqual(df.dtypes, []);
351+
assert.deepEqual(df.values, []);
352+
let sf = new NDframe({ data, isSeries: true });
348353
assert.deepEqual(sf.shape, [0, 0]);
349354
assert.deepEqual(sf.columns, []);
350355
assert.deepEqual(sf.dtypes, []);
351356
assert.deepEqual(sf.values, []);
352357
});
353358
it("Can successfully create an empty NDframe from undefined data", function () {
354359
let data = undefined;
360+
let df = new NDframe({ data, isSeries: false });
361+
assert.deepEqual(df.shape, [0, 0]);
362+
assert.deepEqual(df.columns, []);
363+
assert.deepEqual(df.dtypes, []);
364+
assert.deepEqual(df.values, []);
355365
let sf = new NDframe({ data, isSeries: true });
356366
assert.deepEqual(sf.shape, [0, 0]);
357367
assert.deepEqual(sf.columns, []);
@@ -360,11 +370,59 @@ describe("Generic (NDFrame)", function () {
360370
});
361371

362372
it("Can successfully create an empty NDframe", function () {
373+
let df = new NDframe({ data: [], isSeries: false });
374+
assert.deepEqual(df.shape, [0, 0]);
375+
assert.deepEqual(df.columns, []);
376+
assert.deepEqual(df.dtypes, []);
377+
assert.deepEqual(df.values, []);
363378
let sf = new NDframe({ data: [], isSeries: true });
364379
assert.deepEqual(sf.shape, [0, 0]);
365380
assert.deepEqual(sf.columns, []);
366381
assert.deepEqual(sf.dtypes, []);
367382
assert.deepEqual(sf.values, []);
368383
});
384+
385+
it("Can successfully create an empty NDframe with columns names", function () {
386+
let data: any = [];
387+
let df = new NDframe({ data, columns: [ "A", "B", "C" ], isSeries: false });
388+
assert.deepEqual(df.shape, [ 0, 3 ]);
389+
assert.deepEqual(df.columns, [ "A", "B", "C" ]);
390+
assert.deepEqual(df.dtypes, []);
391+
assert.deepEqual(df.values, []);
392+
let sf = new NDframe({ data, columns: [ "A" ], isSeries: true });
393+
assert.deepEqual(sf.shape, [ 0, 1 ]);
394+
assert.deepEqual(sf.columns, [ "A" ]);
395+
assert.deepEqual(sf.dtypes, []);
396+
assert.deepEqual(sf.values, []);
397+
});
398+
399+
it("Can successfully create an empty NDframe with columns names and dtypes", function () {
400+
let data: any = [];
401+
let df = new NDframe({ data, columns: [ "A", "B", "C" ], dtypes: [ "string", "string", "int32" ], isSeries: false });
402+
assert.deepEqual(df.shape, [ 0, 3 ]);
403+
assert.deepEqual(df.columns, [ "A", "B", "C" ]);
404+
assert.deepEqual(df.dtypes, [ "string", "string", "int32" ]);
405+
assert.deepEqual(df.values, []);
406+
let sf = new NDframe({ data, columns: [ "A" ], dtypes: [ "string" ], isSeries: true });
407+
assert.deepEqual(sf.shape, [ 0, 1 ]);
408+
assert.deepEqual(sf.columns, [ "A" ]);
409+
assert.deepEqual(sf.dtypes, [ "string" ]);
410+
assert.deepEqual(sf.values, []);
411+
});
412+
413+
it("Cannot successfully create an empty NDframe with only columns dtypes", function () {
414+
let data: any = [];
415+
assert.throws(
416+
() => new NDframe({ data, dtypes: [ "string", "string", "int32" ], isSeries: false }),
417+
Error,
418+
"DtypeError: columns parameter must be provided when dtypes parameter is provided"
419+
);
420+
assert.throws(
421+
() => new NDframe({ data, dtypes: [ "string" ], isSeries: true }),
422+
Error,
423+
"DtypeError: columns parameter must be provided when dtypes parameter is provided"
424+
);
425+
});
426+
369427
});
370428
});

src/danfojs-node/test/core/indexing.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,23 @@ describe("Iloc and Loc based Indexing", function () {
411411
assert.deepEqual(subDf.values, result);
412412

413413
});
414+
415+
it("loc with no matches create a Empty DataFrame conserving columns information", function () {
416+
const data = {
417+
"Name": [ "Apples", "Mango", "Banana", "Pear" ],
418+
"Count": [ 21, 5, 30, 10 ],
419+
"Price": [ 200, 300, 40, 250 ]
420+
};
421+
const df = new DataFrame(data);
422+
const subDf = df.loc({ rows: df["Count"].gt(50) });
423+
424+
assert.deepEqual(subDf.values, []);
425+
assert.deepEqual(subDf.shape, [ 0, 3 ]);
426+
assert.deepEqual(subDf.columns, [ "Name", "Count", "Price" ]);
427+
assert.deepEqual(subDf.dtypes, [ "string", "int32", "int32" ]);
428+
429+
});
430+
414431
})
415432

416433
});

0 commit comments

Comments
 (0)