danfojs icon indicating copy to clipboard operation
danfojs copied to clipboard

replace() does not accept falsy string or number values

Open babennettdev opened this issue 2 years ago • 2 comments

Describe the bug Neither Series nor DataFrame's replace() function accept falsy string or number values as a parameter for oldValue or newValue. This does not apply to booleans.

To Reproduce Steps to reproduce the behavior:

  1. Import danfojs-node
  2. Create a new DataFrame or Series (values and columns do not matter for the sake of this reproduction).
  3. Run any of the following to reproduce the bug:
  • df.replace(0, 1)
  • df.replace(0, 1)
  • df.replace('', 'a')
  • df.replace('a', '')

The following can be run with Quokka to quickly visualize the issue:

import * as danfo from 'danfojs-node';

const df = new danfo.DataFrame([
  { bool: false, str: '', val: 0 },
  { bool: true, str: 'a', val: 1 },
  { bool: true, str: 'b', val: 2 },
  { bool: true, str: 'c', val: 3 },
]);

df.replace(false, true);

df.replace(true, false);

df.replace(0, 1);

df.replace(1, 0);

df.replace('', 'a');

df.replace('a', '');

Expected behavior Empty strings ('') and zero (0) should be valid inputs for replace()'s oldValue or newValue.

NOTE: I do not know if undefined, null, or NaN should apply to this function, as fillNa() covers replacing those values.

Screenshots Screenshot 2023-02-08 at 9 59 53 AM

Desktop (please complete the following information):

  • OS: macOS
  • Browser: N/A
  • Version: Ventura 13.1

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A
  • Browser: N/A
  • Version: N/A

Additional context Looking for advice as to how undefined, null, and NaN should be handled for this function as that functionality is covered by the fillNa() function and the maintainers may not wish to duplicate that functionality.

The offending code is present in both src/danfojs-base/core/series.ts and src/danfojs-base/core/frame.ts:

if (!oldValue && typeof oldValue !== 'boolean') {
            throw Error(`Params Error: Must specify param 'oldValue' to replace`);
        }

        if (!newValue && typeof newValue !== 'boolean') {
            throw Error(`Params Error: Must specify param 'newValue' to replace with`);
        }

I would be happy to open a pull request to fix this issue.

babennettdev avatar Feb 08 '23 15:02 babennettdev

Hi, I need to replace '?' values by NaN to operate, How can I do it?

nonodev96 avatar Jun 27 '23 19:06 nonodev96

@nonodev96 In the interim, you can use an apply function as a workaround, e.g.

sf1 = dfd.Series({ A: ["?", "Hello", "world"]});
sf1 = sf1.apply((val) => { if (val == "?") {return null;} return val;})

fogarty-ben avatar Oct 02 '23 22:10 fogarty-ben