Description
Is your feature request related to a problem? Please describe.
I am unclear on the recommended way of type narrowing a dfd.Series ❘ dfd.DataFrame
object to a dfd.DataFrame
Describe the solution you'd like
e.g. this should work, or some other approach that achieves the type narrowing
if (!(multiMetricDf instanceof dfd.DataFrame)) {
throw new Error(
`Expected a DataFrame here but got ${multiMetricDf.constructor.name}`,
)
}
The above code snippet does not work as it can log " "Expected a DataFrame here but got DataFrame"" i.e. false positive, and I would like a solution like this to type narrow
Describe alternatives you've considered
const dfd = require("danfojs-node");
const json_data = [
{ A: 0.4612, B: 4.28283, C: -1.509, D: -1.1352 },
{ A: 0.5112, B: -0.22863, C: -3.39059, D: 1.1632 },
{ A: 0.6911, B: -0.82863, C: -1.5059, D: 2.1352 },
{ A: 0.4692, B: -1.28863, C: 4.5059, D: 4.1632 },
];
const df = new dfd.DataFrame(json_data)
const multiMetricDf = dfd.concat({
dfList: [df, df],
axis: 0,
})
multiMetricDf instanceof dfd.DataFrame // returns False
The above code snippet returns False
If there was a method to convert Series to DataFrame (#619) that would be a suitable workaround
Additional context
For working with Danfo, I think such type narrowing is essential
const dfd = require("danfojs-node");
function logPrototypeNames(obj: any): void {
let proto = Object.getPrototypeOf(obj);
while (proto) {
console.log(`Prototype constructor name: ${proto.constructor.name}`);
proto = Object.getPrototypeOf(proto);
}
}
const json_data = [
{ A: 0.4612, B: 4.28283, C: -1.509, D: -1.1352 },
{ A: 0.5112, B: -0.22863, C: -3.39059, D: 1.1632 },
{ A: 0.6911, B: -0.82863, C: -1.5059, D: 2.1352 },
{ A: 0.4692, B: -1.28863, C: 4.5059, D: 4.1632 },
];
const df = new dfd.DataFrame(json_data)
console.log("df is instance of DataFrame:", df instanceof dfd.DataFrame);
logPrototypeNames(df);
console.log()
const multiMetricDf = dfd.concat({
dfList: [df, df],
axis: 0,
})
multiMetricDf instanceof dfd.DataFrame
console.log("multiMetricDf is NOT instance of DataFrame:", multiMetricDf instanceof dfd.DataFrame);
logPrototypeNames(multiMetricDf);
console.log("here", multiMetricDf.ctypes)
Returns
df is instance of DataFrame: true
Prototype constructor name: DataFrame
Prototype constructor name: DataFrame
Prototype constructor name: NDframe
Prototype constructor name: Object
multiMetricDf is NOT instance of DataFrame: false
Prototype constructor name: DataFrame
Prototype constructor name: NDframe
Prototype constructor name: Object
So not sure what the problem is here.
This is my current workaround:
/**
* Allows type narrowing of Series to DataFrame
* https://github.com/javascriptdata/danfojs/issues/640
*
* @param df - DataFrame or Series
* @returns True if it has a ctypes attribute, expected on DataFrame but not Series
*/
function isDataFrame(df: unknown): df is dfd.DataFrame {
if (df instanceof dfd.Series) {
return false
}
if ((df as dfd.DataFrame).ctypes !== undefined) {
// ctypes attribute only exists on DataFrame
return true
} else {
return false
}
}