11import { Console } from "console" ;
22import DataFrame from "../core/frame"
33import { ArrayType1D , ArrayType2D } from "../shared/types"
4+ import { variance , std , median , mode , mean } from 'mathjs' ;
45import Utils from "../shared/utils" ;
56import concat from "../transformers/concat"
67
@@ -108,9 +109,7 @@ export default class Groupby {
108109 }
109110
110111 col ( colNames : ArrayType1D | undefined ) : Groupby {
111- type f = {
112- [ key : string ] : [ ]
113- }
112+
114113 if ( typeof colNames === "undefined" ) {
115114 colNames = this . columnName . filter ( ( _ , index ) => {
116115 return ! this . colIndex . includes ( index )
@@ -144,5 +143,129 @@ export default class Groupby {
144143 return gp
145144 }
146145
147-
146+ arithemetic ( operation : { [ key : string ] : string } | string ) : { [ key : string ] : { } } {
147+
148+ const opsName = [ "mean" , "sum" , "count" , "mode" , "std" , "var" , "cumsum" , "cumprod" ,
149+ "cummax" , "cummin" , "median" ] ;
150+ if ( typeof operation === "string" ) {
151+ if ( ! opsName . includes ( operation ) ) {
152+ throw new Error ( `group operation: ${ operation } is not valid` )
153+ }
154+ } else {
155+ Object . keys ( operation ) . forEach ( ( key ) => {
156+ let ops = operation [ key ]
157+ if ( ! opsName . includes ( ops ) ) {
158+ throw new Error ( `group operation: ${ ops } for column ${ key } is not valid` )
159+ }
160+ } )
161+ }
162+ let colDict : { [ key : string ] : { } } = { ...this . colDict }
163+ for ( const [ key , values ] of Object . entries ( this . colDict ) ) {
164+ let colVal : { [ key : string ] : Array < number > } = { }
165+ let keyVal : any = { ...values }
166+ for ( let colKey in this . groupColNames ) {
167+ let colName = this . groupColNames [ colKey ] as string
168+ let colIndex = this . columnName . indexOf ( colName )
169+ let colDtype = this . colDtype [ colIndex ]
170+ if ( colDtype === "string" ) throw new Error ( `Can't perform math operation on column ${ colName } ` )
171+
172+ if ( typeof operation === "string" ) {
173+ colVal [ key ] = this . groupMathLog ( keyVal [ colName ] , operation )
174+ }
175+ else {
176+ colVal [ key ] = this . groupMathLog ( keyVal [ colName ] , operation [ colName ] )
177+ }
178+ }
179+ colDict [ key ] = colVal
180+ }
181+ return colDict
182+ }
183+
184+ groupMathLog ( colVal : Array < number > , ops : string ) : Array < number > {
185+ let data = [ ]
186+ switch ( ops ) {
187+ case "max" :
188+ let max = colVal . reduce ( ( prev , curr ) => {
189+ if ( prev > curr ) {
190+ return prev
191+ }
192+ return curr
193+ } )
194+ data . push ( max )
195+ break ;
196+ case "min" :
197+ let min = colVal . reduce ( ( prev , curr ) => {
198+ if ( prev < curr ) {
199+ return prev
200+ }
201+ return curr
202+ } )
203+ data . push ( min )
204+ break ;
205+ case "sum" :
206+ let sum = colVal . reduce ( ( prev , curr ) => {
207+ return prev + curr
208+ } )
209+ data . push ( sum )
210+ break ;
211+ case "count" :
212+ data . push ( colVal . length )
213+ break ;
214+ case "mean" :
215+ let sumMean = colVal . reduce ( ( prev , curr ) => {
216+ return prev + curr
217+ } )
218+ data . push ( sumMean / colVal . length )
219+ break ;
220+ case "std" :
221+ data . push ( std ( colVal ) )
222+ break ;
223+ case "var" :
224+ data . push ( variance ( colVal ) )
225+ break ;
226+ case "median" :
227+ data . push ( median ( colVal ) )
228+ break ;
229+ case "mode" :
230+ data . push ( mode ( colVal ) )
231+ break ;
232+ case "cumsum" :
233+ colVal . reduce ( ( prev , curr ) => {
234+ let sum = prev + curr
235+ data . push ( sum )
236+ return sum
237+ } , 0 )
238+ break ;
239+ case "cummin" :
240+ data = [ colVal [ 0 ] ]
241+ colVal . slice ( 1 , ) . reduce ( ( prev , curr ) => {
242+ if ( prev < curr ) {
243+ data . push ( prev )
244+ return prev
245+ }
246+ data . push ( curr )
247+ return curr
248+ } , data [ 0 ] )
249+ break ;
250+ case "cummax" :
251+ data = [ colVal [ 0 ] ]
252+ colVal . slice ( 1 , ) . reduce ( ( prev , curr ) => {
253+ if ( prev > curr ) {
254+ data . push ( prev )
255+ return prev
256+ }
257+ data . push ( curr )
258+ return curr
259+ } , data [ 0 ] )
260+ break ;
261+ case "cumprod" :
262+ colVal . reduce ( ( prev , curr ) => {
263+ let sum = prev * curr
264+ data . push ( sum )
265+ return sum
266+ } , 1 )
267+ break ;
268+ }
269+ return data
270+ }
148271}
0 commit comments