Skip to content

Commit 52ca0c4

Browse files
committed
feat: Added diff() function
Calculate difference between rows, columns, series or another dataframe
1 parent 0baf658 commit 52ca0c4

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

src/danfojs-base/core/frame.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,106 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
13331333

13341334
}
13351335

1336+
/**
1337+
* Return difference of DataFrame with other.
1338+
* @param other DataFrame, Series, Array or Scalar number (positive numbers are preceding rows, negative are following rows) to compare difference with.
1339+
* @param options.axis 0 or 1. If 0, compute the difference column-wise, if 1, row-wise
1340+
* @param options.inplace Boolean indicating whether to perform the operation inplace or not. Defaults to false
1341+
* @example
1342+
* ```
1343+
* const df = new DataFrame([[1, 2, 3, 4, 5, 6], [1, 1, 2, 3, 5, 8], [1, 4, 9, 16, 25, 36]], { columns: ['A', 'B', 'C'] })
1344+
*
1345+
* // Difference with previous row
1346+
* const df0 = df.diff(1)
1347+
* console.log(df0)
1348+
*
1349+
* // Difference with previous column
1350+
* const df1 = df.diff(1, {axis: 0})
1351+
* console.log(df1)
1352+
*
1353+
* // Difference with previous 3rd previous row
1354+
* const df2 = df.diff(3)
1355+
* console.log(df2)
1356+
*
1357+
* // Difference with following row
1358+
* const df3 = df.diff(-1)
1359+
* console.log(df3)
1360+
*
1361+
* // Difference with another DataFrame
1362+
* const df4 = df.diff(df3)
1363+
* console.log(df4)
1364+
* ```
1365+
*/
1366+
diff(other: DataFrame | Series | number[] | number, options?: { axis?: 0 | 1, inplace?: boolean }): DataFrame
1367+
diff(other: DataFrame | Series | number[] | number, options?: { axis?: 0 | 1, inplace?: boolean }): DataFrame | void {
1368+
const { inplace, axis } = { inplace: false, axis: 1, ...options }
1369+
1370+
if (this.$frameIsNotCompactibleForArithmeticOperation()) {
1371+
throw Error("TypeError: diff operation is not supported for string dtypes");
1372+
}
1373+
1374+
if ([0, 1].indexOf(axis) === -1) {
1375+
throw Error("ParamError: Axis must be 0 or 1");
1376+
}
1377+
1378+
if (other === 0) {
1379+
return this;
1380+
}
1381+
1382+
if (typeof other === "number" && axis === 1) {
1383+
const orig_tensor = this.tensor.clone();
1384+
let unit = [NaN];
1385+
for (let i = 1; i < orig_tensor.shape[orig_tensor.rank - 1]; i++) {
1386+
unit.push(NaN);
1387+
}
1388+
let diff_array: any[] = orig_tensor.arraySync();
1389+
if (other > 0) {
1390+
for (let i = 0; i < other; i++) {
1391+
diff_array.unshift(unit);
1392+
diff_array.pop();
1393+
}
1394+
}
1395+
else if (other < 0) {
1396+
for (let i = 0; i > other; i--) {
1397+
diff_array.push(unit);
1398+
diff_array.shift();
1399+
}
1400+
}
1401+
const diff_tensor = tensorflow.tensor2d(diff_array, orig_tensor.shape);
1402+
return this.$MathOps([orig_tensor, diff_tensor], "sub", inplace);
1403+
}
1404+
1405+
if (typeof other === "number" && axis === 0) {
1406+
const orig_df = new DataFrame(this.tensor.clone());
1407+
const orig_tensor = orig_df.T.tensor.clone();
1408+
let unit = [NaN];
1409+
for (let i = 1; i < orig_tensor.shape[orig_tensor.rank - 1]; i++) {
1410+
unit.push(NaN);
1411+
}
1412+
let diff_array: any[] = orig_tensor.arraySync();
1413+
if (other > 0) {
1414+
for (let i = 0; i < other; i++) {
1415+
diff_array.unshift(unit);
1416+
diff_array.pop();
1417+
}
1418+
}
1419+
else if (other < 0) {
1420+
for (let i = 0; i > other; i--) {
1421+
diff_array.push(unit);
1422+
diff_array.shift();
1423+
}
1424+
}
1425+
const diff_tensor = tensorflow.tensor2d(diff_array, orig_tensor.shape);
1426+
const diff_df = this.$MathOps([orig_tensor, diff_tensor], "sub", inplace) as DataFrame;
1427+
return diff_df.T;
1428+
}
1429+
1430+
if (other instanceof DataFrame || other instanceof Series) {
1431+
const tensors = this.$getTensorsForArithmeticOperationByAxis(other, axis);
1432+
return this.$MathOps(tensors, "sub", inplace);
1433+
}
1434+
}
1435+
13361436
/**
13371437
* Return the absolute value of elements in a DataFrame.
13381438
* @param options.inplace Boolean indicating whether to perform the operation inplace or not. Defaults to false

0 commit comments

Comments
 (0)