From 7200a40278801d0f646401e1064f507bd2c29543 Mon Sep 17 00:00:00 2001 From: Blake Bennett Date: Thu, 23 Feb 2023 11:56:49 -0500 Subject: [PATCH 1/4] Added additonal tests for DataFrame.replace() --- src/danfojs-node/test/core/frame.test.ts | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/danfojs-node/test/core/frame.test.ts b/src/danfojs-node/test/core/frame.test.ts index 9806a124..a371b00b 100644 --- a/src/danfojs-node/test/core/frame.test.ts +++ b/src/danfojs-node/test/core/frame.test.ts @@ -2155,6 +2155,70 @@ describe("DataFrame", function () { assert.deepEqual(df.values, expected); }); + it("Replace oldValue supports falsy numbers (0)", function () { + const data1 = [[0, 19, 84, 0], [65, 0, 0, 37]]; + const df = new DataFrame(data1); + const expected = [[1, 19, 84, 1], [65, 1, 1, 37]]; + const df_rep = df.replace(0, 1) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace oldValue supports falsy numbers (NaN)", function () { + const data1 = [[NaN, 19, 84, NaN], [65, NaN, NaN, 37]]; + const df = new DataFrame(data1); + const expected = [[1, 19, 84, 1], [65, 1, 1, 37]]; + const df_rep = df.replace(NaN, 1) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace oldValue supports falsy strings", function () { + const data1 = [['', 'hello', 'world', ''], ['foo', '', '', 'bar']]; + const df = new DataFrame(data1); + const expected = [['danfo', 'hello', 'world', 'danfo'], ['foo', 'danfo', 'danfo', 'bar']]; + const df_rep = df.replace('', 'danfo') as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace oldValue supports falsy booleans", function () { + const data1 = [[false, 'hello', 'world', false], ['foo', false, false, 'bar']]; + const df = new DataFrame(data1); + const expected = [[true, 'hello', 'world', true], ['foo', true, true, 'bar']]; + const df_rep = df.replace(false, true) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace newValue supports falsy numbers (0)", function () { + const data1 = [[1, 19, 84, 1], [65, 1, 1, 37]]; + const df = new DataFrame(data1); + const expected = [[0, 19, 84, 0], [65, 0, 0, 37]]; + const df_rep = df.replace(1, 0) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace newValue supports falsy numbers (NaN)", function () { + const data1 = [[1, 19, 84, 1], [65, 1, 1, 37]]; + const df = new DataFrame(data1); + const expected = [[NaN, 19, 84, NaN], [65, NaN, NaN, 37]]; + const df_rep = df.replace(1, NaN) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace newValue supports falsy strings", function () { + const data1 = [['danfo', 'hello', 'world', 'danfo'], ['foo', 'danfo', 'danfo', 'bar']]; + const df = new DataFrame(data1); + const expected = [['', 'hello', 'world', ''], ['foo', '', '', 'bar']]; + const df_rep = df.replace('danfo', '') as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + + it("Replace newValue supports falsy booleans", function () { + const data1 = [[true, 'hello', 'world', true], ['foo', true, true, 'bar']]; + const df = new DataFrame(data1); + const expected = [[false, 'hello', 'world', false], ['foo', false, false, 'bar']]; + const df_rep = df.replace(true, false) as DataFrame; + assert.deepEqual(df_rep.values, expected); + }); + }); describe("sum", function () { From 2db945a357d0c789c409759f0c57270a402191a1 Mon Sep 17 00:00:00 2001 From: Blake Bennett Date: Thu, 23 Feb 2023 12:06:44 -0500 Subject: [PATCH 2/4] Added additonal tests for Series.replace() --- src/danfojs-node/test/core/series.test.ts | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/danfojs-node/test/core/series.test.ts b/src/danfojs-node/test/core/series.test.ts index 808bc96f..4e7a898f 100644 --- a/src/danfojs-node/test/core/series.test.ts +++ b/src/danfojs-node/test/core/series.test.ts @@ -1171,6 +1171,7 @@ describe("Series Functions", () => { sf.replace("A", "boy", { inplace: true }); assert.deepEqual(sf.values, expected); }); + it("Replace values given in replace param with value (boolean type)", function () { const data1 = [true, true, false, false]; const sf = new Series(data1); @@ -1178,6 +1179,71 @@ describe("Series Functions", () => { sf.replace(true, false, { inplace: true }); assert.deepEqual(sf.values, expected); }); + + it("Replace oldValue supports falsy numbers (0)", function () { + const data1 = [0, 45, 56, 25, 23, 20, 0]; + const sf = new Series(data1); + const expected = [1, 45, 56, 25, 23, 20, 1]; + const dfRep = sf.replace(0, 1) + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace oldValue supports falsy numbers (NaN)", function () { + const data1 = [NaN, 45, 56, 25, 23, 20, NaN]; + const sf = new Series(data1); + const expected = [1, 45, 56, 25, 23, 20, 1]; + const dfRep = sf.replace(NaN, 1) + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace oldValue supports falsy strings", function () { + const data1 = ['', 'bar', 'baz']; + const sf = new Series(data1); + const expected = ['foo', 'bar', 'baz']; + const dfRep = sf.replace('', 'foo') + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace oldValue supports falsy booleans", function () { + const data1 = [true, false, true, false]; + const sf = new Series(data1); + const expected = [true, true, true, true]; + const dfRep = sf.replace(false, true) + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace newValue supports falsy numbers (0)", function () { + const data1 = [1, 45, 56, 25, 23, 20, 1]; + const sf = new Series(data1); + const expected = [0, 45, 56, 25, 23, 20, 0]; + const dfRep = sf.replace(1, 0) + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace newValue supports falsy numbers (NaN)", function () { + const data1 = [1, 45, 56, 25, 23, 20, 1]; + const sf = new Series(data1); + const expected = [NaN, 45, 56, 25, 23, 20, NaN]; + const dfRep = sf.replace(1, NaN) + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace newValue supports falsy strings", function () { + const data1 = ['foo', 'bar', 'baz']; + const sf = new Series(data1); + const expected = ['', 'bar', 'baz']; + const dfRep = sf.replace('foo', '') + assert.deepEqual(dfRep.values, expected); + }); + + it("Replace newValue supports falsy booleans", function () { + const data1 = [true, false, true, false]; + const sf = new Series(data1); + const expected = [false, false, false, false]; + const dfRep = sf.replace(true, false) + assert.deepEqual(dfRep.values, expected); + }); + // it("Throw error on wrong param passed", function () { // const data1 = ["A", "A", "A", "B", "B", "C", "C", "D"]; // const sf = new Series(data1); From 5e26647988dfa0e3a531362340eafdfa0ba3915f Mon Sep 17 00:00:00 2001 From: Blake Bennett Date: Thu, 23 Feb 2023 12:37:00 -0500 Subject: [PATCH 3/4] Updating Series.replace() and DataFrame.replace() tests to expect error when oldValue is NaN --- src/danfojs-node/test/core/frame.test.ts | 8 +++----- src/danfojs-node/test/core/series.test.ts | 7 +++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/danfojs-node/test/core/frame.test.ts b/src/danfojs-node/test/core/frame.test.ts index a371b00b..e41bd9e5 100644 --- a/src/danfojs-node/test/core/frame.test.ts +++ b/src/danfojs-node/test/core/frame.test.ts @@ -2163,12 +2163,10 @@ describe("DataFrame", function () { assert.deepEqual(df_rep.values, expected); }); - it("Replace oldValue supports falsy numbers (NaN)", function () { + it("Replace oldValue does not support NaN", function () { const data1 = [[NaN, 19, 84, NaN], [65, NaN, NaN, 37]]; const df = new DataFrame(data1); - const expected = [[1, 19, 84, 1], [65, 1, 1, 37]]; - const df_rep = df.replace(NaN, 1) as DataFrame; - assert.deepEqual(df_rep.values, expected); + assert.throws(() => df.replace(NaN, 1), Error, "Params Error: Param 'oldValue' does not support NaN. Use DataFrame.fillNa() instead."); }); it("Replace oldValue supports falsy strings", function () { @@ -2218,7 +2216,7 @@ describe("DataFrame", function () { const df_rep = df.replace(true, false) as DataFrame; assert.deepEqual(df_rep.values, expected); }); - + }); describe("sum", function () { diff --git a/src/danfojs-node/test/core/series.test.ts b/src/danfojs-node/test/core/series.test.ts index 4e7a898f..ac17d092 100644 --- a/src/danfojs-node/test/core/series.test.ts +++ b/src/danfojs-node/test/core/series.test.ts @@ -1188,12 +1188,11 @@ describe("Series Functions", () => { assert.deepEqual(dfRep.values, expected); }); - it("Replace oldValue supports falsy numbers (NaN)", function () { + it("Replace oldValue does not support NaN", function () { const data1 = [NaN, 45, 56, 25, 23, 20, NaN]; const sf = new Series(data1); - const expected = [1, 45, 56, 25, 23, 20, 1]; - const dfRep = sf.replace(NaN, 1) - assert.deepEqual(dfRep.values, expected); + assert.throws(() => sf.replace(NaN, 1), Error, "Params Error: Param 'oldValue' does not support NaN. Use Series.fillNa() instead."); + }); it("Replace oldValue supports falsy strings", function () { From 6fa9cb8a79a54c699d80c9f41205723477446bdc Mon Sep 17 00:00:00 2001 From: Blake Bennett Date: Thu, 23 Feb 2023 12:40:37 -0500 Subject: [PATCH 4/4] Updated Series.replace() and DataFrame.replace() to handle falsy numbers (0), falsy strings (''), and throw when oldValue is NaN. --- src/danfojs-base/core/frame.ts | 8 ++++++-- src/danfojs-base/core/series.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/danfojs-base/core/frame.ts b/src/danfojs-base/core/frame.ts index 13d8cc55..2f35c3d5 100644 --- a/src/danfojs-base/core/frame.ts +++ b/src/danfojs-base/core/frame.ts @@ -2759,11 +2759,15 @@ export default class DataFrame extends NDframe implements DataFrameInterface { ): DataFrame | void { const { columns, inplace } = { inplace: false, ...options } - if (!oldValue && typeof oldValue !== 'boolean') { + if (typeof oldValue === 'number' && isNaN(oldValue)) { + throw Error(`Params Error: Param 'oldValue' does not support NaN. Use DataFrame.fillNa() instead.`); + } + + if (!oldValue && typeof oldValue !== 'boolean' && typeof oldValue !== 'number' && typeof oldValue !== 'string') { throw Error(`Params Error: Must specify param 'oldValue' to replace`); } - if (!newValue && typeof newValue !== 'boolean') { + if (!newValue && typeof newValue !== 'boolean' && typeof newValue !== 'number' && typeof newValue !== 'string') { throw Error(`Params Error: Must specify param 'newValue' to replace with`); } diff --git a/src/danfojs-base/core/series.ts b/src/danfojs-base/core/series.ts index e42f169d..9db5f37a 100644 --- a/src/danfojs-base/core/series.ts +++ b/src/danfojs-base/core/series.ts @@ -1536,11 +1536,15 @@ export default class Series extends NDframe implements SeriesInterface { ): Series | void { const { inplace } = { inplace: false, ...options } - if (!oldValue && typeof oldValue !== 'boolean') { + if (typeof oldValue === 'number' && isNaN(oldValue)) { + throw Error(`Params Error: Param 'oldValue' does not support NaN. Use Series.fillNa() instead.`); + } + + if (!oldValue && typeof oldValue !== 'boolean' && typeof oldValue !== 'number' && typeof oldValue !== 'string') { throw Error(`Params Error: Must specify param 'oldValue' to replace`); } - if (!newValue && typeof newValue !== 'boolean') { + if (!newValue && typeof newValue !== 'boolean' && typeof newValue !== 'number' && typeof newValue !== 'string') { throw Error(`Params Error: Must specify param 'newValue' to replace with`); }