@@ -329,6 +329,9 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
329329 case 'div' :
330330 tensorResult = tensors [ 0 ] . div ( tensors [ 1 ] )
331331 break ;
332+ case 'divNoNan' :
333+ tensorResult = tensors [ 0 ] . divNoNan ( tensors [ 1 ] )
334+ break ;
332335 case 'mul' :
333336 tensorResult = tensors [ 0 ] . mul ( tensors [ 1 ] )
334337 break ;
@@ -726,6 +729,36 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
726729 return this . $MathOps ( tensors , "div" , inplace )
727730
728731
732+ }
733+
734+ /**
735+ * Return division of DataFrame with other, returns 0 if denominator is 0.
736+ * @param other DataFrame, Series, Array or Scalar number to divide with.
737+ * @param options.axis 0 or 1. If 0, compute the division column-wise, if 1, row-wise
738+ * @param options.inplace Boolean indicating whether to perform the operation inplace or not. Defaults to false
739+ * @example
740+ * ```
741+ * const df = new DataFrame([[1, 2], [3, 4]], { columns: ['A', 'B'] })
742+ * const df2 = df.divNoNan(2)
743+ * df2.print()
744+ * ```
745+ */
746+ divNoNan ( other : DataFrame | Series | number [ ] | number , options ?: { axis ?: 0 | 1 , inplace ?: boolean } ) : DataFrame
747+ divNoNan ( other : DataFrame | Series | number [ ] | number , options ?: { axis ?: 0 | 1 , inplace ?: boolean } ) : DataFrame | void {
748+ const { inplace, axis } = { inplace : false , axis : 1 , ...options }
749+
750+ if ( this . $frameIsNotCompactibleForArithmeticOperation ( ) ) {
751+ throw Error ( "TypeError: div operation is not supported for string dtypes" ) ;
752+ }
753+
754+ if ( [ 0 , 1 ] . indexOf ( axis ) === - 1 ) {
755+ throw Error ( "ParamError: Axis must be 0 or 1" ) ;
756+ }
757+
758+ const tensors = this . $getTensorsForArithmeticOperationByAxis ( other , axis ) ;
759+ return this . $MathOps ( tensors , "divNoNan" , inplace )
760+
761+
729762 }
730763
731764 /**
@@ -1333,6 +1366,109 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
13331366
13341367 }
13351368
1369+ /**
1370+ * Return percentage difference of DataFrame with other.
1371+ * @param other DataFrame, Series, Array or Scalar number (positive numbers are preceding rows, negative are following rows) to compare difference with.
1372+ * @param options.axis 0 or 1. If 0, compute the difference column-wise, if 1, row-wise
1373+ * @param options.inplace Boolean indicating whether to perform the operation inplace or not. Defaults to false
1374+ * @example
1375+ * ```
1376+ * 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'] })
1377+ *
1378+ * // Difference with previous row
1379+ * const df0 = df.pct_change(1)
1380+ * console.log(df0)
1381+ *
1382+ * // Difference with previous column
1383+ * const df1 = df.pct_change(1, {axis: 0})
1384+ * console.log(df1)
1385+ *
1386+ * // Difference with previous 3rd previous row
1387+ * const df2 = df.pct_change(3)
1388+ * console.log(df2)
1389+ *
1390+ * // Difference with following row
1391+ * const df3 = df.pct_change(-1)
1392+ * console.log(df3)
1393+ *
1394+ * // Difference with another DataFrame
1395+ * const df4 = df.pct_change(df3)
1396+ * console.log(df4)
1397+ * ```
1398+ */
1399+ pct_change ( other : DataFrame | Series | number [ ] | number , options ?: { axis ?: 0 | 1 , inplace ?: boolean } ) : DataFrame
1400+ pct_change ( other : DataFrame | Series | number [ ] | number , options ?: { axis ?: 0 | 1 , inplace ?: boolean } ) : DataFrame | void {
1401+ const { inplace, axis } = { inplace : false , axis : 1 , ...options }
1402+
1403+ if ( this . $frameIsNotCompactibleForArithmeticOperation ( ) ) {
1404+ throw Error ( "TypeError: pct_change operation is not supported for string dtypes" ) ;
1405+ }
1406+
1407+ if ( [ 0 , 1 ] . indexOf ( axis ) === - 1 ) {
1408+ throw Error ( "ParamError: Axis must be 0 or 1" ) ;
1409+ }
1410+
1411+ if ( other === 0 ) {
1412+ return this ;
1413+ }
1414+
1415+ if ( typeof other === "number" && axis === 1 ) {
1416+ const orig_tensor = this . tensor . clone ( ) ;
1417+ let unit = [ NaN ] ;
1418+ for ( let i = 1 ; i < orig_tensor . shape [ orig_tensor . rank - 1 ] ; i ++ ) {
1419+ unit . push ( NaN ) ;
1420+ }
1421+ let pct_array : any [ ] = orig_tensor . arraySync ( ) ;
1422+ if ( other > 0 ) {
1423+ for ( let i = 0 ; i < other ; i ++ ) {
1424+ pct_array . unshift ( unit ) ;
1425+ pct_array . pop ( ) ;
1426+ }
1427+ }
1428+ else if ( other < 0 ) {
1429+ for ( let i = 0 ; i > other ; i -- ) {
1430+ pct_array . push ( unit ) ;
1431+ pct_array . shift ( ) ;
1432+ }
1433+ }
1434+ const pct_tensor = tensorflow . tensor2d ( pct_array , orig_tensor . shape ) ;
1435+ const pct_df = ( this . $MathOps ( [ orig_tensor , pct_tensor ] , "divNoNan" , inplace ) as DataFrame ) . sub ( 1 ) ;
1436+ return pct_df ;
1437+ }
1438+
1439+ if ( typeof other === "number" && axis === 0 ) {
1440+ const orig_df = new DataFrame ( this . tensor . clone ( ) ) ;
1441+ const orig_tensor = orig_df . T . tensor . clone ( ) ;
1442+ let unit = [ NaN ] ;
1443+ for ( let i = 1 ; i < orig_tensor . shape [ orig_tensor . rank - 1 ] ; i ++ ) {
1444+ unit . push ( NaN ) ;
1445+ }
1446+ let pct_array : any [ ] = orig_tensor . arraySync ( ) ;
1447+ if ( other > 0 ) {
1448+ for ( let i = 0 ; i < other ; i ++ ) {
1449+ pct_array . unshift ( unit ) ;
1450+ pct_array . pop ( ) ;
1451+ }
1452+ }
1453+ else if ( other < 0 ) {
1454+ for ( let i = 0 ; i > other ; i -- ) {
1455+ pct_array . push ( unit ) ;
1456+ pct_array . shift ( ) ;
1457+ }
1458+ }
1459+ const pct_tensor = tensorflow . tensor2d ( pct_array , orig_tensor . shape ) ;
1460+ const pct_df_flipped = ( this . $MathOps ( [ orig_tensor , pct_tensor ] , "divNoNan" , inplace ) as DataFrame ) . sub ( 1 ) ;
1461+ const pct_df = pct_df_flipped . T ;
1462+ return pct_df ;
1463+ }
1464+
1465+ if ( other instanceof DataFrame || other instanceof Series ) {
1466+ const tensors = this . $getTensorsForArithmeticOperationByAxis ( other , axis ) ;
1467+ const pct_df = ( this . $MathOps ( tensors , "divNoNan" , inplace ) as DataFrame ) . sub ( 1 ) ;
1468+ return pct_df ;
1469+ }
1470+ }
1471+
13361472 /**
13371473 * Return difference of DataFrame with other.
13381474 * @param other DataFrame, Series, Array or Scalar number (positive numbers are preceding rows, negative are following rows) to compare difference with.
0 commit comments