import Papa from "papaparse" ; import { KobraError } from "./blockUtils" ; function parseNumberWithFallback ( n ) { const parsed = Number ( n ) ; return isNaN ( parsed ) ? n : parsed ; } export class DataFrame { data : any [ ] [ ] | undefined ; headers : string [ ] ; isTranspose : boolean ; constructor ( ) { this . headers = [ ] ; this . data = [ [ ] ] ; this . isTranspose = false ; } loadData ( headers , data ) { this . headers = headers ; this . data = data ; } read_csv ( dataStr ) { let parsedData = Papa . parse < string [ ] > ( dataStr ) . data ; const headers = parsedData [ 0 ] ; const dataset = parsedData . slice ( 1 , parsedData . length ) . map ( ( row ) => row . map ( ( cell ) => parseNumberWithFallback ( cell ) ) ) ; this . headers = headers ; this . data = dataset ; this . isTranspose = false ; } transpose ( ) { if ( ! this . isTranspose ) { this . isTranspose = true ; } else { this . isTranspose = false ; } if ( this . data !== undefined ) { this . data = this . data [ 0 ] . map ( ( _ , colIndex ) => this . data . map ( ( row ) => row [ colIndex ] ) ) ; } } loc ( columnsSelected ) { if ( ! this . isTranspose ) { this . transpose ( ) ; } const indexes = columnsSelected . map ( ( col ) => this . headers . indexOf ( col ) ) ; indexes . forEach ( ( colIndex , inputIndex ) => { if ( colIndex === - 1 ) { throw new KobraError ( `Column ${ columnsSelected [ inputIndex ] } doesn't exist in the DataFrame` , "Try looking at what columns the dataset has in the Datasets tab" ) ; } } ) ; const returnDF = new DataFrame ( ) ; returnDF . headers = columnsSelected ; returnDF . data = indexes . map ( ( index ) => this . data [ index ] ) ; return returnDF ; } drop ( cols ) { const colsToKeep = [ ] ; for ( let i = 0 ; i < this . headers . length ; i ++ ) { for ( let e = 0 ; i < cols . length ; e ++ ) { if ( this . headers [ i ] !== cols [ e ] ) { colsToKeep . push ( this . headers [ 0 ] ) ; } } } return this . loc ( colsToKeep ) ; } trainTestSplit ( splitRatio ) { if ( ! this . isTranspose ) { this . transpose ( ) ; } console . log ( splitRatio ) ; } clone ( ) { let df = new DataFrame ( ) ; df . loadData ( this . headers , this . data as any [ ] [ ] ) ; return df ; } standardize ( arrs ) { this . transpose ( ) ; for ( let i = 0 ; i < this . headers . length ; i ++ ) { for ( let j = 0 ; j < arrs . length ; j ++ ) { if ( this . headers [ i ] === arrs [ j ] ) { if ( ! ( this . data === undefined ) ) { this . data [ i ] = this . standardizeArr ( this . data [ i ] ) ; console . log ( this . data [ i ] ) ; } } } } this . transpose ( ) ; } normalize ( ) { } private standardizeArr ( arr ) { let mean = this . calcMean ( arr ) ; let sd = this . calcSD ( arr ) ; for ( let i = 0 ; i < arr . length ; i ++ ) { arr [ i ] = ( arr [ i ] - mean ) / sd ; } return arr ; } private normalizeArr ( arr ) { return arr ; } private calcMean ( arr ) { return arr . reduce ( ( a , b ) => a + b ) / arr . length ; } private calcSD ( arr ) { const n = arr . length ; const mean = arr . reduce ( ( a , b ) => a + b ) / n ; return Math . sqrt ( arr . map ( ( x ) => Math . pow ( x - mean , 2 ) ) . reduce ( ( a , b ) => a + b ) / n ) ; } }