From e7945be1a9a83598174f3c35ba50abed0f0494be Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 20 Jun 2021 07:36:38 +0000 Subject: [PATCH 001/202] GitBook: [master] 207 pages and 8 assets modified --- ...ewplot-2- (1).png => newplot-2- (1) (1) (1).png} | Bin .../{newplot-2-.png => newplot-2- (1) (1) (2).png} | Bin ...{newplot-29- (1).png => newplot-29- (2) (1).png} | Bin .../{newplot-29-.png => newplot-29- (2) (2).png} | Bin api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 2 +- api-reference/untitled.md | 2 +- getting-started.md | 8 ++++---- 8 files changed, 7 insertions(+), 7 deletions(-) rename .gitbook/assets/{newplot-2- (1).png => newplot-2- (1) (1) (1).png} (100%) rename .gitbook/assets/{newplot-2-.png => newplot-2- (1) (1) (2).png} (100%) rename .gitbook/assets/{newplot-29- (1).png => newplot-29- (2) (1).png} (100%) rename .gitbook/assets/{newplot-29-.png => newplot-29- (2) (2).png} (100%) diff --git a/.gitbook/assets/newplot-2- (1).png b/.gitbook/assets/newplot-2- (1) (1) (1).png similarity index 100% rename from .gitbook/assets/newplot-2- (1).png rename to .gitbook/assets/newplot-2- (1) (1) (1).png diff --git a/.gitbook/assets/newplot-2-.png b/.gitbook/assets/newplot-2- (1) (1) (2).png similarity index 100% rename from .gitbook/assets/newplot-2-.png rename to .gitbook/assets/newplot-2- (1) (1) (2).png diff --git a/.gitbook/assets/newplot-29- (1).png b/.gitbook/assets/newplot-29- (2) (1).png similarity index 100% rename from .gitbook/assets/newplot-29- (1).png rename to .gitbook/assets/newplot-29- (2) (1).png diff --git a/.gitbook/assets/newplot-29-.png b/.gitbook/assets/newplot-29- (2) (2).png similarity index 100% rename from .gitbook/assets/newplot-29-.png rename to .gitbook/assets/newplot-29- (2) (2).png diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index edd8726..e412af9 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index cdbb85d..dc8cc37 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -52,7 +52,7 @@ In the example below, we plot the yearly trend of a financial dataset. First, we ``` -![](../../.gitbook/assets/newplot-29-.png) +![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) diff --git a/api-reference/untitled.md b/api-reference/untitled.md index 4e0b10f..9737fec 100644 --- a/api-reference/untitled.md +++ b/api-reference/untitled.md @@ -67,7 +67,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../.gitbook/assets/newplot-2-%20%281%29%20%281%29.png) +![](../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/getting-started.md b/getting-started.md index c18e8ca..85603a0 100644 --- a/getting-started.md +++ b/getting-started.md @@ -17,11 +17,11 @@ npm install danfojs-node You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment without doing an local installation, use [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js @@ -2232,7 +2232,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. ``` -![](.gitbook/assets/newplot-29-%20%281%29.png) +![](.gitbook/assets/newplot-29-%20%282%29.png) On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html#pandas.DataFrame.plot)method exposes various [plot types](api-reference/plotting/). And by default, all columns are plotted unless specified otherwise. @@ -2263,7 +2263,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe ``` -![](.gitbook/assets/newplot-2-.png) +![](.gitbook/assets/newplot-2-%20%281%29%20%281%29.png) ### Getting data in/out From 9e05e5837f2e34fd21acdc08196dbc9139c41711 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Mon, 13 Sep 2021 09:07:59 +0000 Subject: [PATCH 002/202] GitBook: [master] 2 pages and 2 assets modified --- .gitbook/assets/419nr0t2zml.jpeg | Bin 0 -> 27488 bytes .gitbook/assets/b17076_cover.jpg | Bin 0 -> 788502 bytes SUMMARY.md | 1 + ...-driven-applications-with-danfo.js-book.md | 43 ++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 .gitbook/assets/419nr0t2zml.jpeg create mode 100644 .gitbook/assets/b17076_cover.jpg create mode 100644 building-data-driven-applications-with-danfo.js-book.md diff --git a/.gitbook/assets/419nr0t2zml.jpeg b/.gitbook/assets/419nr0t2zml.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..971413ad50071b608398c7551e0239d86f2cabb1 GIT binary patch literal 27488 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/b17076_cover.jpg b/.gitbook/assets/b17076_cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..726b93975fa0f4ce1e945caadf90e2a89afa4306 GIT binary patch literal 788502 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

3asbLQP(U=Va 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%0A1Do4PB|KJ7fY5$?~Ays309W$8lRSdi$Di&m)=e} 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 YkSyyJ-CW^8lxx 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∓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

MihNsF=}1(*i3IoR)b$eqC>v?SjgKtRD0G zgKNnOaxRK`4rOivd`kX3(N=k)DH?)r4L0`B`np(x%sch^i|V%7-F59TA=J3HoM=U>%WA)~-?Hfn|6y@K~Y?i)<_+<~?o_4JQ%jz)BFq)|r zn))g_2PZoxG>-P5xB4}`7?dtWlN8f{_)^y7g6CU4uAlLg# z3*K=@JJ~Bo-JdRJt8wYI+cnko;m7ar$i_0&5(< zzT51mr)Hjli_)tEEV_Q{?OdCDJUafBLx}tJ7D?@Lt)}2S%G_Bbo2yqSImPzplb0(s z5bPJ`bj8tu;|&8!*1=t7cp%(GNOtS&tDpJO8Kd1zTz;KFi|-9#epU)m2#9Y}{GzLo z2;L4IFFfcVhWR0v`jeskj=3Uy#pUro%7n&3Z6Pt zFNvNu2Ox(4DwK-635sp^vJsbTDzVpkY;21lDL~Yn$&kqNBag0M%KetLWe7p?#X=ty z0q$m9OFs<^FkFy9C`nK(*_bSLI}*dO`|(Z5T*WaXzuSwl7!+S2Pp#K`GObf=$hx$N z8?{tx60lMs-G=Nr(Lx(-U~LoO(bIqm=f6ZYN_B!i2S0n%Z;+ugCcrYNizD>lBnw9J-vF5$Ndf!?5H`O8MZ$cqSO!e zu0Z%*yIGHAnIG9PFS)(!*axWbE4J`6zk?!Tj?Gkw`=K^E9&?(UrA>QDn#}k3aH4?j zAy$j~tgq*x-){l&R1Rtdov3m%xF|B^Q4#{qp^D}SY_1fc>0z3%WirlBPa`W9rn6=x zvymHLJ+a=L&si{u$Xd@I^YJmdxf8I`vE}Ntd_e~fVR<3v)!sqENQpZo?zRxsYHr;$ z;`}~GHTK-O#_r*o5-O2zJ@2E1oTO?K{2x5`?9nlrhO7NOHjjz$y+)5}BmGh~1h}@; z%{L}!U6q<9-b98Z1r6RZxL8d2<^hFKUYDul>a}2SWuT)UM_Q73! z>-T8*W(jXT{GAt~Sl18~b4X;NCo}H@DGP9S)YnD(#&(IV+%>2s52ij#P;m|^dX}le zvQ}v>vKGjMAlakTdzT-o85n|}6V%ji(A{&|q`*}_e__Uzu8MRmKXwzyvPA|LZI4+^ zwAoCVfrL4aSD!pc@ONYxT~M>l3)XkrE?6wpKWvA`Naj*FRohoW z5_^XDjoDY?=C9;@&7`t5irN%RC>*h>E6=VhYm!_K9&sjTt=Brj5wUgsyWHik z+3&@RRX4v(Vy0qw!R)GU?GJmtRl{BDa!*0Xqm}V#0^^e;iDjpnvb09J!CR*5z}*1e zk5W9P5OmU^zrNMW>{p6bf{X){5dzg2yy{IW)}a>F)(ckS$|&)9DfLaY!4>R~Nz?wk z$Tvo#d~yp1OX9&eaGq+@_byAZ|Y89HJ`f1{S)7v~y&ezo6)l@=s=dRl;Fc-Ns*(H+Rk zn%(+h<5KEQ$nq?#wAVXENvNOb}9u~!hqIrA`E|aSD>UNC5rUX zkNNs3PYLGsB&rrYf3|MQZD?X(8%3=cD+z~HBv+7*2YBN0Ojsv+f_BJ!7}MphgP-_y zVHE8aaw++$7p{?BFs3I(Q6M|7=a@&!3L%i54*Y5Jo^+%fx?uauQ-Cy9q%e*;5BTd4 zd{f4-nz}ZTjZk5Bg0fS8eFITVtsv(aNd+b$nRj?8yT4Kn(nig9f?z$U19qR}O)&@2 ziIY3yYz0NabB3jmw{}0jP7;5+;jx5MKfSMzEB*E1Bk-Q`xX;ecLDGug0$jO~P?4E+ z%QnXm?#dw~J|igYO35G%`?;U(6bx;k(ngGT3K}wfNE?nH%e^p6u+>Yg29pjlgM;bK|Rzpss#Jz~SDU@nMCZJ}5v}GcNYs;#`b`;N6h0iUU zzt6=rx5R!cWtXwESV&MtJr%d!bemMXhpLj0!31lLQMXlUx@avx3^gJ_(6eG;mtIUk zz0}ly_`YXF_x~Qxdn@t!ysnOg9%#e@%>h`y51vYf?t;5c+}@iZ2p~BLa=C3H{W5S) zxNC0IrY6m^XRN}$GFL9tBM(F!3!L_KO`%R27RwabWjP(^lUX-B`TsH%b^9MrMN{a9 z)@&k0Qw{g949ma$%9Ch$2RX+ca(X{~SR|gNKh}Y(v z1lLSDoH*;1%=OKE?iU>v1F>@Zb zuU0XPaWQ1e&?!xOkfu#mg{FN@ZM$-O!rI%jXKO^wydK$j@>Gp_xdU|Xgg z?r-ehvn(N;C(?|ekf3XhR`744fF;t5N4W!m4>!7AOY3qzx$@ReR&LHV6D8HP3Xi?pHbcZco z>o~>z?c$WjXG;$BF;nxwW(%IBMf6IoP1vXjdAg`8=k5GTMw56sW?;}}^s$vdIbf(l^L2SfT z6S$4qWX;Ca$84)orx+SPcVe3AZ^Ha{i$6sp>U+@p>i8yxlj?R0-|A9^g0L}y@IB$a z`OK+Lj^;Con=Db`uPR*de?G(RLUsk?$X{?jOd47mWp$11Y(m*mE>*o`NR{9BEL*#* zOx_`bu4iZoFA}wiPu;S9M32CO*$98ajNiY_zG8}rWEosM^=9Vo&_DZSrr-&N7}fd~ zz2wh+7o(Is%{LgVmfc`X#R*(E_~p(phm_J9bKEXF6hpMupf`RQ- zrVD*I%p@jsaINxa!A1@BP^$e~RyBo&P;m`UQ>YE~K=FKr@;fy4iYz7Z90NbY1bH)+ zABN2-Iwy6Fn%1(_v5L~@vj~m!r=(!JOz*>iCD9@yPw^*$->|A#?`_F|N!e#J`Th^$ z-aDM_|NS4W7A-9$#HJNHh}v6gCxRLYwQE)oYJ}3#){ebn*N7nY-qhY|kD#qtqg0i) z==gbmKHqb$&*yut>-=}F^N;^?xnKA5z908v)EmJ&Y7V%HgucY6di)txFOqT*ur8D8 z{Q+qgq$wYK?RR6U-oivG=>hi-CPf3(&!iJ~j4I=s1eGB(4xxs4lMIW;bbzjh;u&6+ z5i04<^Uq&o%6#>(fc+}8@1}7XITv~J%EG9WC-77U4`r1;(n*U|C~XIqIdS*9nMc#4 z6%057KB6PnGMy=8>7}K#3L-Opun}j*T0y7+cQ|aq=)M*Sj@P?K%S)HDOOQ{~B}fj8AvC`7(X9)#i?}i`AtE-pt&*jT-5} zLz%K+#W&JPhU+S0NA$d1PqFgf%Vnaw{j^pFviwUA=mLBNEG@E}sTP=>**Tm#!|?Yb z)7+CyzqwU*Iy;R*zZx>22-TY_^_S>U&9>eU_>8(z%XDd;KlqjVlaEvSh$6hdj9-loHQiX$l7uehLTbx%V_IQ-jL2o=X`dCX@bV9vpgZ4dg4wvlofyr2u_<8Lq(_sc0eK9Sr>KY^A208D$3}eING!Sxc=8Z~z%j-*w+=vcL+7yq{ zHj9GRg6Er#XHa6Zbmw{ljH z*4Z**1J0ZBtHj+wG#h&jZ6rx$v>g|WPT!bp_`ZyuZL4VVk!o}pL|vB=!8rcr@h!=& z*@Ea6QRzlJZnj{We%D+2#zpbJKzS2oo%CU7$ftIEgQ9ybp@LlJy(owakOEQ85Ms( zI(rMvW!#l@w?uV_$n2|evkfuLg?-`6O@PL*URf%@MIyZn`aX;p!(oQ}o^F@JI@@z( zND?`R`7jH9dKY@5gBtXCk2yKzp$CY>`ICohr2+6CWJ2fnMn-=q_EB%nnTz=6jx}41 z!X6>4iga9~qS4p;(!0jj?;u3zL3^|PMkipmlgny~bS_0-KaRS6+90)RX)z@g?7TJl zmW*EYM3iGgw#YJlquS6rK=8y{QO+V~sVtkeEp`8|Dq!>vFMWlIIZ zQtv(h(TV%n@OE@s{pC-o;qQTevwU2|7P4hMl= z!}kjf4~JXspk0mrZ8?c%I+yCY(N?16Ali6UYa<+bW$~(=q@+k>WCqghMD$h!n=x95 zY=P+P3hV*)6h90GgH`J{@VNcFRfk0V=dd{87S)j#&{-G%1E*DS6j0WnJY%>ap}pz{ z8Zx%h=9uA+HYi33SKc>|xrHC(%trDcyd;!*yk?L_AHi;$^Nmsd%CHNTy-^}!OPcx( zMN$v~m-Z1=^L~Wb+9Q-|3Njly=h2VXkBGh|OUDj0znaU0fPGWDXPIrt?K4u})&NeyfD`O)#ayCf- z7vHP7=C;4*T(#l-f}?RdZ0Qdu4tL1M*Pt;+@Rz-FP`Ui?@r{IZsuQ$*8!1>RR~mU4 zlRo?GfZzD(!riN`i-pb&D#~2qEm<+2(*UK9l7m!R;%3P^s~;@*E^R7{F=fLC6+zO# za*BO+K8MOr77VG>d26@lQOU7K?j1(kIgL>^sV}jpXE;ZA8b2TMLybpOG5WtatEK!F z+`*K|lB-TBUU$d4B#qHBIL---Ng;wm$=hCfB{S*s@tzkCrQ^lhx1UrdeFBqPwG#By z6CzuTGW1$LdFT~lEV#T#Ek#w=nf7R;Qe{kU5wj|)I%IeDWJf)_iG36|fawK%+zH73 zVSK$Am(#E2n--QxkvjW6uL>r4p*oYPnP+$j9vpk3+Aa;`JqN7KAznc}K$AZ8fft_x zLZA_ws0yYjP~d$-!n!Xf_s9yJrY%q0*UZjKdU~64(c?D7kzVSp(kW_}|AIbKVP$>p zXqCrKAL6zrhUAtA2IBwDFYYR+wWxZq1~4YDdlEl~ce+_BW+eKqeuOtT6yryVB&E!p zQ!mLEbd|qTP_4tQ-9;I%iwxDZw-pMOG5or@1?_91L-9fvc-Qam=$`Y|f-gV#f4gDu zt*gN*qpMqM%cL{ZX~|VJJ^OXF*3z^J2T>AP;VoAftozwDOTX@XjU8Kg;!vHc)0cHj zGv=GecN$FD*7%Nl_gVeAwfqu&NyTHaM@zzdehQ1(CCKYHg6ed$Jwh;hIH`krqhDpe z;PAdSuw{)nxbk;&V4$LN#MJ(s8{?_IrqF%U!_^FpIbskq^n$Pc{xIpuTMKoqKeXUA zs~Rk&0*KUU`ZON;6W$b@IZay`nYwZroHy`0TbK@LeDdFuowE@H@rN%WnaDRc`S%Kb zUWFnH$@IAlpHyYlmS2kvDh!l6_kB5v>-xiQ!K~Ye-iz}>s+r&MM$seu5$zmLbmMt0 zGt&g%{`4j*@!A>G{_>T-ilyg=L6qKfI`BFz6@ZrVCig}RL{OfMSK3b&| zU-yKQwR{1B`Yq@iz~%d(eqK;+=wWzaN0rN)WG@xcT-j!{S1fHcv`r^v0mwwUjTL{H zt)Wu#2&8%9ANrvYclJ>6K*(uI0whBMp+Q$&5HD}%d^c(g50YBw<|?{A+;x_mHq~|d z@TM|a{1^S-EABEkzf1WxmNqx1!%tDUMj979^E0>cQ~$gl`B5vd!c=yg%lE_jM*;UF z=IhnYG@yVaMm*&bGNEGF*yHxqi=Y0+eE;`5fF_+ZU7GkN{=LF(Ygec{O&xO8d8baH zgUw!Top0!46UYq2bWnEe6CQUej!kJ!+>qNpTGh68cY4|lkPL6R4zby+EPf}=*4M8Z z4G#l(|M(p0J2%F@*+lI@Vwd>J-mo{?pwO~k_B8Rm#r^D90!n^fgQZ4;g6@I8A_pB~ zv!^!ZkH~Kk^NOi?jtc26Xn0M;H+tLdGgAjp=2DWx)yAn0G z&EO!SxAlg6(R&{_BEX^k4EyI3-ka~YN%h0OS4^h1s~;_8aAMsuT^WqbwX=9XLGb7J zqz9MXlHa?J7#X?Zgq#~`^RrCLA5=vKRN*~2rP|E6O1zf97QIoUz76}n-}{L+;ZuJ` z(NxD?Zw{mZzg>^Nm^aCP5{H&7+==Q*GjvSI7`j_8yMN;2+; zZ>L88AN?4Ie=6DVvXUR~UL)oLtQYjrrX%@sKB@`N|hJbReC_BU!O zX$BHkSD{MIRHYZAX6jOT7-#6dx;E4pS+e@JXxn6~E3_}fxl6~zPP+Mes7ve6wH`ie zOc_$#q9@-fN3>xXwX|1`Q*!@Dn1E&<(Xn~kftLJxMePJnaufTtDetLL$8qV5*+{xC zq2qKBji=W#hv+V9_$+c99Q z#0gsm&bE?ZV1-X+;olGhs8?ams3T9?>zB{tNa8veNB}3`ic024eDg%$CSqBQPjgn2 zgt**1O&O>QYOFFuV`KD2{913ZeAyUw(K8EHcPi2gle&TFSPkXT_q5JT$GX$60S;~) zVFPcPfYrTX&Np`-mzGy38-P#&%jN$}WGIaYm?czl1>XZi_N*v)G}liO`nMu+7$jOR zf+B4Ik#6WX=d`A8tl}1K_zAm!If|-e>NTU623IIFacVh2ZrOGTb&P5mtz^BL0+Wh2 zSK=ERO4)~7{YYGm(Sb}hp;oggv-Tzsneap$Ep%LkMfU45ihaErKAP(xGFre3JVyoR2hNPs-I%xqe|5a@l>=NmNr zL0bmWqqtA-ptUUFq0jo~WS1<3C@Ldo5^!^?#fL_?6|v+9F$474G}1?AB}dq@wJ z4?DcGQ#J$JKjqQ*KZZ3Q!y8b!dV?3PjZ+?l@T2I)sSyC%vE0cI;-U0p_7Z@JM<3v} z=4MJexBtYaVdtR3d_2xyh<*um11wVo?ML8O%`3?Z^Z9TQ;|g)Tq@U6-8Ebk z$#=J`_MI~Ve)AS(dT{jd{y*oXl3&}`7!TO|T0gJgGSquBOKab(UKAU;OvE$?ZJ9($ zKY|5mW?kLJ-#8gd5;Jy5_WZpR1(Gg2dSG%Qn=ZUn<`-~ASvUbV*zw~J;Jqtfgjw8^ z2r`sgDC6VuyB9cD9AZ3+WG(Nei#2}SNM+6V1M!`>*j5eASxcd<{X*;fZ+Fp5YsCS|t^&d#p3?k2@baF3Y7&4~oV6EEaSYS;j zR!gB-FLZ*l@(Ou`**O?UGF#Z4F~9Xy^PQNRbMPq|9*P5to-s|RrLDCGC>twS`q6km z)Ha{uXky@1S!xD)qsjKB+JaEmp^cgMWz7p}-VV@5v2w7wuo_E6(~6wwg~G;D^B22@ z+?^k>DL3fm*bHN%qx5t6By^iBGfBzCP+m%IwN%k{WD9-CXNKZbzls9K{gb3LRJ%7_ zQh#S>PW^ve=hG^Tk6N{tMDzdX&!}7_Nh9dnxsmvuXC04cLF+ERk6rdrdi3zsUKdZ0s)my#lfRd*x?_o0Y`5?=+S+sX5_E3oH~|7S`ZweTv5jjJ8}CI#toqX>{_4=E#YTbPU%_Vh(*LG zG3)#EC4E#Nut?;xZ&>NXuYKzrF`0ZfkolA6f1lOv|8rLB-Q4n69=zN(U<{w*Ep%0q zwJ&LDc*Yd?NTF6qKU!whOWesg*VICbn6x0(D@}$~!tpy|-&XUo+U$$JZ=3&nr9m2p zxt|>HMrq~*6#+@MNgm-VfFO#DquB}$<-U{enaqugK9d_=VMBp^c*6Dc=FiR=&ql|L zeDcG;1jO^S)TJ_rc@rs~Q?|u+M&?+R1%S@BfQP5|Oy_f1PGv&gWO?Vd7S8Y$&#Y7W zTCUzL)ry+u<=8)*wbUZ@nThcYWi@(eoQ&}eIHf(IrO;#XT(}$Z#M2l&WxRS_qA9Og zut|VCneY3=-zzMJPuB*0Uwp#_eWLvbVdyV37k{H8-YkG1Do}6`Bd6EhIh<~WirB5O za*p_cEU}dV-i8iYkuzc%Q)^G3mKW#huC(TX{*-Hd&lF8HLd?&W2C-{jh}H`XkG!n^ zr{`Oke3T2H2S?AjSnTDrGA;>Ah@>q%p#ldV2(CJ>l1ghHls68M|D3yp9`roo5CAdO z>ylHp^8yjP^R0bf{FaD{;osM$mc85}OdlImY7M>^hcsB|0CEjaUTPME*o|-ro(vs3 zMBZg5O^jk-G%E@{SywZB{*5Os9GL4F36r-Eko^+ zVhd9)!_nvWlI9gt6@nXXv5`6C49toTIJC1j>nLR2$BUA&OD#zV)ul>oTa;LCYR4~r zB2)Wa3)h{h0KH6jn|P1NNJ=Ejes+9^oXU{jX$q=wlplh#3fyUW#PG8*X;WNE8%>^;AG3;gx-@mLH!n zJ16FgpHNTuft9VBe@2x=dnUaBA{qFFBqdg-8ygGfsZt&j5kE0k|2Z+Ty6AOo{FI>W9HkyCZG9*%) z^IyGY4WK3hT&?W<+CI;5_C9~QbI>BAUREt=%46T@gfp)wqIxKJe!pN!wZ`!_V}OId zga#eW!4t<;eE1=!t=?`wTf(_eEc6;}`A~CERMHo4se#=7Qyu zZqi#j475%(804Jvl59@CS+Rv47&)0oSUe|$-;cgfSQf-#+|0yxe5PozT6HYLvSDTq z^}DYMf0+Rv`nFmjRB;ZFp`HX%vVK*KT7OHa*7P(q9k6Jx)3Fp6*X$vdl)8QT8pc4&Vd|AM=y!Ou z-sQD_AfR0@oC*&j2vZ`T+}j6H)R&arU?uK(>1pn{Q@buD$3h+M@(uk_pVpfi>$+(nTvT*|WP~50zWGmh>rp42GezXHG0@t7 z1xvCrTYEOxAsx5hF&L8KS}bC29#*nv{;)0y&hSyj0Y0%zM~*dT{*W8aa_76)E#<1x zdZKKTf2~A3q7kv{4)Oene(6GS7(;k>!`EnYT*8z+DfoJgwvIOMu=hA>i@yK5W_ zg?aL;&1-6S?!}PoGsFkp=p|jwVjC#3z$Yl$YQkm2c{jS&e>Rc7aBL zpG@W)*x`>MSm(Zh|2(G~JIAt67FqNBFML~TW%Vce@7WIL+Nu^}lZ^+@Tr!2N)aktM zwpMT2p*&9GrOVqiod`?`YDEfm8GC^SBO=X}tGy02d;{3($HZt<*#n|Dg6(;%r0CH4 zA-b5010BU4ENEKbBfAs}E*KO7>S$o%jlzfC|Js9sTg4=VQdZ)KWf4}YCI_xS>Sh3+ z^L{-0SBC-J6QbfoRa?}(j+$U=z^kKIRS3-vqn;yFAcscMFEOPJTEd#dQNBPvO6uU| zvppnCG>da_Ty9P!6T%M&lJTd@^;ftVK@CA7=j)_l6>_bzS}78QVc%cUumdjtOjoUT zjPcr#Xy{Oj&ca?@G2=XJ%}Md8PZ%K#y6l*B21IHq&})t>wNZs($}{EhEyo3g_yY;T zTaggLlTn5mhgv02T#-MPVvo5}Q_pP=^{*Ng31)`;o}v}Ld=;kapR1+mE=h|E0$c@q z%Nv&g%ELn^X>p&d{Fjfo*EHal85+LHM)AV}YF={C7-DF7Vx-btVwN0C?Bt&}*TMul zDTT$;rn=<*c(9|R0Yf)hw-kG*>1{1FsJy|aQtqS@Uzpfl&M^Zt5A0=Pnk1C+HR+8Q zbw^)}s7aX+xlvvWWE?zPZyp8oq^-zO*b*h8`xCYYOZ$Qp{(pw)wSRnG~qH z`LP_Q9X!KbF1z~jMuqXQi}tel?9>4-Ju>pMwsVpmL+~tN)yz}8a^N11>MHw7>Rpj~ z0v>j|16HcUU!5H<_-#Th;Uj2!j0W}~I=G~Dr_?#2a90n4XgM~IppOjyob0RqDGSx* z32Z%G5>A?v;g<2xCERDLpP?ZL++ho-5<=B1Sx&JPxUJgfh&DMG?$rQjU_1obMKTOm zynOgVOhv`dkV|FV=SJoT_|7`7Ty^`m7^SSx-h$BR77Si}asympILRMQbZZ`$$cepo z99}mReo;C}P0M~dhe>@^F&H4#nj_shc`K|FR-+WFxdfYR)rr!&nJPAlW;_l^{w_XO zxJ&Ld{5D@Fp4}b@6%P9*3;8`6cUb{7JGsF%GCK1>p<{4Hh`YwyKySx~h3W@U zm0w}gZ6SffwXst~(VLQ`4N)&pdSu+Me?@vnYm_fNn2bjLe;288bn%a{zL3=DbBs7%++tg~B5%3dDwOU)qFh zQ9WU1epsNOIV)=A6|klm__kaHduUMdcC$EFxR%!6kd1s9q?G1w7W>B*pFHKS=+`_a zlg(l_@a;`qT+h>3%tD|j8@n=r*ZC`3myI-QieuZ^@P95f)3eYz6lC@>(rzU1Q-KQ2 zSd`~`rkQJEPj4Za!FHOpVtxbJ>-#mPu^@(!P8Z$}C!Z^GaZ^La`L+wZ%^kwJRLnaK zDnLFQDSw(H-~lv^wG>G8F5F%v@%W>gdhm^Qz7C}Ou+v4suy%J7Cq z%3O+hrOAANn~iV9H68P-axoGI0RJfK#Mp&11hW-M9Vzo=xkbk9dkl&vf|h#B7cEhi zC7b?u%W8ysoGB5i4Y0pX4;d+GG=;-=`UG(+GZQMGU!aK_e~8k*WV5{?jH96*UD~_HVOJ3}qG8m~f_2p(QFVzuDz~EDL|>!-_myc* z@6L!V~!+_s!7cly6q5DX8MH*$<%4yv7fn(i;WJ8`CZNYrJiEL<@p=ka& zqQY~-sEQe@k{V6Nx5&-J8)gD_Mg@tU-yTO*X8OQ!;8nE1acn%fblHDWu1wYcBtQDe zgf>1-vRPuC^(elh|L)A|$KNY`qyJp_8=P~lK{Frhnv{O=p$)}rq%Aw{XZoJ-zPHLU z-aUsIxMR(W`<>Va#cw^HrId6Y_2wC2Gz4;M3@ojbv@R5-u1`BBBk2+L)BU^0RyO8W zrmbG;!cetBDGQIL4gkfvL@%Ti!TXEQ;D3;aBSH+2(#K4PRLw z1kT0y%&_2rmy{MyK_wIRkoneZOx2Qwu}=_H^XC9>4UYUZvLK5Ixymk~uO1N>w&07<_-#9G(Tp031*JAuc{+wI5 z>AAFvnm}F}6|yB+Dsf=$hMf`_H4b~oEL#sb3QiW@vq^PodNFGxoA>Etfq`}U1R)?@4S0kV zk)Z;`yL&+Wz6LeLPKa)c;O_C6DXm|n4Wn=Z5yvC)$xcQi<87bjzE|!a)|NcR~!JE;aR8Ciwo8#rEFuDm8RY?D-|% zL#>b49@7VYs%mOmejHtpmC;{oH^X%A^ICyo)EE0G&4T%;K>ZqIsLrOg1A`|>`{`>7 zW0u6`C7}C&Yey+R`OmSjF!AJgu*fTQ$M2T#$Xg}@2RETkMoSVM+z(@9EFl}K8`6kY?1!ycf{KUdCV}1pVl%apy9blel^#tZB zky|*+RwB*%)90h(H_vZHGqlWH+py%S=f;DWap@)ol#Mi|?~^&73X4;LYRnk4qLjYO zP5aie8o~eaY+e!k|LZ>qoZ94**}zGv(A-N-Bt_`)o5^NR21J?EjEK5 zF9WH*fbb2>ROD)E)^w>8X9eZv;E600I#+C}Cor0mocR-?5sCy+r!Q;U&f#%ZpMk^F zxlv{AU{3<-_&J60kek~xF9F-L1iL*T;b-%E(rk&u&xC^eROf$PtUF=t%fIB{V1 zAZWsN{22YhtiSU&j1ElyD2v*{Wi~y@g85Nk!vZt=B}6Av?qT3+yi?*rOu*MmL(%VB z$5{oHLh8Y;4qE~C&y|^Z3m-rCqf$A$y;GaRCDdl%^AuY4P%6>DzwL{O#-S>z!Rjd* z@H^|^4&1D2E_G*a!F7BlN`w}cgZY+F<6V+|WbKNxL2Qpj9VnE4;wpoQ$6Sn78?z!z z-djy`SdWYj`wVRR$|Kp?SB`DJ-kI{i?LOaT-eO@)Tawl*H_GvzuF)y%Prxv<2u>hA z4a-Xmhad!4X@wtyOK^D+_W;GbQ5Y*iV%k3AFA|hLqM=S4N3XiZ6~Tm9w1CivyUGUX z`ly@UJ1iM${evNjrxRhs7DPfHmbSB3yt_7T-kB_%)WvVH0H`din`+uYYNzV$*2hdr z|MQ(8mHWo&A;bLt`p!=J%Q@EO%~I#!9XXJ z9=Ia~V`_<^0+lAUpJkl0plQ0>>2)Cm<5L{kkndnGpvbCfUgD#2X%Z2myCh=NCe$5H z;z2XljaW2h;2$m!>pyKDYx;^js^+xk(9%qilAU3uq7bX)p9Td`VbU_JLnRi~ChqMd zH9#1C*ly8n#^1QE3*zH`pvrWnM`MRnQ3-BBFvD2 z^#v+SH`zxNchV9IQ_^X=2_v!mN-4DL$0o)%Id>)Ac!%ysMGrtQ!%y}m%Tg6GI`kFX z?cAL8WN4BL4n1k_-vrpU86m+{^rf?Bud@^;|rE=Bl95<`c=-#&7Y>>ubn`Uf1s)o$nB+ zFR-bW;~P1NL+q$Mw+O6lYY3;skyL3Ox_ZJf@1*k zoagEFiJ;aD&7Ilr$&^w%di{KQF^#WP(B}E@#H;L+9>IOuXX;|gZ*;#1Ede|C8xM5x z^}C&`61SXbI`?igA8Df4m^tW%qM97rkOOxvv)%mbP}|mIp2e9@FD<(&a@BzUWV`WB zx+F`zlp|V(X0pY~0lii^^e)>$-ax6tyWL2qbI3ytZog7f8^npxO69eO56en~T_2T} zC<;~cHV?2rj=aU~_7VO&b>3TtvtoAln9D2oTf+K4@TQkW3vkLv9^y&ZgVoG2U%kQ`h0Ib^?4Y9FAgf2G z*wm36>BW11N)Si{Y zD7q&DP7Xq727uiVn$z}sd<-qwqxX3W0)}trkax!(yCj--+2TB94wj)BZQu2g1lhVN zFCCfdO;3}*B>ahHHR6#wRsA?VRQ66hC~yC{NTYM4sBDlWO@aFdyBUp&Ii6wgvh*~e ziH%BqOO!4{HivgGbk@V_!luc^IN9Zt+I%|LKqetQ@>qE!5}G<;T;a=svuHLH7%7z; z-A2gk4x~GN_P)37N*+Yh8^K?}&GUOFMf?%~t9CMh`HA0NTARSgnj-^`T1^s1k+w*Q zB5*FT?>P=NC>gQiGE!OtD%L0&_aBzX4&Q-AokW;2RHn%Ltr=OCy-Ji7X{iwRpd1K@ zba`>=uEv+>5@05@o#@r1PmpGeRd)A^>C92x~aFo=3)vsJC7J2Pm2$h$@j%>H4 z)u@)vvP6z@>7l!1IrSO!-{Q;U=Gj05po zA2ibo=vrpWl7RO$GjsKzm9vZ7p4e238!2vQUzsg;nnw**t%)_ZPfw(L;pC*2HYLt4 z5^rL;gZpZID7?#I%ly9|f|^v2WITfF)=E_S zH|9OsrrJ@b$lw{jt+yopgYTkJI;%!XNfmWgU{}w)6cwW>s$~CZ-Di4Qrym+Fe2e5| zstk%M1o^I^s3PNeR!Ty#mRkx7w!@gVFu)69vQnp`dde6o+>H99SL7O^L7Uj=H{)n3Dhxeyd(*^zgLtB+pqm*zcxqOJbxQp zP%h{e3lYY-DeN)Ctv2&!eSe~1fy|p;ACBO^<5f6#2JS@~Qj(sB^z=2)c~y3H5T$-1 zg;F1syrX{ICY}B{ON(9$;tY_{gopoXt&|NM+HjX4X70pMQXm>YtrJP}j>_64(grS) zN4sxFx95IH?KY+-O6(IVgjyQRW;-`qga+ns(p$e1six!gPT9AL;G0i`Mi}CZ-8EH7 z!ClfNpIiC&)u!ut*!fmCHAIUvPed?p)&ocin56RKAWgk-o+5+8c!5iE1lc2xh1QWa zUvtL*x>4Jka=isQv&|1zBU03pl;C_Toi~at6FIQEAmB-lP7GN9}KHg zEp!}*9hpw;vL3on$>lcKBzOpZDKOWHGkPpbnFW?gKQ@r_7&g-t@xzYKoi!%DrEq!voL}1|u+Lr;CrSu=%G6N%)na%tQ;jv8?N>S1E zjq;4Bx|65lNE2Z}hTW#hUN`7kV^;9i{MP~Hg}+yh+&}ouqiHK7ij6DuUvrmwlGi=u zmgY+uSdJQdK6Gf=M8Db;SoMiiYT*YfGh8LkT9?XmmiSCNCi{=A*Dp1vrx>HXmKad< z%H(Z^Klg}2m!b_LJx}c{la!?2We2dz8hk^BhY?>);|4TBpVEdK$U&P0!!key@Zj>1 zRh{%r@JsLhbi@4i<<}$BT0SHC7C%iL8t!Ws!h^h}{ul-$@=#5yTM}_b8Htyu4Lm;uDhd4p>GaIUut4oiXaI_=4Qurdv`j?r< ztglj8VoK|syPc&*a2ilxp@g5@3G0P5pn$S!5DdRzuVdaW$uKVwCrwt6<*;N zIDua1h*chdmutE!Lls2744Nm?CAI)2vaX;cVS7DeS~xN8*QAWW`WS7FC+&@|b;9NB zjBN))SRrjIg;KH9Un&-=wz`aeg(~hkaU3e!%l>kk$#}mx>uuJxuAy}3E$ho(yWY89 zyLj$(8FP_jHLc9zrR1`_6Kz-w6B*MfeYFPDQ^_g4s8s7qf9SL|QgnHG5W#B!j7)e2 zyb9scOZ>}dF4yu#T4U?>+NV-TjoS0+&3U?#-s#L_a7jS}j_HjqXVEy+WO;ZROp^B2 z+0-H;))P9YaX`l1rw+Go@D5>SH4{FHF$BMg#)UQoX}7e6A%$&Wyy-TO#^j?kz6`#?5e$p^tv)LY1+TLW*c*oLY6nCs1tdliT>P`>%Laf?) zXM7fmQSpbPFz-~bzaA=rRQ5nGilh^nx~H!_79gS|H_YM| z!kWPbvNi=-Hxgq_L>`?gD1HrFxQlIKvh)wu=`HDv(jku`=S@$Q#=SG%gJ2mDKaD=g zT^qO;*{$+Gu`GPw*nSR`5?U|^rq6fcuD|fkBmXfKIf1W}&_*yuunF>=VaiMEiMbJ3 z(+lbSwOvsrPx^(>+Pq@Q7AyYwi^F3m~G_sX({27P<1sg*liv$BJQdvpts zr*E4CvQO>d)#ivR#*uMTfgp`d-y~zryl z7i8faepWdGD#EK4wSX<^Y*-nH49HGn-sM}%+^hwe73vuCHT_J&noUh zv)>c<+5%I%Vu*xmRgmws&*#BlKIgg(vBNy=OLnn2{x#a1S~$Uccbk{lQt+=}+~NS~ z;TAjB4c7_80d3qaITJ|Ilz4?04^F*1^jP9x<*}RQ!`qbztI%qce#*6^$DRB6F#OH% zQ3;F3-}Lo!(JLBYXu&eHBpS2TV2jFOocib{apMO+>*|~wxQo!AJC$z8DfT1NyhSfi z)+44wC6ZJlktN|UM{HsZZwZj7QjO{^D`K%hG027bLHI8H9JW38lD212NPeCeSw7=w zNi0OzfiUV(BZw5c1rMDOT@nR^!I%NOx{lc|z9sPvJ*(*gs}?O}R8CuF4p(e5k{HBT z8no~!EjO0K?}!qC>(Q?Rm|kJNA87po;l5w$f--1}-wAc0#f}U7NJjru{cNK4RCD

8UGcfeB>+Jg_6toq%h{}{2OaIsgby*(W$w?$`x&)#V z5wKhG3@yOBda3C7XMz^tbMrbyz;(n`Eke)B8+ygCHYPg@SWss(%MnZ(XWVAI_Aqy8 z#GOI6o9U0&QK{sJHO9c4qSsft3j!~%n7(VcGY-B;Pu531q5BNZB67dfSxueE5@FM4 z%gPkxU{zfhS<`MkSpGZ{fP9EGE>0?tS4mpnEg9r=^h>rg$!)XJyjM9_fIuCy<0!pp zMzDNE9Zl&zo@B+pOIi%QAVreeE<75CZltkR+v5P&n2{dx9qqU0?PebIT_I@`hR$C} z<*1v^*+m?lT3N6@T%Mjxv)1X7HxFib05M;q036bN?Wna_I8(>nOuds4z}uK_QueTc zKi|l9m;ajxx$kgliY?oA=Etw}Vu<=oX%6RpicCipJ1>%Vl7n#4gW=7I=1&>hN1z)RMsAIr|kbjN6*TVdY8>*nFjy>g*P@w!!- zYCRV(a)gox7o0xCzwQ65S5`jf6!VpxQfDmku;5lRpkK_3V_^CsR;&Xk0dUmKjAfja zpEC<~)Gr*k$NYhQsMbNwjLnuAlv(h;g#zg2wzJ8^im*)BsaG#kn%pM@>85y38FG%^ zB91bE22SVnm~7MEyjL2v^;4Q&(PRH2`C%Qc8GHb~nR3=3=Sk>d*K!ez)xc~ruWXt1 zUug~i&DVa}LvgxOK1rJ{1$@%jqA4qXvc%r2G%dK!S>GWt4ycxL2;NdC6l?*?4^2zf zXdugS1mgKEOCyk({XlM!-g33z_D*>ndvWe2s?jV4T4oA}#Q|P-Fre{ z;@i^a@3I{Iee4Ylyv9;G907G-b(az!Wjdu0-lLy3-^)N5ym{NfmJmL7{{3BFN=woF zVNi_JuOR$fabQQH!0@Z{4{6Fq;VVWq_J{IGaD?4x9*y#drLT2RKEP1%q37Vr+gV%G z$;8d5NbSl}FS8%lW0u9_WcTeTXOk|Rx0s$z$^%VmxX3#n>R^h$(F)m(wN|A8hO4~x z4A}Ge#I*=>4>o_O(T`eeu-nbMUW;AZ5Iz5%kJ3sgxo=h`D@533tYON@lHmxBJFA}w zHA@3*_N@_D1D8zsvJW|&Qx@0D!lKYZBV(`F|6Z}-`>MF$zTGdv(da519nDo*IHtuc zo1mI(?X}d(=fs0>`8L!ZFSVB=LHx&Z9QK~w!zz_c_{)x|y^-$OG#i$hT>ykA9=#@V zZ`w}wR=KB-OnR@l=XPc(GDBX{vEm1n7D1-uRoEnVDRa$Y6WE=`BRS!d!Jr1u;^PCA~}>og|zLy_9} z@#`!sw`UAl9Y52LCc%(W?Y^cqrW##<(!iMii{(li#ufoCG-VmnnHcrto}Mb@dCp5q zDZn|85D~B<99x$IO(~=WY*+$yIQL z;O{Nr=N%#L^3qe{esXLOBn?bIatDjzD|Tkm`X0~`Ze+#pg=wA>{}F~eY4d|;{IkYJ_v zym1bbD1$^BVhhVBCvqFKA5UrNi7x?cJW{+K;rH`?uAANjTV{@=MM__D{&egF@T_Ge zFgc;+b!u1lL&ZOYiOn}?MQcob;>^-bIuY{Pj}tK=`wpinySMS)K@p^3AK+$Y`I;}0 zain6p9@C;1-8DYWF@9No(Y;TejmG%!yPjy=tb$L$mZZ_ z34swhO#y4xiVo=!HeknD{~68k@q+0$j~j1TFvP6i)=^I*DT$9kcVpUMnN$N#mZnIA zQ#uG|gMkz3SZ5R6LCyP* z?pbi7@m7T(tBx`u{sb)z%O)Bw+-n9;WW&h;lSnfnkQ*jp-%r^cT&ye0s}S?5{uk1q zkJu)5OLcD@ys1|D+3ST4&74b23rKe~ z?eix15!jYu2RS;rSXB3JBB58Xsq}uq*9==(;2?``4l*;IV8GLMYmUNI$`@N)Sn#J& zPacu@Rv&AQ5VLEHmtjB9!HOm%GQlb1Bra&<_*dO#te7TuPKXu&qBM2DJJxTyBfMJQ zwm2!c>pbQBiq7;XXI$p|Z-Vm;ls1d2Z$3&TW2dJKxtkYtH;S*Y-&yLpG%(y=Ix6;V zv@9pyL7Z7|q>0}`QoWpp^KOe?$tXlq&sX?tu>d?bkww5cj^JL3|9+Tj{GZVl4p@DE zv$9==O5?)zo8C2dL!J?hmaT$&N){nKsozr{RY>OM8Cs%Wg%Y8w`ULe{EgRki$Nc7O z_MbW>(McEN&tmGB6xD*4=`+#c7L48IPqLS93uEf01#z#TS@{XSLvBum`W zsEa9)7+Kw7nI2klhr1d~3Cb=quQBuJ$OEZf8d}N>+iJ(O*O#^qSNtf8uVGW^)8rmt)&nkpNY!3s898)B z6{P9yi;@;L-!C>s{gIXJ9{nGBgY9n8T!cmpRqObpzGWk33ZuMj1MbnF(>xR6Buf@P zmE}N>Cv8zhDx8;Ek&8nnyIo__-PEcLkOrRuEZ8Kw+E3R17R1u0&yBF7#LvW+nbPw0 z0KKBv$PXN^nc1CMjP@JSW}Funl1z3ld;5oOSbdLnI)(v#c_RB=b~#uPtL%|pfu4f( zvzCQiJjTy6C~EZZ8Z=)!Wp-)Ej&7&X{)q~ zO63E>aZ!g5J9ZM!a@qJSVBX-XFYgx-s^&_bvQNS984P(nws&^v@)6#{`INDrY4(u*LygGjFy ziUsj`R^Io0zP-P1>@~(7>&N=VFUDZpcQTptn&){OhqVlv;20)89~-MF*DHz@txin* z!K=#u@HCe8yngM;K6^3aAs7=hAY_oSSsd{=Gl0`JaiQKm!gc=*gGl}6%qBrtd?=P1 zJ5E-qqeF=jyHIYXRMTbJC`IV|Ky=SLIO!y)njisEP^c|TBw#&IMGG5~l_02RwmiTh_Jq$RKoYbMCWZ^tlXk^9Jj#3nu{%HQg zH4Q6sFj#dI%WVFK(9Boa;%HW>QE27ulErL~{EV|)n}=7I!BvedtsdNLH}g$3Wm%IQ zZ~I_t!7wuG_shWHQ9`I%N^QDV7ycQC&-@1=uH~vo^=( zziDDA1IJ?D6Z@Qtv}pMRE6lyV*+ky=>6OL!DA`d7D98Z$ubg;o^Y~WV$1-O_zd2>; zP0N=Vwtv$j^9YsqXN;I;5zB=_yifgXRNKuJuCzfDZzKauDa&csnUlO)JI!G_@-U?H zaHsbP53c{1UCVRaCfVF=!i3kxw#niX%cy`FO>}@z@0$D4G^N1)>VS?`SVookEh5xS zx?phTN6pzW6Fkd#mbVQVlW)=@7~3tujj_!OKpwW0zflXmuM3tx^0cF3!Q3|A?rJFj zjVmw zl>!m&+q{Slo{zTqi@Q<^R%Jkia@S7F7{BkAU>xJa6Y9O{+=g5XotYt`j6CQf?&Xf> zPssMO?>FBwo#$OL(#l(QC^=~Ck{8r^n#ka!sLQ>aQ}WAbDW)J?GOvxWhpx=iSIiW1X+|e`o33;`!5wHKjN`Y+u@p$*y zhU>0ANT}4TRC*Fc7q*j6pjC>ugVy%vI;-lVK32QOx5KJzZVDOYgm$>Esn!sZQN-Tu z4u^{|x0?)H|60ptaBiqq9)CeeSN&oQm{H2R5OYi61wH>Y9}c zj4?3W=RQ0}WA&A(K{ft-Ue@BvqlWv8 zWqDmy;W=TX71(Z!xb zne^#3JME4_xpiX1%SW;1Z4v>w_I={7KlUN_^j;}vzD<6x!Me<{Blghf;vbCd%ntfV z#R-2&v3-s{snxJvW3#kOg&m8!p&N@qJaSCPf7IS9bGv8A&VMY+u+_|bQeQ{;uf`6J;5>F zt-?f8cbH`*Zb}2wQDDF4Ci*O=Ya+HHZD+Z%C2PTd{SPbd;JWa1*nH28QRJchTo~(I99YjC`J=SqKA`O3;7<2D@ zYMb-oT{tooNiqnN;XT@Ef4!vb&4iiY6mD2sj$LDpaDbx^jLqUPPG(bo1Omm6emt^A z9{I12c>o~f#5p|!^FTyLyz&b2aQNr7d}(JL+uRd7xn*0wVTPV@L*-MOa;o~&aqk%1 zu?hX>M<1tb`e5?Yr-s4yl*}t#E*3UFm>i0=pN*!nSm^>zfC~Jr0yE|>+3Xj0o=Dq> zzh(4YBDDf?OAo{-&Gr`EV0^P^^oGdS>y2qF9m>=APhBi5q>1W9C$L4lNH530yU^&? zX>EI|VcqA#zxs2R>UHSh4E4<53{650MPe6T<=|ii3}W38=O?)cr?Z<$M<>h>Ii<+# zzUd0Xa6*b6J#2*7fc)LLlDMIsR`trE%197jESOGhPBJ<3H-5Zq7v9s*`SMa!xUQX|r zHy+P}!#X3sS3eEzbWr~dd#gN}Tt0-{c0BWH8M01zUrFggm<>U}tgabF$u5fk?V<|5 z=NTuReJVF~D^?DcixuD~dec#`b4I2DZ?&&r<4Ii*Jc=xTKO-{z%c3T_YXGAtRTLMK zk1EL0*H7)AmqpN9*jy|$f9ykaXC9kZ&fXVXvop5e7bH9bQN&Z{@IerZjrUUGiz5_g z?7}(xQ!UT?6Nu9v`*Gba;`-{=+N3^dg3q3@!>c!S?}Xn@jd_}6W&ceE$NuXz=y%rU zeNqX`n*RTsBi@H2Kai5pBOc1g^9$L!k;9h7(b@ZDb5A*J(&5E6vFhn&(RXceKMb~$ zDXO`%e<^!>wv(PoSO-lA_SGkQID0nDQTbc{@PJ3Y4{4?Yw0AY!CFk>CyqxAdhA!57 zGt7On{Lp$S11J%G(L5!jt`PT=zV@Vi{(P0gUDZPuiny<5Zj^}BX?n3^KiO$Y-)cC` zh^u2alLpong)5no0MkFky_XfLP29ph90+jTUj>Et{bBw0QfOSBu{V$|&p#5_;MTaB z@cBU_d=}c2KIxcMZa#m(YWo%;knF_DKbA`Pvr>E{CH=T{%=7d%Eq}TCsjgLB{~|Jj zBxx64DEH-aY>0d{)x{?j(!vNBi#4NXov)_K(a4Z~fkejDfy|k8q{f2xTmD0&`-kE1 z-^qeD%_hAE_g#tczf_EV(m+b*G?HZB839{Dg%d@Z2RK~a9Ovb&E&KpLP!mcdLZffa zCa{3$74eWKrE9kSRKy7F8jR#`u;TDrk%SJ7^czth6|$+QVvh32N*!m{9%HRmite&* ze6Gw$=S!sn)Cy7uivdN6{_>0Koz6|nHs%bsGP|W+T9Ab)dp8&k{64MgkQ+q_Cln7R zJ`*(meRt(QL_M1-$6!L_aH+Uv3fO-XJ0dnKPis*&(EHFi*~x7wS-D1>8^sqipbj#4 zvHTlH9R5z!A|W6B?0q3m=HIR9c{ML72nDTW*Yk<^?4tYH%oJ8(jrQma<1Z^JQb(6Q zTO^hn^Qe*hV~efp_e>a-0n+m!`70Anpl&--x)S}$#QfQyy!@-{0eKqB;mxCQGvzOP zplcu~A+Dfb!gD;JErUj)LkmGd9a{J=LT~IXB~7*_8lz08@hTB^k`oG|=CJSlbuOm; zbqDs(X`Ww(NvOmqps;<HlUq*xUSX_N}%$ zv)zx7yvhsPKu`PS+~umz->4fU1W zOW_l9cfG>ZFzHJ9f9@WYVeHKTo|QZ5m{2flXSl(G$IqaFSjI0ydU3Dtwip@tzW>)Foi&+0}u7ug`d?<`OEpK6V zh(ucf)2{NCuYtglP(K5~K6$}+R(D@|!zF~@1a^jGry6=B`^ztg;#}3!jzP;7HTilvof^^_FqHX!$PFoxuPRVc=r@}xdA@NkhK6S zYlioC^Sl;-7zN$Os&|?-J`CeHU1JvKFm#^IWkPMzb3eal*DewZNVK*HbDvt(Erh&+ zbHEJi3g-f~vrL=ZsV%@BhY@`=UZc|5WY!;Ylyl)0POb3#NM=zc)UDfQR*>e4GYjk> z?74IHrsr&nRL1{qgt78hdClKsjsFw)WZ(sz7OHF_=WzS}^IN#>7Q=`}2lZlMCUCH; z@}W({T_}H#c4;VRu%Feb`*dhYiJevJChNsOc8>J&*NnKL$Cr!|!o&rTLjemS2l#RK zf81nyz0Y?joj{qVp6l%2;`X`KLZ2gEA;o3Jo+bQ-*~p4ldDb9*M|OR=l2;B=V*s5Pa%` zc9~cX9UfoNg@~1&s6Sl>Ik*W5McSgEVLYw`3rzr~vcFhxV6|dVERU!uQ~l-~e%YzF zE@5{xM;WXEQZ*ub7SHJb2sM`&9QG$@)QH@$@Pf?(f=QF=G5JEz}d zL>A1fA~a**HBZT^Q~O9Dl_SqpC$0^hVwR+rd_dMs3#;sQ@8<9ghHf`Rvip_YpC^{( zPC{ttYvnbOesHV{l*`Iacg)S^$=y8VDZ39hLq*=pFt$*jr$`0H9x;LOi3%_s%k}7jxHWW4X;8K{9YuXiF6dHB5_l5?c zdK?TuQT~sRpQ&aKt(=+diHjiEL6)C|5xH4_nvy^i&`4Y8uJYPS0iwKVlSAnqgtbsZ zzh&oE)J$my+F7gneZ0k9HZfOuj*)O?3>TY0?7~?dSo^bT*=_j}NhFR#@%ewX#a}0i z6^LD}F}NOOTQR4Kc5-q!m%XW|w^l$4 zErCnb2eeX^t>hFK?mbTT&#}39MDD#Rp}8jVir_}rNL&#;M_AqBFHXgp@?|rtDwr;< zd?}MFG$>Acd{`dUXp$)>2it^oTi;+@Sbm1uCotir4~^TTgMmC-C6L_Ht!y8V@e0@c z*@k~C%>3vLbFNTpLpdEHA$ZhjB!tri#qL`1I0z(9mSZL_zS_z?8(bh#6pp8rf(MK@ zZsY-QLA*zG;o_EsUu!JD1EWvpIG*?p``*@dEgi0$u|-HJ8VXgM<%d1;Wp0x`Fo#4d zQ@5E_iMl9r<$G-kXn`!J_0t3(Ma{g51m#WnLPv&yV9z;O1gGK8!uDEGE2j>i=;sdc z^ePDxOYoEk%sQopBTe|q(DlFwcS|Y3Z2u%1r4z^;XScmIOlbHyfge?ytp$*coN^3qM17%odnmW~%g=G~d1 zDY*(_7HibZsNSUrV2jvl2-!ltMb|&*Ka!+s5YSe*)&@zFq~ZhMo`I+P-sU>3Z(5!? z4%VoYd{zU?75*ilJ+T+~$bYSOAacR2;e6-d5U!0NZ{NzM#>&rV7%P9u*3zV0p_$DI zVPKq9z?cKRvER+nQP`Q@8+2vH^+&~>og`q6P!hHb1vChvz*ZVN&oxBUe}N}0r{J^7 zcFP#cSC@m)6-Gcr)zr+7M-03PS((dnqcrcvdTEZ+<sGP$P((%YwYNT?u z=SB{$>HeP74v~xN=L6c?X7qzsd6o7iR<^I<%?OsL9fw${1=k#9J`VtMR#?tZzJB}X zp|@8{Hx5PKK}RB^a%Eo2^C!vn+x!vR?qaDo;+yf{B|qkW6Q$E)+m_vk&D8%P1L3X^ z3@{uP(4fF)nkQo!iXZZmuw+U3gsqwRS57iHZUyj@(n+ZgLZaCPMp>pmmmI+|l#C zhOeTHPU?UuCD{*AW1t-R1wb7O>yZHpeJKS)8GdLR8R=zvly<8n#tpAOer=FrF&?;X z>pHcU`8V0$WN$3=ri}hH{Y};CIk^&pbggq#WjzIi;KCsMi>{9gpiKTRkW# zV7^}a9HsVP%{okOlGeYrv2q*@ zd+d@kv&|uN`)HO&NvM4x7Y<@>Pu2shTnGuDw5Ew&RybFglPqdMmyZ%WUUek;e<>8i zqR!p3Eb>f3^`@%UQmO5J*kk*izC5rn7G{~~j1g!bsZT`Of>wfPt2j%|Uk;W~Am-mY zQ`0Lht)g*_NrgEiWvy8JCe!(aLloxD4t1S2(Jl zgiiL7Q<@x~$XEylz=Qj<4i(h5+@6iOynGu{PKXY2o^YBi(J$1hVDKPPQ@zq0EA)ri zh8(xJk-{3=&0bvJrDWx9)o>O13`+S&XTQjjkhXGs`9YI)DbBGft0IqAZ|WSWRaZ+7 z66nS@$<-)lStc6LWN*VHoXdsOeztM57V8(h5YL0&VDikJMw<%<-`o0Oo({apTRDNE zO{lBZt+{qWey0u3$g9!3Cd_ ziWJ%X!o{|H+QyEUGFYoE<II7RnB?>bFOd3}^fMI9 z$(SD^^C=Rx$>r0TU=ZO3o?iZE+E150`zBaJtVX0yuWr+A~O4Hhww!Hu}o0)Ur zZ>FsV@#7P11KAg@lqw5xTbe?9uH35{*ZbNNJ%a#XFDW!SD_tp6xJcxEqtGbtLcqW| zQp~_hV0L!V;2B5)$h6n~(A=PZ$=K;i<9g@q^z+w?x|_d{*>jQ+JC(5NgAO_5coEG1-g{!r8xtJIw`p?~*uql@m4Y zY8n~`pQrIuvUWO_zm!3I{)sdXZl)9wC;u|8=-w4g46#%Y2vn_}^*&R`qyjG8%Dfcy z5y=RNC)Mk`r+n=REw^$)=d8?+P7yv4tS5-yixIi)S4Fn>;%Y|SaWlZG>p2QJ<_may z?Q+d!3vZ^-G$W=?tV5L85khyMY-pp05g!Q4&XF-S^nJ`P-$i}xS`laSn|@&<1y*L= zLDfg^ldc&_E;~{7+zhl-8q_o}_mo`6mD=SEe`sCxum)4J+p=PV{o+M{OkeMNJV4=TKl7m}Q|KCSa#dW!}t0-X5 ziO=n_yjZa#{@2u1;&*%A%QYgXePM&<`_~)aM_bO={`It}8UOvXBfVTrG#}>wRrSlu zjyh}$uNhfbBUe2c4*q6lHtY$0Q%lt0KdvPlZ?g&ZM!UOra*jP(s62k#YlfO0mCn!*zJKOBzS0- zjkF4JexS)Q%nH4l>-Bgs1DYapz`Usr0YB$h;OCMSuGK5m$e>;=Ud`^~!~X_l(?`GP zskO}k+k8>sJNj(BXRG%p?vK$ChXRzjtMRRg7$RHE=R9yD%ew)2Bwpxe$UBaKW|-Ya zQ7cbW>Z`Px5MQ*-*DdsDwfF#*tUAmMPhMi6QoxH(9-LE2I)~Wb`mpm3L5_U#Z zOcVCa@49`bxvcJGo{z8}?gaNh<00wKNL|wnbb>$s5Lf#OTTSWoMw~CVGCw^!zJ@fT zT67EhasdS7%|Am304Y3_AwV9YtnpkXQqZ03{rI0~? z!-a+l4g)TE&h`SnFJHL4emnAYRAlyj55rA`FAdtf9UrbTU5fCwuO%^{FyhS@C(N(N zfcq5TpO%9iuG?g@b+}rmB##3s87O{)}pi7OAb4+bnRhHYId!{_H24RUgi)66ylBhpK zY*0BncbxRl(b%hsd?c;7fPO4Tz^a_)^SX6oe@v8N3&3?@ zcR#3IXXs#UIU>L~k9iIU;0m}Z-KWPU&05~rUoR8GnDlX1^5kHg0r zsVkFOgw(GU(CWN}L@!yuVXB)a#w3Wn{52&yovhv@?`#`SrWp4QvRim!K*`-wu6`CM z`$d%@zwr~H4ZW_h_CW3DGC@Ek2N{JBXzHk|^2cWGieI4z%u6=oPd-E5bT{0baaypNHW53gtjude(aEt|aa zm;Z@Bn)*4zf;6A~Z}GZ^p1Hh?B-SVH2rcn@60riVPe}ijBa@Wy`mx8rXl@{(BQv)>jzWe3VPh~%24EHb6r1}18DCzKQETxbTF37pT@a%Kw#D`h0K>nWS zy8+!m3-pY5=3PD&uf+YDYM`1WPB)njr%tPW-C){TH=dOloj}2RH||tS zF=Y&ZUvAT{e*X+D>l}4Vg-m&sxf-7E*njnDV@6W!$>wMt{+ZQs-RN_++E>mWE<>CdAFFkpl!6KwYGI6S^IY8ee5ir zy`jh=o0i}@Ci=w8rG8!m!4`vyz}L1P1tMk+b{hLb1pCQzMiJOD9p; zeXlmN#$X2M>e9G;l5MD9R(k|YZQ=8$Q1$EXcNv%7jY3B(o*e_xlaiabvv4-`D9yrrpw6|7nf6eQUi#~3`;!vkd_r=)gQk?*2#rxb5LPZiCD;Xnb zG^#zDmc^&F^=OU^;?vS!8J+m0viJy|`teuc!=A1^+J79f$$$7fqD#)+;Lcv%oh%&+ zv1_|I;I2Ym9JEm4oN=IXFP^2>P>!Evynb4|PukR*Igd$%@mpAVja$`Z+1}h6K~mbg z;3awEyb{v#cTNO7v$=RoqqvJ9hAY;X-n>+L)?d67>5O7iH6L3Y2fUj3;s2zJLgtvk z$7OqTiO?gD&@nUA1V8rm5y{5p)Cb>rbbUGtHY6<&Et@56XSR^)}p zSO0RH{dI`>iMW4EtPB5_($mlUPc__4ou@p&#Y)JXd;C!8z-Al)f1wq%g!9P-5Is55!UdwGQU-)gLRtq{N+AfsvJIiV4K9< zFC$IeRyPxYK!80Kif#DaTp@hRSnFn>(by14!~vt{PCu#F~2 zmEMNXe1vaMa->h}mFcgw$qveFjV@_^s)I%I7UPQf{QdC^WoSoNVsk3S{%bR^b5_Ze z9Y1IQ0To4O6PFlEal1KYrnUW|jd|i&b3)`IM9maukSyrl%Z`52OzUvn$3TyIbBUN{ z?qOKY3@CAC7IB_qskDFeo6-%7w0yF*Q5MfBWki>N4fmiw16 z9n}U8$ZchvpHkg5cT=|H3eTHF0swA^cf$rBAllXQ+oC?3+ z_*zY)3ZiV;K$R(hI4bf@LF!eW3;m{NaI zZjMey*sCdATf&c8hn)!)6mw{i>b}ss6KTSVs*#eJ9uO&AL2(W;g`mGQm1{fc`kLEkq(&;&p zxPwR*$sAoNn<9^}iB_-u)OvOZnK?lDXCFrQ=4B8BGc=w*I`G$fE|}itWK;_3@|S<_ ziUs#Iq}jdCJFh|8Y)|ja`H|kc)>-X)+nYgf6H<0XDDm!^{V788A?R(W))$(G>i@l1N_RfPUaADp>4LQyEQbGCC>n1Rs=OcXal zTMC#LSB<)t`rWnx2RN9g(!cVi+4K&jlHQ&}_mn;~_L4nRnQ;|Z_J_!2FwHAs*%|Hf zEo^2-1)V`6qfaZnD8CL=w6N?5Pf_jGzZD{}RDclU6O&l=K#*W7qKS;$Dq9s`bQ)g* zWqs+tmg+Z_dBkXjBSgq3e5KkzRs+Ad8ee2)tEUWc||`eJ?nPyq=KCC zPL07oKL7EFa0c9>KK3xMTEvjDOG)><{(70uT<;TMCS)~JAF4ST93gMyGoHX8!05A4 zaFcfIEp<_@|G}aEp_z_hnQpH3=oXc$-ZJm-8K8~f-MRp1*1bjxDH>?pL`lUwTrO2> z{M(l)u~5*clerC{jb3oXC>i759`oHL5H}x=+C5I%J z=E|<{YwrRQe40arc^srfcpS50-2#8+FAiL`&R)9sr0Y|TNF3A)B3f-gG(!Fcxd#`_ z+?noB*B(qOVy(-)n%SEAIM8n9xHVt!UAD**l#tA1VZ`+U5KQi$bmg-8S=u!*kYUBh zopya%nR{{~3*5moVo}0{hs2P3F*<3eB0;*(vr7+>4AE;P(I#CCoDMN1qwPPrkfaxaT*JZp8HIBcuq>{4iJucbcgt*jo1h0D?!~?4Lg>?rVU{Lbwvfy=s^f3!3ix z$7NAyh)?JmeW3aQLUK@-CT$Nq1B)hBh|o%}zUM$FRq6#W?5;W5z;@!{k$gkW#50zAM%r_qI zZL=(bv<<*Rxx%&n%6$(?VIPtH=q~1e@ntxe-8EtdtW~DP&_B%IOr_wzH~ZcqXDm3x z&*2t=n$K&Z492OQtc1C)Qm5ExAqIZ~d`GZilu)rom|`Gc%#6_ROF_A=d6}f;LZPXE ztN?`Vlt(%na-F(ajRhHFuv3^j?MpKpQ=*PRCK_fLP(Qut661u@_XQ6Fb#5ke9>SAj zzzr_bYm(VL;6!MVVK`Q5pvq&E=5_qN+X4 z(U;%(wHpc_YKT6<6K|Bk}LrI`7L#bEEABKKNEU< z)i&APO*g!ap@OiQ@TE~7q1soTT4gJ{05ZbiDuVK*v3=A9B+wmC2ME4ru5vS$5HP3C zcv4f{NO-wu++{*K)v-Hi-PKCzpuH#S4+1l8E?w0fKD{u%l289`YgLcV`2j->SE$s(k{o9L|uVTG2FyhPhOU=qvT_ zsAjqvQ{AKaT1G7T?k?;9FMC_-w`GX?qANpX5rjkt|3~LH`BC_wo5tLdHvG!WjDZ%rturMOnvt5g&sn@vX-j2>=r6@ZFn z&i>4w<2#@+o)(mQetoT{kw+=CmW^_IRd5!oZAF9f+@!t7uke-p{CY^~U-#{N#Ya1| zaVkcCZnAUSHHdP(I)Bd{>P7T z_OO}i67@RrFSCRhQR4qC&f)@QQ&A z+~h1ec8_3@z;_Y!nxlC@28h$=82@~1;#;uStmwk^wfhsF7ALd{ug7$5 zL7P`XN?y(ZAPfsQ=G>{s54S@lAw}^Es)s<5Pd*nZtZE9E{f0PfHXy&f%*MKl)?pm3 zYeTL*)6_Ay$FLeET%mQ^Tt{&eB0_IF6Pp;$DW?hXpnJLJcX?morgmQgA`@P}DWHZe zrr0jXkF)sifJTC|hqH$paVQa#FAmt%eW?8Lx2WRTU~1!-uj*Osn-vIUzycddc{d{} z!G6lipA1T>?uiHc{290&`J}61ZV9$ZDoh;6hkI@xG#gC1VX-i6g~sDys$Z}`}e^c#eqO8pTOQgJz`TfrK92|Whv4?eh*C*8(R zu~D%wTVCZRQVqd`FLlqLBggpPS;#dz=EEqVcT}rOz~P(~DjyYvPkSGOs~b~$h3f^o zbSo+FpWIoL=A8WLdW#a=pLoODAr%a9Pj6W$-HMel$t+@2p7#oWUOh6oy0Jq{bzfLG`{jjBM?-eiM;ULtI&uGmKu7+LoSk$OUqu z7z*?Xy@FH^aq?&{z75A%Ge0oNo!oqTu1%Ko_KEr}4ypG$WF7kZ=vgnl-lD^ZYEnm362Pm=cMBk-WS7r8Wp$9RE`t_e5U)h>e8{Dj={ z8h0%CB1deCP{oO&FiSKkf8Sq^!B#SdK@}m&i6}1GO%PbVf9XbfFn?>f_@h`p&g2FT zton9G!Fw7fNnS}Qt!ot8*I4Fxq=s?rg{iZm=lT~SDMNQt-yY3y@}>#Z(pc&FGugv} zYbs{jeF73qUP6(o`aQZ@eZq@)vaBRbQzLQOd>WuFr}g5GET3rYsJFBP;gfRoNQ&Io z%C1g}_>1|vyA=ONyH^#9>sE0ESew9#A8k2cTN z4$(PP?JMul$;E~3zdypiBeBP&FeXIc?!!}@! z0}?riW09YW9HBjXXHtkeDhxK0xTwH+=Q;la;`dEaKnGbfA&i!$cuIL8>UKCOz&2B+F_zW9J57ENxSYG-)6Y62zhT@E!y(pBEdRp0|E z>SR?rxMFgv==TAlhKTJ~5uGbS#4rPAp-si+t{*8!ZQ7TT$V5wsp4@srj_Yl}w; z)UTm#D64x;MAEEPE%;aSjkYj+k$kLWrMg*FPh^|_N24SXFnmAe6`{3KMI^!|-SM$M ztvQo9ZQY{533BU#j+eIjxjrULM+_*hLnp6=Xr)F!e%$(^C(GIliC#Qv9+7r3W%$97 z#!$ZZ&gJ(L0Hw-qD zc*O%VaZNfh<=jI9Oo~fMK%X)3eQe9Nt!cFpN4y|*h)N`K_?XIAApHI72FnqvNX8{O zq5@IwaesHT$rR}+E*WPZ?HvdboSMLcVg)RM2cE{<=@We z*wk#^PA!4#Sg6%3MWgE@Z5wMF@BlboHXk%HScu7&1IRIQZvLKQEoKhRc`X&&yCRU37wuKizK~i3 zuY6ZoNCvMgWTqrx(|cA($aKwrA=3-Z&J&)|c`ZAhM?CCR^LP|20smg?HoJnDv>aEv zLAYemL{p?3#nSG8i%N_iuw_EhZ27e72v+DNXI)mWY(4G=B^5?|IJCL1 zk+wNbZ(zzP`)X@C=$bpP+O> z_GOf(eupY7Q`%l&W8EOOM=MWRs&0f%A=K~urTcWz(IVUIZ?fut3q?kkP0w^nj}tVF zDL}1R?b4LI*g8Xyn?@TObt!^xEpygOQfFGg&|aFEWqf+k)atI&jZ+q@Q}iprw;$!E z9WI9cCS&l5rM~X9Y!bdN&0Dx zCgrdzu84M-?d{jpIsfcL3<_Um&P3@uCJ9&oVk)2uAa`o+u~uU1{Th7}yE*Pzl9M5X z$8pN*g!0uuU@p|ToFNUSR9WtE<6AJ*5W^1C_)bmJ$M%QbUKF)38y0R@$Q+!+X^=uc zkB9y>`%gOp=z0KK)RY$i%Fkb|=BL{u4PphtAgx94PAtyDb-%B#!e2V0U(Qz$j#_wE zBwG0V=`C0!qBzzxk&l^ps>0|^r}s3%{gsYwOYj@DVJuUI6knHaaTQVZpe1;z z5%;0-!;4r}R~RLpP?bvc^G>D%Af`AZ-M+<4`bc~wgT$CtCikHHnJ0 zK74x}xdF$U~Ytv6P z|I9{2M@ztp@iC+2y|`L|(Y+fMlg-LrNAIiN<#wDpCm$WG=%}YZ z`l*XR6ZVFt+V_W$Se?)ny(W&h0a6nnYy@C)m!b2FZV^Ivs36h=Y}4%x=K*O=#_H*}yxpZW7d zhwA$IEl^S9%_+fVzXRsFTd|3Hsj>cF)-sn>j9mR=l*N@gh^xZANBteUI_)`(P|)@q zhtA9HGJ(9p&d{(B(Dr-O@gaySoP&1|KB2 z1$TEDT!K3U3$B9>?lQQ$LxMXbxI4iiKuAIe;l1;obH1wYoci6W->tfTo?W$TYRlAK zd#_&It9x}nPkDY#^uosnlk8AM&3c5JY{1yNGjqEZjn{!9DsXK9hp+EUIXI)PqjbIt z$~t>;`X3Fwl9wID33yc*B(zWgujKpp#3#T;ZTL}I-H4b&H6E3b2*0nyOz5ixps#7^`k+g*3 zZIn?B-b#C7PxQ+n<<&`Nv3Xi2u@OY(fHaxKXnP!S$^8#9rMCf;Ze3y zWeQJVN)#7E+h7c@+%)|cebj$g8wd9cpHIHCC}5_$U8ZZTEA_E6nmcmXc}a+OkpICKx$>39ri#@V7ej+tOM|wj0KD2s zd-X4b4U^ikr=I0lY>xmZ{K^_T=2f`?S1Qv$V>yK{3f8&~?VFHBOkAcRc#*#Akt_Z{ zCTMEg~(sfHKID5=%4mLf&!BIy?@7eg zeMfO{c_|Z(4CJQJJp{?G(!Q*JfUnOmmPzZ&jgC6ppXRu|g@Z(%nbefCly7&}B(&m8Kja)Xgw9p`!nB*VP9N>Pbt@3ezhy9UGj%spP2ua>{mP0w*NVlTKJ_) zQS=}Lq*O^aR8C?)jJB=%gDx=2oZX(G}rs+o`{0`kg}eM?FeZFOM71fqZgsqHK8Vg)bC zqOFH>6(tFq8dvffQ6r{k{pwcDRmEzoA&-xDoHZTkIg2bC070t{a||%~e$}4DGQ8@> zRd3pgWzbJ{bu4Z6tGBiIDE2yk`cm(m92FNC9!2ULLl@5eLcsdbnDL(RRb*ag_8+>G z+Z1D=>q>L&GGxSwu8pnpWk}Kg;DsoP$eAak& zz8i~SS3h}OT@^_v{?MGM>Pw2^qhiOK=hdxcQFT9JopnzVlK^cZJ#u9bB~STXKJVHT z)K6PyskAKjI9k+&H;APVM_Hc6eCo3Kur2Wmop*)m^Z7yt@G;*#qdOsmUx-b_Ygg5aee*Ab z16K0A(0O)4*UPupzC`hA6}88PjPfq8KzTB|&THPBYYhC28VlLr)LV$ToAxmt8i!5{_JrN8 z5PDoc>H0?H6JRZlF@cC%Q zT}ZDsZ`H}N-_I-q0}7+NRHujB>^bsmUwbnt#k~h)=|}v*cFdSUD)}P{&cR2jmwiwoI#eT1C8-o9E{L9^tm3QS1@#T{meX?PjW(-v$^4H(}7Ybd07) z9NG1E!8S>l{DWG`>IGD*n^kW{N09TwCD3hY+zti=;z6D;Ur4#N&&H!0L3+?yOrSx7iln0pI z$itfx{int6r#jVv;+b=dgg8FQ2DUX26eJfpXGp z(T~Ewo_Ba>>YdvP%6?J$%0ge412Ysj#FT8u<0%vVETt<1+o@;9t|k*=|Cs(1a{kHD z_0=<4(*A1Ce?&C#SJ)RLNF_n;88g0^CRVh*lt|u4>^pI3-+M_*Po6@Bky>99Df z3Z~j4ov$l}(=IRZh%8zGgRD)Gn^xpRZ@-pJOKliv)7mBxdo;@LEvw#FPPz9c2#9S2!I+HBZu#|Eyj_Rzt{+ z0WnuliD1mPRfP&L{nMcsGED#*I;68URIha3Fl5BJ3h-;YvwmmYPtr)fSzxI6J)Kaa zwg3dn=S%A9JB4B0=2VT2LJ8;UFX6o9SGYea7MURV-&LZ7xggHZr4PuUa(Cw4HW#7I zb=OYQb1Izmkf?t%2lM}74w^P+TBBAYoO zHt_Mcv-}gMdziY)f1WU$rZ(QJK;69>M!ZhpUs55(D9LAcHHYO}XHE8C^0C{Rjj1Y> zE!%dkW-J+z(b+9Zvyb|rBm1&u-$5>+Crj*PW_Bw9S#*xqEO}ExDpjQnB9veniRC=Z zQO5yKnWN0fd_f^vf!EAJWV7Nk`dvQu?G1W9xvLidv>dQ?9`1f6pF{67 zto**JZFw=JT=v%6VDT@6vV|AIYctj-xi{znuG~)&uMX&1-M7^G%W8tT+UxGR&G9s+ zU#dRobB{Q{lLA_nqtWBj|YDjwiP$BnIc%JPrU-jc}MzHi1sbD>q zy01<+7-+RZsPFChYAlA<;Oo_jN6!`c`j#1~z=F2By!!CqLMNrLgf)o`uET0KFbeBn?`vV!w7W%ABNk73le8*ajuH6eUPlT0ae)KhDI zML{X%5nw5t5r7uoCf*~ZMectPU~un~^KU!Ne*cG4u)JU~e)1^dTKYkIDTHk1ql1Yo z>f{k$SQ_>Fcs@!rT-XTe-R<>Fm5{$1@Tum$=^xC$j zk)xG4Z4H>M7g)*G7?N(~dStt@ZIn@$9eVr&VbKA~(M+mM8_2|@S<6rU#j~I8@S^eq z5#h%*=F*jO9R)MVAl8Ss;}8A5aWtsYKo0*LkRCX%7QiT@1d~yU0syiJQX6~OZQ(HG zClEQmkd$79XNZd@i~Z*ne+?$JisLIYsP=(SeT|oe{qflQ^?M_6waLWu7KT`KTUxh6 z(ydlLQQ7HHon!V43~zI}KlgCGqtXeaTNJWxSB_fDrVXls0FC1eS`(Jl6%|_XxGeYe-vn!rGGvS3niSe z^%NmebS2P!o>1#YFZZ(8d7pGiPH$U==^$uw|E_R~VZ56vXGmUE#}!HzFLqSg~1VfPjkK&6xUqEzXhV&)5>tk?19y zwzW+Kt4(A1 z{=$_)U%LMxK!T5Iy14I&ty~hG4S5<(Zwo|qAU8zzoJ&*|SOO}D1PPf`&NOLdB>HZK z5c=J%$-LwEsLrOU1J_7D&~)zo+0n=(?%0qp1G#9(x8FdJ1oayO1b$ z$mH;$tAq#4Wj!ofUS7G2npca57Yy7AGnPxYBb$>l+&7>|Uhkl}xJ#OH6~y#FRJ9B% zkW-6K{=U=p*>;&}vE~y}RL+B60ONj(2V}M^Z0(TT;KbC9+pj zIPbuVl*${p(^Vpc!%h}Y8S3Afx$>aI6gVBaj%wfmCTkiKtSJIT6d+G`7J+&j5!5{i z`5%i6P2OvOC&~dvU%hJk!{lOVwj9Cn3YE>m(j@c8bFqZvlwa1~<9JYXp5+8Ck!bUt zaSF6HNo& zt(9tN7vB{Q-~pY2MKgNm*Jg#3HZoP2(>`%{wbXSCx_=HX(+R2wyqs$W5-@sau3ot$u|-ZE*?F0Be8}c% z7NSd#AQfaH9zzFQ^$^+_jt@WigC!X=5hC1TZ zt5VzXSb_*jGkVjn&`I8NQH9V)fTjap%n2HPv{%XRfJ248zzz7Z;uM zMcmc$Sy#?=nMIP;G+n0rh>Z#P7;RPY3Ji{DLOlf^yr}nK=Q!cR-|fa{SYb)~!=QnS zAd|d*@_M_HKgoSU7psH4QmhYV5?lx^SG)D@O`_p*l1yFnu2Ox!i>;F<-lS6@(u~J7 zjsBU=%+B@;g1i!5uBGHn|M12fI! zX?bc(a;DAVTt8^Pu=cQspo;Gc=vp!@{6?GaUSP5smhTGY3xK7 z^Z2;gZ~1ym5)-l!Jqk9Z*S_;Hx-tH{cZ>0V;oVl%`R05VV#jYE!6R{M&q+KvLUXOl zac8t$GgYqsOi?Ys4%U#lpQ-sM(2-K8ctf@`nE+?cs$Q&HD1Z|7aLqUx1s_gX%PPTQ zX0sk;1KHz&(gfd-tu&BV^F zj;hud^B5gawh9=xQ|^R92M2BGFe<8g%C6=eYGnphzGR|Tne%33)^Cc99dZ3MmV;s_ zlPKwP%aBgOs{6=T3QB*9eA8$2OJKfmg41~Ntn~yUIuAFMCnXOuJ$&n{73A(@<7JX*!=@dR6rCRd`$x#a(ar;?a@(uV>) zHJQ!J6&P0&BMUc(Bx`)_n6{BmP}ranP?`$Y>0pOeA~#SuYp>MugmKlRm!55`z&apB zbk%lws*%rXy&bEaqQf&^Eo*i?>e@+n4kw13*y%_+IHHHvN-D$IoR@a=NnRSM&&0sHKwYO`qsKw2T+g>>)2A- z!^Vi#=Y?THS4M!9V==8 z>mU}3vewShVpv18tiB3LZpHOYWiRx^D2B84ncQu^KYc4Ju8$%&jhq{nRqgQH6`?F^ zFc|!^XO1b{&Wc8W7CN<_6KJf%rP_n&7t0HpoG_&t3qluA9{w0tQnloh+QYQsz z{gfh!RVeDn-6(WuHQHC1;Ji`eNMrdYXFBSh#o#x)!3Vi(#=JLeA}wXWAFTC|mwcO2 zt%DJ$?~HJ2g&z4|2-|7pj(yR(Ioo=Adf@8n9#T@Wc~vDM*49FO78;n+aeZ#uu7Va= z*8U|!XHrw|Ax+n@aY`j>nEWSnLq@}E9p>-{Bq7oT`qWF_1JX%uozA+xp}TL`Qhs~s z>z_$ft?U}JC!A?au*sje>j*P2ol3x+tZQ>S(%MQ}#xrDeqx34s`O2E<7vMerr7t2I zI9@YdtxcUGFxG#nQz&YijlCu|^@!eEPQIb%^rWvRh>GtG(0K#Ya3_mZQO`#(~w$RcEb<+L#jfJ8VPyQm(%`?Gu&c1 z!W&W#s6Y#)-C7U4GdJCS23qg*WsUN%tT{IA4Ek3HNVIcBd&Z7&s}BJ>bfWpgju$I> zNGD7_@;~8Y*5F!X9g)iP_%`qnmsj!!Uga!&J!6`&WMPu+j*|C#DOIgq)b0(xyYN}l zKv~ll$dYaw@~$H_+hVVc< z$!_EWYVe1@sHtnHGf$=@#;u*iS-5k{byd!lt+C$KCM`2Y?oa&<-a3twm6`3yb0WXr zs4iP+aDG?o0S2p#mW+lS+A13JcZV%m4r#koQMsiKy1Ii$beWV9w~2EWiqD&SxSR!o zIRak`dbH7W(YPT9#0zn^`}0pi_hlfgyoX~B##ZH;ChISm;JP-))??{9?6za&OnRe+ z8M}h3F4DC&E__mM{T^bI1*?{LidZUf1%h}rXwDoHE(6tNBcbYA&cd6K+E6EKNB2X$ zy_Req^=^bCdkAnV0wieNduSOzDnvGZ*^ag^=^P-T`2NDW_PS0DzWtJ>mn7t|Q~OMLmy?U9 z3uka{H6@3yf}Md~?zuA8V@=9RLCh&w&hCn;Ph=7P!m#`}gE63a>Zey5A|i2R{S~++ z+)EDa5OM8jjTj*B5u&gITAv6+bKGMB zUx7mRwqEaV*@ne3eVI~(#3K^OXf9`|@M5dcx_I;u^9sfHCppoa7=?oOedR5`<6W&h z-laBnvMxTvAiPZV%&O2Hvn5f6gO$|G0Z6IO%aIxabJbWw{_wRFFcxEZx$3c7&N6V!oVY( zsbP#aLf@{M2C5$<(I56#&@Knmb9ZG5D`)M!Zut3PKNj9{*om}$bt~nOY;I@P@Y!lA zqvqR>)Y4_4Rj@u0sPVV?=pUw-S8bF~TNVrEH0~wm-Rg6il0UhsF~h!h8#2uw6-&n4 zj4t()T9$NRIV~3 z3YsX2+sY!TW;!Qx< zAV%bSSi$&IjsAwa!Bm+%u^WFFSqWyuC3`#Td&2^se{-x(js7|9*ZxRZ{wUu^uJ&aE+Wr5)4nkFu(nsRlkUJ5rvGy02kDpNg> z8FKBp(R$x2;Z#WPWi1-~cvJZ;Ofqc?{nuqqtEKrR9oH;}t%^Nlm2P~X`+!D}??Dl0 z@8Y&KWA8-e$q-BJsCZcz~L6!x_be3 z%G$Rip$>};FCCoKe?V;-AvK@o$k24R~B{JwcXLnTv3j_9Qt~1)+Up- z&ql5aphAM#ZWTYQ8!Fu=sy|F2FP!mmdlhXBc86W?L9Sj%|7gL`HnR)b!RJ1ZLM6&@ zZE{F4n%a;pM2R(_jz$%$aqP!pc&#ow$#7t)CQzXiPma%Dfq{WonO>2I@p9+XXmZP~ z*J3o|12&iNxmj)yh-|@N**#5N^BY7%Kbnp3%`EkFUBuXje{@OBIJdm(-+QKhz)SEE zJW=)UeY&>q#e1?gYr6J>?_`&|X`(sgFND{HnkNFwFE(cXuRmL*mm@1(vTLz*Zm~`H z20QrXbPc_9{Su}=68?dmXMwlhT|a+6xcKjF|NS8Um5~3Ah5sst{}0-7?E8rOUz-RR zh=|CDZx{?rdwef-cD~oRJuP>=cQXCZ!L?_S^|e9u-D*YOe=q#^ll)g0{{I~YH)||? zFI2}rLr1_xUmu;*ci`22UO^uZ8a3ZN3ryYog%Hytv3L7_d(&SCJes-I+^Ug{gV1f&0W0oH<&3k(=<0THCeF0YRG?0a-j{3~nJ|hWa-2vZ za6&igk`DR`r&iqRMlZ1ez*6O`Xi`uRiNf;9cj|g2MiKXES|IuMs6z`FugMtA>6570 zqY-%o>RNXV(GVcEzIaqF6~l+y#d>=ru{+#jdTt)RFrGo^S}Rdz0e?p0f|7o+q_}yn zWQ0P4T)CXl;EoAZj4?So#?Kra9leN;X7ujkQ6qA>_7%DDUl4brSCMzzdNcz+-{@~Q z@1nEBNNErWB6Jy~4)j@-LUAw(46hx2<4Q1tTgnp@a)CE1!q`zSfk|%?mgM5i8Mz}DR9X|vl0{02>syP>B(ggMkJXoY@3+j3WPFzrDtSh=Xh#LU z?JD+7=Z`9#!Z;f3jzibNuz2Fj<$Fal18CE!PkN6m7iNfKo#B|EaW^j~8r}Yx$600> zbSBCnXMtMYTbCljOPJY&5?$_y9+g~FS{|{ga`ZLz>&SQ9N#Y*HrVptUB!)9t!qy`t zDf%*5%8~TVa;IZctRa9Qt|+?6Xn43C~c#Td(u=Y$a3a7PE@{_~DOr`M}#Gn`|jhT4AmPK5USBVwGkC1wcj95!;JQD^es zs{^B21)y>OqYTbnpUr&%%1dRtENe(zbsu{NMjMq?VHTejC`>4`1rDq3!}zo;A!AH6 z2_xdvJQVq#k=5kCPp_$tDD@Mpa0qtOt;%73$Q>Q%b@V$(rtZb|YtbRFlcJ^aeDlCG z*zz^+>wXA;5;uAXT*8;?>q7YWIf52l<*nCDZ%pe}sJhMPnYBE%sqez7rZkO0)uM?T zR%?CIYSrY3X#$k}Z(kRX)yXArsaNSChQ=`pq|;kxyUq_7Fe?ny$d&*y8z(2)94sdi zdEHhq)GXA%Ac1|_p!A^EWQ?=^idSoLdS_S?o9@KWOM6&L<+=Eg|nf#Eijh&2ZR+3MqzsikcYXT+c;x< zPB!aC59Ln?OJ<190Y($@S!ey|rk+pSMkcJ6sqmQ$yBR9eBC-tTVggg5&aoTihNv8K zFt|`a7;VS6u04bbDZ9~_jG|S}p@=(?3MGKSM-zo^KI}Zb7QW}qNduX6-j`Q@+rk_# zvu9$w@=vy)xvV(YkJpGOEt#T7fx3iOs}4u5*-zy;SU2Frtft37 zKp3P)8VX}WDqx&ReVDAM{ZwnlilMlI)gD%rT5G$fn<9#UTda9}?$H}XQ1(k2GG~uy zoReVG8+_)qqrlvTP;)GH_XkZPLXvDXkplX(H25iDL^jHgA<5x<=lCObbeaIct~JTv zAf*r#ypKoJJ7>e;nB9vR%3aNa8)0Xn1_z%%^a)=9_82@fH}?;8d{>Cr^fdC;I`NG1 z;kv}^H991caIP6cBzp7%Gsa9-r~>N82^d*{EsE{pmI_*3?6?k5a`=%grVv?*wkV## z$iCsYqu^zfwgguQl^a8iWaqa?T_=g+^>UBZqXzL{>DjAse8r>-v7)2Z(}qHDoyGU7 zy|I%`t%?Bk*Us+30)k~5e;|suZlX&QqcrogmJj~BWj!|%Zh;#s({Q*W^SNhp*9sZ! zc$@aE#}LhTFIH3U4tUt+nJB6+rq7rT1d1fO!D#cfPeLF) zb|u5oT*C17*^EWj%1NUW(Mxib1(OJ|;ok1a?R`pwuy~9#;1oFh2aJe8M!g*-$C!yy z4_ZX_P~qeg!OKKKNN4Fs>1bZ8u*o#?UGdQGW*0>rIwZbkSBlap$&B8Va>JC5QDj&w zks`AF8J5*arC0A&hu7PP)rG1k)h#abz9KXhK7~A?$qt+jWH(+)yQTU>GL^&WmKIx~ zHxjVQXqjBS*qTx0MP|m0Xo(er`G%B`9KDezQt^IV6$Kfc(y-yTYi0nK5B&`qqu!rQa! z2**`$J52M8nyYA{i;#;q2qM$!BLsYUKTzyu6+4to>y`wmE|+>4TYcYwXw+7yc-1!f z?q}d67EUV?-xHAlm{6;=rGDmkrlLEaDUc!} zknM1~(o~fLJ(uF6a}qXi7P{x&hw&qX;h@Fd(G-1s9xA#7z9^63Yz?Ad5UwZt61;O} zFYQQ>&0Qc^O==>^qYy|KfpV;FAz&kfQ6LS5+Wi0J7X0mCgxCrMw&13}=9=p#ciVwZ z&O8Y)T#PZ0!IMQw!gouKM`ea^-YY8Ik{f|jVp?!c+?ACt9Ta_&=1Rr2V+VIc)XvC! z%WyCE!U!3iwmeOOWt)XZ=NuscfTe0~Yd#bIm?i^;R(rdi4l&AhlrU^IA|D65VU&kp zrLDyi$G8I>g(B=OwEU`t!g~WPzFa4ZU$g*$DDFVsZoZ-%l`RMe<=~uxGOd=`#n6iz8HH zbz^sQ!_BL<6UCyVbV8TyQr303@uRG z&wj;ckRS)=FN9A45_@^XuKDZAgM4HOnMy;GS7Rc4D^I z080b$;Z-^OzqQJ*SXr4P-@tK(nE1zuX%$x9o%&aY7BAmi4Ce75lw(AvoyJ064!+-V zk*eWvE&wL{G676R`TkBbz7)4!>W`j3z@~Si4c87A0`EX#VE(JLK^$s9fD9S2TbbgU zYuefT1a{HmY9tUqg#}y%0(|M(}0>&HlcGn~VyrIQS-_XT;q%*oZxt@PwLHLc)Tw-w7Ss$lLjk=0L8-b>-)0l>cykpFJlA?qZ} zinA~e92&lpFA6H3kttTIhYl`-5E*sTmsDr!2qjKN9|K<9yfWvoWtlnE#**s9CDAE0 zgx+I{H^^Cq@d+}@Mh*o4pM`&eK-}_3!jUi}%Lw-X>ays(rLwf$g?95UXK|MfPs@RJ70-Esaip5pJ= zwP6ur;Xa`@@;-?7>`_gloNFLUbm1_Zx$YlVA!{fZXa|hhA)$^Qg-0;`y_cJ{Fd^LO zB@G*rxxiQSp2zvOM_1iq#`qpYDGCv!W5}*%BwPrNGHk34H7%)H`z~C-AKk$w( zey8e3hOjbajBO`q5n{YPTdaezuaJU#wTB|D`d9p!y@b3erJ5*|tX2b#;b z!y@N{MdIn9;gf$McsxCtmZOuu;x~59f*ytWy*kWxt}m8}@E3u9Jqx7ua}p~GwYXAN zTq6VIXbj6p`Oq;GK~7E_P9Q0096%m6f@2E>A4~}yOl){~{idf-Li^HX-+NOr-f~JR z!1qS)N&bJ@>cQSjiaH2}r(lYM_pn!LW|OX^I*RCjooS(3@K`<*%^_QLaMtI>2hI&G zi_nIU{~ucFuD(J0)5+^bKX^_}Ht3@QQB&kUB{gOC-Lmy}pCA$CLEYO3j$a$wLP3kD zoU%reCuE2Tv4FkUS9U|Wz>qV(0mBEF5veKC%z~ggrN`$(MEaIgeyk0$+{3 zZ>Jti?V;C6tvsKef2QyJDit&^Yl|b(wzVovWf|~j35ZKb$RL_eQoY(m`WeE&_I6vv zGZ&z0i}VGXpi+2wjx~l62V$V`>fc7>zSo;=$q$s#uB-|~KS`f_0|`lbe*P}aANpqp zkWHM3J+kG2ONkzouSJ<@ZQtd5M_`L+kIF6ZDY-OEb00}*-QPtD#}+hRlr!)BdbBj3 zK~NGkDMI&&&{)v;SF45*w?U(xjFQm7iEGG}a!lgk6I`F9!bL>zZ-p>~@#IJ-UY>5g z#A|3q&&g;k#HaTYbk*uHUB2TlzR*S1)~3cHqbxcTxo~HSVpu_lTdv|xWV0i6fgkyA zlA_|^WQpzvO3GWFlxMB8iqS{Wk~AxLO8V#fp|<==enBc_Af!zvVZmpV#%XS@w;m4@ z3O2&g|JXXtY#Mg$hn&H_bz(!WATj*|OzESEX-$4XR{cX3uheRbpL)_Z{h&oN^oivG zZma&G7H$>mBcfWJrelWBhu&-OLTj3E!&pt}HDIjWW07;3J+ zV1!WzxVT84zd`@s+TvD{=H_s&!T^hp*DgVPo5B!j*Ky2UkD(=fMMy=(jm^-vZ~r*7 z`+YFB%{SU-+xEFE2hNJAhS~`PuRx}K2t(EP(AK+IvEVRmF zyaFXrO+8LpS08*VWv4R?Wnbd|p#Mu#JYo(GKp1_+axrLO2GQy$4V-a`^SllyID+Xe zHRF^)3IB5&(Ec_s=m=ZN{N9|AP&u zp3KX>p_B@8=Jv~BL0CG24WqjcPiRZNKl8JtM@uZAYuhvJADR+A)}JRr!=<uY?mD7 zm702yq8a^hLUBx1WgVsTH_yNR{unaWO+IFmY5R#8eVk2P-Dt>hWDI2bX9lh%GGEV0 z>5A0ihh@mknj5OO5{GE;u80`$k+_w^Ra%FT5wRE;XXyC^7+nOGVUASXk)W(LrBXx^ zM5%_sqG&8b`BI|&GrEpQE+3!tNcO-EW)qJ`=}G;LFl~MPOgnI0_I{uT08hQOD}$b# zNX1y+-~!gy6tUCiHA4$2H%*PONMRjq@32)XoWd(0f5R#{jCq>JF@QQ@QYP)S1tC1+ zFkk@b@RY7G4d@63oZs&6KdnLjF_Qn5^uG|$Q*RK_rujrO*#gb%iO%Y2(Sjwi$=Hde zJS%DDKFD&kQT?jpd}l&lPGLsrV-inVeenZ#1ba1%2jjXnV!%2t*2=Af?Lv=eb^86Tg0@v!2x=7Z7Z^8MS+vcAPS5#TYz z>IxN-s$_cAH~HR<-928=kP?*^EDzNG^r08w_pRTHNdD|FDu@Lhaq^+#Jsqsh5O!4# z;E=g6^_O8M=ucFaX2#}54qA5C0)Mg0;qb7AVi|OQf40_T(UehT1z|z)yh9h=2}PlSS~D@&7p_9b)fe>B?u62HRv25KS|{ zcJ}wbI~o@R8v}Y}COTZ%!}I>QDrp?-Z3JD!TuTci4`Clr$v?`tW+79$0BDBel>I#qqKs*T*=7w~u#66Df4!{&%Rg6r-Ii~K=vST? z_7jheTS(SWGh*HI&l=oj7TI*|PxLd90e0jr(sk0cFy>`ez7b?QAiPBVHocCDYNigx zbhUxq6{iNKz$?!WajwIAZT6q`aJA&-&f+RXgAy#_5Zx z5}!1B^ippf1#yQhP|_n&Gs)qxu#sl85Dc)cEy__4p`Y!tF|x*G$wm2TCeSWhsnlTh zMxmy$A%JCg)H52G2f*&NRroZ8#>72pAUCpHcTWLf#WXBA#vOqUK$T~ z3%kyl`-e{RzlL25H#GS^VbIw6$K|wBZPMX4+)nWC?2||&a2REHt@~9dzFPs0)Zsn9 zqUFLtOl4seUcU!=xtn!ai#@yB?FU!$X4pqD=?B#j_7;{y^89dPB&hBLA4HjB5 zwl>e-v6eHCsHaPkMN7gHbxCmS*(fcgxsicJL_rS)LQ8F;`cO9*UW+*G+ac7P@9NzZ z8eEI$xB?+%3AbB{*Vo*LjB*`b-)1Tf<9NMvAy``3Z8uW7}fl*>h@7&btoNF%xY6mbX)S=R7dGnv_f_UlmUJV2xDqg&y8+b zf6fB)Vei4aqvV5P3M5RiR7b;K_7PT4$Bc&r!RFcc9s|}PZvFBWR#*&An@OHh38D@j zck6gFcA0ds6(}oVK*&-PomjTfJAA4~@5F=EFR;1*zuu2T~0nVKYo}=IPMkaw|sey|4?zp6De(u+k-Jq!Z#>&=+H<* z{p;Z8iKFhoz3Y-3`fy6zK{AiY(g1&YT)ibds2i}vW@lp;!fiKp4ef>Ic z?-6oLYS{ankCNDK--ZCUo73yRJFD!s%T5D8E504ABrXY_vOI@|-@O>uUCe{n<*Ztb z1%tsU7U=Lv|EO2O6EDTCv3=5FEZ5#`LI*M6Mm`u5?IRuXCAju&c5s4ejhJ#Ov zdnpr`fyz-s+k2X@;TfE*7?CiX7VtCLX;;OdQe}hwVR~h}2ckP1uUj`L_;5yw$rYo-+|zZOJ5-V+b{)mn{OA5iwD6 zFx-H|7`MuNF4ek11lbDID~A*01A*A?6WQ*KW?er$3yQwZexv<}C7d>#97RxfDcVG# znx^LS%b&Djcp3P?iWdtm#Ylr>$T3v6;1QAj2(T*jwmofloc=%~wSXvK%fl^3`KF<;vEiG2kylJdVQB2m@s*60m)eAPj z-bwAXxTuUqTO2_j9{(S+Uf1gpau=u7 zYOCnvU-XAyRAoL24-rDP!ZZ|6aoTC4KUJ+dBY;tTj-4b*7O|jz$Aa*x8;)Kyrr5i< z=j!lyfb9uG!xMrHNv$Ya9j36S8?HNJPf_XmDR3T}FG6BL-O`vSg;sgf4VF{0d#&gM z_r$9ffNVSKqznaPG``sj5+at!e@Jdjyp27U;+$5t)mUamHS4GnJdYiYA2C=%MBxrhg*VxbvmiT<& z6iXD8Q7(~0#o#UxV)*|s_m*L8ZQH+a2o@ZIYjJn?BEj9A;_eQmC3tYBc!RrJu@<*N zi#x?BT0%=HEwuZFefBx${-68aZ}-Fd2Jcet!(tYm8y?7 z)S=NM+&Lk-^BwleQniJBz}WCrm|Fv{$$i1b!7%xUYRUXe9o*sVF308EK#VD@n4Ks) z=s1&buEy=a=^$!f2OPdc1dh66Gj7z*oz5y>qjd^d%QXTtub%h^y+vvp@ZegymH=~o z$)E2ZBf>tv8}Q%xRP7{1qdJU03ImDbGqyl z{*9^j%dqnd$%B5X>yezq8j6{WFEo!j(s9rz1l}+02cR^gxdhLJRe0^eH=GkMU0KpS zQjcDSl>AGFLBRM9+2Ym4C8I8|4#`i&;`D?hjN;0Z3-_wR<8G~7c>$GtC2Kequ|Z|T zBhR^l&bs$PeHvR$lwT$$h8hC0$ker#!=)F!*qqaOhzcHcI|(xU?2@N}LQg@>ievF8 z4vq`oByy9ntXL>pR^l%h9uMW-gv1D$m)3R0r6Jox9S3;O8TOX{di5XF7EPmS2*qFR zH0_jcRF!b6f>?>4d1?C1c_A2D52S)(%%kiuXVOM+-+O%V8dN^m`$qtvt4}CYi0Ww# z87%`(^BA)7@8pWo#TAIEV80y9=S}fzCPp$%ul`oNoNS}>lkDijl5!tOwACnpMpZSU zd+@>%qy5yA8E_8xuqo(%Ni#YG=-7g>SqJCf%+`PlHZc0wW>P^KoLlP5;FsVFO{w9; zNlNP{|9T?NMzM+0VKw}~e&t}*^&)XEC0Uz)E84j|CA!HXk_K0DWdFD@Tm^~wF(0w_ zxxtSbz2^fxouDX2G4Q^)N|fXP<`_T92K3zH^o!PejeZvC(tfk}|EM6Kc)BjSC5D@? zH_e<2d|Jr$j#voAlm&UZRIA?1*m$XMG(IMp;eh9cB_dSA_oAF znr6C*HW5$!O9&>%QBz=eJ={a9k0|vgkB!M%*7pnGgp5Lfsjiizx-Lu$WPz=gvUao{8q5Cz~tW4_;0M9a7W9Vf|ds2liH#8GfT47qLI(&P&|bgMUJ+@qqWuf*5_anM*X?hz6Jf^ih8?KkfhP?{>e+gwrAY z=;#j~`s0Q#h64|HK9XhIhTG`7-)UvBYQi4cu)6h}z&ptqzzou5(7^yM$q?hzIimX! zA|!_AS)I1ns2WnrvGZ26^12wVKs;lJic$gsOIgG^(lfBt1n}NO*|5uD8K_!QV)Jvg zN4>^+LYh7;k8c()grb{9K^Lqi0|+Fi@HC6MmHCx|N&YX%oR}De3L1$o*KVn1#$iJq zb2*wK?wUf=*DUYe1iV+c!4RiC4cAovr8(zgz66N(9-9^2k45|inBzPo81TdV)Ps6u z8Tq40?*0)(&@2YW=n7Dx3AU4Q^Ji5Omy;^4%gnKlcu}^;-w*!Viu0RmYV@YpKVkN-mE>reX{#Lc57_ z(-=pB-@IhzNH(D-FQ+|iWjAXNkP`IO7!(m}*iL`ey!V_BN4gUQFt){K{0F&9NC4!9 z^9S^G!xi+kz@>(^dq5ECDdJ#1kR;)uzLrPt%_*ARk3mEs^f; zF#bzJPACTx+uK>wat0CL#ka@Jt&;IM@f;i%`qH@rKh-24N~A-6FsvaskhU2r zWugp0R&c4Rt}5Gnum^5L7$wrB_fcRIVc%DRFjP(qdRPWOoHOEdT%tz!W$bu6oxW?*s5CXNo~OCt0g~ zr0~uT0&ma>BvS8{(d8oWi3sO0tEh|qwdYSFFM2W&5=FH01&iW&zboQCk^+r^XS-sq z-nKvsSSrs$%e@ul#XSjS(y-% z8eL0h&&Uo+f~clCWmUo$C&QI8TDi7gQz0ZJZ9A|8Pg7Vij}iCNzbH^GnV|uWWyaE`~__jAi-y3Qv!SR1oMYG$H*f zlPN#`2agD%C${(`gP*b7)UAWQ8%aK(;J8PBg_~?6Ve-Jg&|(;tHz+xX(oE1Uh*_dkuLv~ zxS>;o&`0TS|MT`#e0Pt})OgX0ac-R?AJX}(0;MYPz2#JtrS(@$!5&A9w#0lGp`TZ% z2%5;rg72IEuj#~}b(qAoxH;|ZbbyAn9#No~&Q##CbZCqEF7E&^|L3;332p)-Qv|+d zz95dt2#pi-T<4Z#kQ*bM(Lq&*kBt2k@EX&A_0ywlCOM8haK+|6C(IF#%M>JntIS_} zsUA2x=jGXU)8vbVz%7%@NVKY6;^VdAU(JHBhB zM~&d-SaJP0&wJ>Cn;NznF}_+YVG<$FzJW{~hl!BTH3>cfpPY>|>?xr4dU|LAM5~Kn zQO{Li_Cuf*V)gAomZ5tc!C0(|Pl;KPukC<@R$5Ug01yZq%~U>uu@)bE9D@eSJ;-7j zwF9u5PKrBGT*HBRK$FRe`7o8C7aiH|vjz9Cs!7Sb0~`AuUEGcNh%$G%$ZCJ`4!v{5 ztpo;Gk;UvCMR^4W|K4`=q*KXfd+JZl<#PD* z{sOGnSovi@U|1!;*}V$X_(~sJl7VR5$7oasO{UKthDC}T33&@Y3A&^Xwk!^9#TLC9 zHu4L(dMPNWZeU*{xiqCr{WM8f+moQ9q-uI~Xp!zb44bg|EJ6%wZ z{(lBFgp~ouXWJ~88X4Ksb5$5!?&RkPLA((68^7nsQEPt)LLCSZPGc*B?gmUN7u<0- z&OI3)U{hK!Dyc-cf+;`>GirZL-Cs^!voymq&^ERtyK>MP3TKo1{&b^9W~WH`ELAEJ zwZ_#o`mE%A*(p?-yc0-SEE%UhdTwmdZg~`d|CaaBmoHC*rmDOz0ZtyAq#E#D=vrzP zSXaOsG^0tFDDXsRsa=vDr)|3e6D)d^Ab)+b=c;vHK}%)EEePWua0J*73Jn=^yW)~%YN_qD>MPQ3zB4x3?0VL zYO+539=7&rkRQ0v25N2?J04>(7L<>mcp;83X*+E6o1v9&&Lx_3ebIHcgVVSp#-&Xq z93@W{re&o_f?x?WT)*Z5P{*ikTbqgmi%>bLo}FC{rAKXMhn>!2cA8V+D987q?ShNS zFrAbnH3k?>^;xH!Q-OLs<{8AKmsF2NuBr-vm!bn`s`NRTA)SPGX)2DVKweXH9}T20 zW({p*Dm!F7-pJ%f+wUHaM^=_4GD z&r@QjKqWduKXwLp;lLciY5HFHUG_5p(4#V2M67Bx;e@W7N#vY<*T(t_+2$Hu6>EfS zhMue!+I(K6-4EJS`lWvXmIiTIXF*~vrbhVNF`n)Vm9hrfBk~K8!WIqKZp8}Cx5&De z<8OB7(3M1vjVi~lvs3d!D01l9fZom^OrM)b#*7XD?HFMNV_}6|Y$ssWB^52gT~}ii z6gmPS9+?TcJ4k311M#e!h7ng}e*xQ;WZ02$6OBc^T9r%rD1I<2dM%-)%>7pVtaMzS zJq_|;1!d0<`Orh%m=;F+peob7`)70XH?YOZ1H(A;rrfT96lC1=U>0GUy{}~b!Hqr1 z3K}z%zbv}XnOzPV4$Zz%qmM^V|J=oKwlEATivt2$_uE!VSAM{J8|e5-*>@9rEvVyK zkS%Fmuq`%%38I(olV^E8NWV~OHI4>W+1*yG1j=y{ogt0opg=m+0o;9w?MI(Jl8J^n+7 z6lE%4lpHx?r9Sa}YxsGYSk2>l^gtHGER}ml>9|s9UBxJS_T?|%VcvdXJ52}ll>#~% z$%3kFNsd)Z*(!;Cr&GbF#R>m`n zCN3;a3Y*c&TNiROcWPleWnACCh20*7{BTSvVIb*DrpFG{S{*-%ilE%6Sa^+*;r9qK zTv<4g_9m0hCop%*-)O@;axS7C>Uc|^d`vM{I6g$j;DM><84O1t{pvvRTzV)JDk>%C zi@!l6q*9R@f{X@vsqDH!@H^YHd+-ICkR9UJ7FYj~TRO{Uv_xb2!;a~eqS2p8T~%8t zd@4E5n@6L1MC1Mfn1~J_0R@Jth*;omr2##1y27vlH+u0ALVS>iygFTxUIzbO=B1TC zm?4t6h;$&8o?U&2JPUn8H$4;A;f(qzb}2Id@A|nn@psT9a0bPr;dZ}F)oEAl7|vYG zj3%?aIYB{uO(yRa&8E#G;VM@{?3<<>Uka5sDWmp9Mrbry2{Y0owJ2s$42C%--Gs5D zYPreeGB{3rK|>UiC}J);<$M!=$7qHH0HFZM>;?P*XhYX7C7qC&;fTf!1CAJd>8#S& zxDOABE4Fl)1eR&n>F++I>Zrg;1e~pv5BOI5LcO{+6Ne+(4q{eY+Jy#pl4%sRr?0fw z;*J$&*Sk@4WiOOm8D)^2MiJ@;fqa+(n|rCu#txM6H9O#wcT z5h|N_z)7aQXN@?ODC~03MAy}nIl-d9PzzJiLW26!i-`Y_|7J9aBS?F_IW3dGS*OMX zcLf~{JA5YK8xe07D8j`M8;e@( zpitc7wx*K3-IUrES6>xMFftc;hzzSZ3XcLP;-t|iPNt$d!!OO72r<7jA^!ut?})f-u7O-y7hprz^s(aw45D>(0rEB>3%4^gWV^S#xJ7 zo=&%?Rw%}-Z=I1|y?z!~15wqM8N^;OD{V#Tu7C3>pQfHFMwQ~gMMlPd$XsswRD5lF ztqrpykJbwrk^A>{xG61-a7UB!MY)!kG&@ON72ZK4e{H;(Og^i_%|S}JUH;&wCUTr; zTvdX_HQPboxomoqQ0Allf2tA??9uvwpSX3tAz&tjT$bU>S^0NLuesc=nH1#=MYMvzymA zADJP%y*Ol7P{t#&zT z_o-q%Od!{U5k%|$od`S7o$yPUi_;mCXkgiDp5zZf0s8D&oxb1gRu0}!$^X!DO^JhRg+WhZ@| zp33FMi-l(&DqNOLFSfg}+C0+7YM%;NGU?%Y5`(3N8pA-P+I>}^(?-re_7+d^_sIGF zqgpkPBbj{fJikwA7O(~$aQnJ2_05chAkB(#6@{8!%9n2skt3aYgB`|5o+;k*w*!($ z0hY|f=%C4hUiJ$DZJXRgO*9nj^HP~ppWChmq7DAOMeR{W=>>m*K8q2w4wA~i^3ja? zqYkZXjWV^4;p!1agEI4{R+C%b5c5shofSuPB2#09{7-YpUj%K|Cf4Zp$RmTOd!MSL zRrUOtCga4BijPXX#I<`;g8p9{^(IzES69W3N5YSFi#eq1JG{ssKWBmFfhp>ofulD^ z#Qxg?A?)VPGa{_A0&5=PBo$5-kIVxfyX@CluFc?Vpzq)PCeR2{KqCWb;{7;addiy% zDP#&BCBdx$54~9Fbx}|}0I-Inx8ChaUmnwC*VPC1enFZJNdEeSV(Pje*k;=0wNx`y zandM}*9~({*@m`iFe{s**KWxa<%J7Gl@jr?s?%D4rxx^a$N)n_2{FNj)hf4@NI%*P zag9hqGC!*7&3;U2QgJmPB{(sKO4w!UYa3YG90E8Ft|c{Kh1IcYjnA~#|Oh>K8} zX)~~La)&EaP)jLa zGD%-Dx)5JY{sRippC%P31D5vHdd@oCs`}cIb3r#X=;DP-rG<3e04Z%$gUxaxbcB z>HWo_n?+y1N^DTO*J1Du&2mKuS3G8#oArQ?{?9U!dcz^ON`@-{{l!Q?8}`~&()h2^ z5n_pR)PQRF6RXG|}e3GeY#wgS(u_^K=mzn2>{oMt{I zLK48t&q}3~p2%o!UL$R!Gd~UK_PlSkb&RT$TNJC5+WmZk}I2XI`DcKjKub1PmKZ?MNMYSA4sqsTphriDzc6Ve@jj zi5u9d*NH|PIYz;jZz*MjTI!Cm%PYYis>Eo;F$cbCd(Z(tu_w<4|H1v^zwJ)-;Vk=| zwx3|xP#Uw7>sTXttIS}VXbU}Gdavx<;#Z9h@-xBK%Zn5wJ=6@ho7s1PSAOL1?oxv< ziuRmlz03ZiGzr2q9fNakQeAu~d>MM3zSK6oMWR(?6m5?L@{)*Rjdg>5j58|;3@%1> z%0VdeNM33ZX5k78iFij_$1sX!==@=zU>2zGw{6uoYr^&?`|QbQsY))6ZCF!L4sn8D zHta{4yLi&eu}g~seDkzWmPueNaUjEY_Rjzol#yQl}cqrrgY!!jvD{ zy*Bw(5IdvOf&lin;t@)Mm^e7P69`Wu`pg3xo=+|ewIb7TnvdTB6{2v74 zWB+l5=Z{;yNA;VfQh=fXfcs)ZKT(pr>R6f3cl%x`D&zZ3+WCEGjT-t}zozJlk=set z9d_?0quvi;=kZGF%1X?sB?D0Q$KJD2VQiSk%<>}Q7)Fmnu}V3*sz$pj^kGP&-l569 z`#^U~(t zZ9b8rf1$c)O&0bl5;mf%MTsA>E^0i;v*b3-0b!czKN4^%k+{l?!xLE2-t{$ZBjzFs z-$v6VNJldO>Yov${sU8>zp(}R=gB3oz@!)D-ogumguz}ff5A%$A;>~=t%(s(8x#G$ za~Y0m>mnC!KHha*+EYT5MU-y3*=yw6;=A^Za-h(rb1}4GW3r%9#~Y)1wTNXMP_m(Y z@Wm$wYnB-l)CmOzR}$Li3^BYZ0mIwCQ6|8^01hhY*q{C+GdX!nUB)wxbkx`(n$4G% z$jl+ZvQ1q*IUsr}ujLRb_=9S$)taf=OMv~Z9Rtj>NIW5=$B(>HW_JaOfAsuE-|+%} z46%cQ%d;O-A5hEz1JM1WSwvw*Gk>Cm`xES^L0CT%W|M-JTp@;qDRM zUSSIv9EKe31_^#$7Yeq83jb)FGoun%<(W;e!K|JkfAF+fShkV6N#LvH>xnNzPX$!T zgsL$))8W&EISTRlZ*D;B8|V8jh~Cr6*SsB>beO!B4R0uCOX*?$)zHd*naNz#8jjD5 zvBxhIMA(?0k72DCz}vS$jw?!1;sfkuY;zwz88O-^x7G(En|yaAwcBIfBIA(%XS0%* zc4SbFFGDKIoB~qx4A~AhuYrg1^m^>5c5cETOKzhnUs|GlxEzQ9%LCxn+4T)(w!suN zE$4Zj#C|ent->XEnJ7GD_j5V)8+9?S;)c## z54?~To2AJjYz?_M3cJ+eOgNEE<`gr+*7**uM@CZ1smbI}5evb|NHyo64WRG2+@+Vt z14Cjn%F6KR%gI3z>qxh6UZ)Zyk7_QAEc$7R17#yx`Hu=^YL+bLsLBc5&G8l$wS`xH zBYDaB`X}1CZkSRe5>K=R>Ew_Hr6r!>S^X|o_G-N>e-}-ZVOSAN@#4)vwQ*d` zIQ`dfO2@0WwC_09Ef>A-ACqySgmL7|jLRipHypbeKR z`ujP8P7IU6w{geVL@&mQO&0@e?!{fW$00Y{^qgXUv zYQ6K9;^g#7&sFOK zMD^CE7i!wq;6bh-*hc9qGPxH-yN+l+f9~Y1$9r|f`YsS`jWCcZC)1ecrR2_{o-8kuIOP5+ z-g`Re-w$^%&B{z}%%ytAL@sW&X0d|X)FYH6;Avbnhk?=-*YLv{8yz5KO4aneVOWDG z88DPuRvP3xX^)=3dK0Pyh{mS=MKJa^sSuYxwWp5@Bi51Gn6nn2U52XFN~*N1ivQ?w z7@&RjaaSGJ?`yd33R4taIgw$%!Slo+uC7>aET?A@1%+EG`y~9>!QaWgXmaiTosYy^ zOS}Dys4BL5lmlnJZBIh6O*9y#(XE#yA{qma&;v^n-r9p;VreMCsJ#bD?cFw25T@){ zQKEN&2zKv`YWHKMH=V$ZASO3EmY?sUpN=@xXP3z-XHOZI3HYij;Qf_i?r21XNUuiwc}haLLr(t0H~if{ zqavS_osc1wfyjvy#lEf2xS{v(BM{7g!Q6+{_AG~bjY$A&xPTNVhJkfy@KagBG;qH~ zedu_>S3ru5EVvk@t^ds}3*_wYR!fBw?s?Dc7~Z2D?EVG#-#_O=UL9=`p^MDaKpBSU z0V-D6V$w4=aR411kO}FRh+IQe>9%6CjI29U>-mbFK{(<_%~|Yt(9=#xZe{ac@pKjvO2fhRlC5?hD61Tsg{^xUrmvfR7}-=wb4S8r(tw( z1KCh6BC1*dArX(`{?1w*$cc0Di+YLLEdDNmEZ86JdL4;&vvujv>#8-~lHW*Ja-4}J z#Ivm?*&JUa{wX69D94Y-lNnGSo6qQ&)~6Q86`U_%#~75hGtYz=P(vOP^=Ig@*AgML zCItc=wp3fm(%_bI!iOqeDrD;ZL02uotW>}dX7Q?t9UQqXn4*-_TTS{H{(ytKQ0$42 zL6$cCOx=m3iNmI$X6{J1Rnk*c$e;yJJy5=8fAm%-uM!2lnSHaiWu95*8WluZ$O1vu z1OQN4o`BbWxpLp^LIXJY7c&jGikAQW-51Jo2 z2zgGh!v(*7FeH=ns;IL)X7Z2}{Ca8o=iTGWlSBfbSfEU%3@YZ`B-a$G!!?#t%iv>q zA_CoT%k!O7->2Wpb)b5flNJ`fL4n5H>w@8raY>bQ)nWr1u7nH$-Ji5=t2@MW?Q96A zaQI`fEe9nYX}@^sF9=b!V!HPA2bGq+>Mh*Z;a zb<&TeUNZY{RArzs_$E^y%fAsma<&sj!&`VqME^$V+{0=)5la{mGvQRe`0GAv`;Pz` zHVGv?<}w3r;=CG$01|O=is})+UoC$*AGvL7mrH!}NW}uVk!!q`e;~ z%H%Al)HVIE(Bn*BP&>4}C2nd3Y9P<_tfhF3?J!-Glg!g88P3F5e{mYr(#3%2N!^L1 zd;b+Tz-zp{<7eb+cDf?)kZ|0s=)_Q|LM%23yY50Y^i&@OV-IKh_JKvA^Xi3b` z=*O&*9ks3Wj^`!k!NbBfy+gmJl9h6_l}v?C+?!ugG_z6;^SrlM3B;-ST3bItcueft z@qB)9$fo3I-A7@&iZ~dP%kE}6LxW#_JrxTd*N*0Rw|eIu{gGn<(ODPQ!T@tg(UE?- z4o9?hcVE#~XP8*yrcA0TZhOk&7&l{!PkosN)x>ZdN7rg=V50Rqp!&j4ZtD+Eq_>07 z#6#q1n6@nkGTBM0{A!oOPqEPsYW;kHaayIvc^B!5!IoY+lKwDCyI_W$&VeJUGlv;MlN1F&5bPMe$uA}V2B?oLw}JgO$SSjd#F!4 z|EC<(n%DSp%yBfS%8jMtrKMlK#07SmVqF(Jg9NaHE#w5G$Zzp=g7461UONwJ)|z=1 zx)XO`oED6XjyZdLeuCpFMCg|%?`1fMCquE@#TLEG$rPTj!izE>95cmMzHE(|)ING@ zMad=VZjOSi#dyO`-^Cp!TlP*RYNo?u@rMhz1Pxn>r_Y2kvU&(vSSN5plV8NZZkJ0K zt^YOCf_K7HB~F}&@axN}l*Wh{%CFHsSG+sRKk1$;IG`G1!H2qIY0Zm&N~d?bfHxH@ zM;Ob^i)7I^E{U6DDJXlhIe$*}cldYEmG$$qK`ktbw@_AKHY;jp)!F0+$gPPlaXueH zYj^XK*oR9{Lq+%C(f9fQ#Mf!xodvu-Q~fT3Q%XRhaCxEZN!R!70k_M?0mY-KZF7W} zuP{nMoGXB{z^ZT7wB!$ApQ@F&N1j(WGVnO^q`IC8e4f83Linmhy3pUcCB$w~BzgGFRU5veICT_P632AsIX+#)SA; zD+za76W$}Kp;Q~@>#sYTaUAiVGl{7qU|8kU9u102zpIe~3I&sG9ievjne}6*++^f} zbC$BRak!un)@6uSJ=|y)TH0E^j}FKIcy(b@zs5yqxu_)%`|j$p18N7!jmu2?z!aaB z2~78-lR$+tdxl8;BV#8--yPnuyxUYg?Ax_oxadU_~a>S-X&tFQCV z!W#|=Z#acJp4&zozjrOi=hnT@UjsG_{FTYG!-Z~A?5IAJG-(Lsa5%E>HaN>hGN!W) zQ9}YHwL}SYaWoqOoO#-gwmR>n31%>giYc7w@&2m9(*d>boioFhW49i>?7R0Sq>szI zI<*EghNBcf>(sDAbtNH2Qx%fzmPA3J_ePv(%DqGazsvtkg-T4w8frkiqBpig@$G$$ z?(4kMqOAR4-S}i%2@9UM3LdU0?(w>2)bti}*FI}2O2921jx9cjj0CgRFY&!6&@teq z8Ks_nN*5UmTm1Ynv+V2u@dO#QOACv0R~=LWv5;W-*(_TTUm;7mdt~d20k-j3S4GlWQ+6%t@T&h@fWYj z{}x}$Z!RzJ(z7bLX$Mc5_}El^_ht)IGKM{tXZO=g@UqBpR~8&1dOEQNe^BW|8#A7$ zJer(;v*;cmjADq=mG|ql7I#gdj9m#+e3K3GScBe)5w?$(4TmQ{WMc@75LIQ2ca+~k zQM~c4O4eQk60Dei9DLkoKOi0@iunnPQ0**7t6g;K_kecZ?`>q?;$z~~X8_c;Os}fe zlwl0xErWAR{zte!Qd8m?BC2E?qtf!^2Q6W*h#VOqDs%CcxfNzW)u6_kH5$4zCF z#wI}MeG)E1)!s@z z;^2>$n}j31-)|`nFND6Hn#`62(2E+(@5b0FbZFF9L7kNn02vg)Pw+*Rxuzq0gKg{| zXWo&iP}vJV6+l=?2AnQdYiCPyH993rEOYAG`8uWsW0T(z!`JmB>tfnZ{3~r1@STmf-|sHa zynP*N=uNuTwrcr390bO5rke0uX3?iea_~Ue1Y?K%b)NzXyInI;8KB#zKO z2C7EN@s_GI$KVcbp{+5W2k&QE5__BzIox?2Hk$dwz|npZUH^>+5i*dJ&6=MI0U3Pj zZKrNL&?{XcGzTx1(XE%L3t6wH-I}m!Pm;w(`FvuT6R{OkGCH3`Tu7H(AwUwcA7gaN zmcHTPmGJ0fb2WPUd_~OMuG`BD^VSa&Q!{5J$RzE%u=^WJ6SjW_47@lj|N!Q8z;lVix7y2r9;=_mHYRowbslieRe<$WfP z6~uBGd;YW(GK~xVM1q&akH0x#7-gfuY)^XeIW(q{?~!F<2sT@*O|Hl*try zu9qt|u%Xz!dKOmM#?zxW@9c9Y@OvRh&@~qY<{mCgT4%555yk^I%gQP32BA=~9>`$`FjmEz$^xf_=Fu}k%+QU9ATezc#7w^<{w-+}zN%sq zO7ba$Xk{>x-N|;?_Gl}7E=Ju|4j6@GUX)kRp1hC5u%YkUi-ND!h;rg3M%z7JTtCx$ z=yvGgqwPT^**#9l!!)JvjSGfNEmqciuCeupCXEqP264qNtp@yMdLpg6)O>`K%lkfd z4z2-qqpcIygs27bOrw%&s-h(mqR_tO6WIK!_fg~pZT2AjCE+}$&z2Z|R?*2v zEwyA!1v`1uZp*k&T(%lyGwwiQzhYCNDhj8SpuYgkNT=H0G6_wdK9{8>(5jv_J(JH~ zxM-&w^jR-a(hjkrr%}-z$D&LEG zuj%MSLDDEPMqK&!Q*2g!neF7TB?q`X$Mu|^H4qWAB*@15OD*{O zpMPUgJ(hP|v7dNPhBRIL%roAs<ojnv%t#onTIY4vE+HRkG@fXR7xOXkW17dU1@sdPB_=KWyu7k{Rz34ab5jctQK% zPl~=qKRg9@*ir3&spRFTXyG4|W`ST0ezHx8Rxj{&(wd~ov{IJEg+}5N56h_+kxaLU z2*+O1Nejbuf%P^xbqi_%#H3d4_gz=UPkd0?%T2Ig?r+XWCxqGCpEw~xe77<}3P94l`n^^Jd0 zn9vqd%Y6`V&$jzoHvH$e&+k*Eq5(%sOFH6znCM#A^%Q}t85 z+VywIq$qp`!q&~zI9y*W%Jg!PWCfrBOaX`qIt>}n3Rg^03_yi~;v_^3tjNzDTy^DO zj2lhVSP#LG=0)8!Ttjyv;`zLfG{R~8=gvqegc9}D12~@F{7%hq^3;r{po~&5wA2p= z=wjEPZuv0FDtQ!gLN%kP9es5r$G6+K)OETw@AU;C{y8UZ2AT7gJsF_T=woLKEgf_7uYcb zvtS&RS;SVdW1dEY7xK!(V6TTNUT(O%7T_AuOjcy0{>lI4Hjhz1SQiv|h z4pRQ%+L~sp`;L(N3Mf4GG2xK*PA=dowiqKYxo>=+T;td!Cngth{P}%8?}}(E-os-Y zH;v80!gZf@9WP%ZBKm9eFIksD$c730m18)_G=!pmaxO*`?NallUEzKyQ=Xz)-R3)O zCb$v}*I;x@$N^+r|HNQEZVmvD8(wokhYsz&K}*k-EOO?UYx#yT1 z5|T2{&TQdc^A5eqeBVyrG972kHd-H^?fv`3qYr@$S_bRIRc@2xaavjh#Klg7+1w_MZ!6f1?|9}TXiM@Ry#N=Y2_f@U<^)M!EXPE zXGj+RCh!p-vP;U1l2h-Cn>bNL;Ykd9`ndl_;n)V|4)}U4Rn=5P#Ibe!Q4VE9>utn@ zU)=}@7rzG$9b4^K%VoZgh8yPPdN1Y`!y?UhYl-He!_1nkcEGnT# zB($6Fm5Y!HC5=wIt_GnIT34d>Scyvyn@kyvh(Zcp{Gt3{Bh|_Lst-Su>*3Eqe(XD> zJ9A(z#+U5;u?e~wHuX#CHs}bmVnI7OQB1?1T;&qvqtX1i7qE@4hbpIMy-3{3$A|+M zYU7QTgHHkSx8Y_zmr|Jx6H=CZ(_FeER=KtQ{+kZ~Epixzw z9s&M#dZbu0O7xmMcvobr!rNz@R28_jN;YM@}8)g{;>;tt{@Qut^NiY)-A3pk-c}G~gB^W0j%+;efB^;%ZoH z!WDR(7-LIG%xGIq2qT?90ZIiv2p5pF=?4+_J4iDf!rYkKzF}6YB3k;Digl^w({Peq zKm{HPgyqH+{86<7BXKriON>OEE*c+q+uYNs0XR*O+Ja|n1N~FwK^&9eD3K9-4V1pW zlaN8aPCoK09FDDf(=_N~h?GkBg>$qrWu}hiqMiNhM#`}PZ7coZ2m4j6S#-elqDm%|Cw$bjLj$mhLlI~pGL z$Vg#IQmjbm;Z!TtBVrZ3GSnp0*mapNw~QU&pd)Me+4D8n5;Vr{ho^&OSD1#8@0r=k5c)ia;?7U_j^@#u%)J9uysVv*`gl=kRJ z;<)-Z({Ki}P&D>BBte7#G}blJC!%(&O79G}_f#~fT~Cj$I|AB8GGu>tJfziYrKhzU zMZU7=><;YD2~3qF1wH`+}>3LI#UR#SZ_UZtshK{PddrXhmqv0*E*a(YgsNNfnWzE zthh#huyhT&A8;Lo3Yugr5@uE68PYvJDQbua`G48w`2Wp0D*xj|mOr}B6Jw&Eh8p}V zWo&i6GfbzKiv%KTa{e!Wq7VPaFIcj1ipM$Spf1p_r(cl>`6mlh4xhQiig*QQ$*%D2 z3|VL(u-LGnh~!qQid_n2jTA3UJ#L~>(SD({^;CE5rp6=8P*jGKnl9)6H$Rxpz|*^X ziOPgD#37$Z4nJ{I>kC31;e+{6v@F6!9|((miT_wUvKb>MhFnF-eVobj(CjEt8?=4k znaLk_QJ=%I_o&pyr$H%!x`d}_0=qKyCVv6Ak!+BLj>0)eX`Xwp9$?No{3?&iAzK6< zS7&V0`xij6i9S}4!o=uOqsnkR?$C3#^tEo@c9{@6Wa0tIynn<=koQt`%<@|}5?4w* z4`?8QLI)$B7K$OEf~Y#9RxUHaz?a5vnn~Q039HxV3jd3}w~lJ_+t!6c2oO93*Ftc2 zuLKVX?ry~?S{&Nq?k^X+}^z32S%-8;q| zBV(+Lyzla?x#pT{KF|DF>k`r)F#R+F``hMEZjG77hW>eDvNR(V);T-B!52G)wTtuc zRZ|>Sn)~}!-a^loDrAqby!3u@S8?%X{Y)W~4Tkw^xuvd@egr^Bp^Ick(W#OxKt8sj zk-2Z$_gcW4ZKnD8x8w{;nT|2J=Y(=-P#OigixG6PAr=ibz4S&20odp1J$T#?Ed#w8 zr6%!4p`bJ`Iw@W_fAkZbs2ujr%(f)6R&31uu<~S;qMhUA9j$W}xnt{e@Blmuz=IKV zmx-BlUO!uf9Q5e<4InqAg02Iyi3Vsdp)PCT;P?WvHE)AUBCnX&=^sbgEVen^BwP|Hd(tjGGL1nnzdzIh) z>iQnqkV=(?<;|~8F2giV@YZ&$30FtpT6s%iCIUMNYr5bK(H>c$o=%oWtTrX)@9uj?33{5u&!Dm4-zPy{B}C@#nvY^`NP-!3Ot9=&G}- z>FX~R*jvA{>Ry6@Kb&vpb``QnJvO~W9NdPc44Pa(>+{NC2Ipm#OKbHve_iBZKQVQq zcIcX-vM?^>^{J%N#0yYiinMyv-L%p{k}5dBG-X*yNC5A@&CY!A`UcHhe24kKDtqi8 zO)6o~rDF9v!38j^_Vcj=H~tXTT)z-57VAS?&GJbXABQhDhiE^OXR)fA-N=<*d`GVf?cQYa#Y7IpD%gcFC%`xo0t1n)t zJoA=CK7pz(N0l%ka#>SvKBJv;KKX)cf{Vu;$M2nBz;Nf`=5SQP1;me;-)2O3+8r%B~=sgHAhhc<;EuxR7{(p+Th~s>vQhbNA{;+A+ zyvA|2BAPU=G+0;HaJH3r<)Jxh9`?<9K$9eQquYTG7NMvWb?pWF-o~OpvQ{)NApdK2yC=A&FEn zjdutNcPrA<^hR8@TaA>&y1zQ}^ts*lts1iz{7?6l1Xjg>yBhR$lrL?o%CxU3!oyVR z>VmlOTdK>#tDv`X#F0pR6>PDm=QN~hays#v2jwTiFKmF4Cg2EqRzvnGK>kL3*tmgj z+QY*aQ}!$2fKLVArIfahfM-GEPa*MF8c{G9B9o;5Asd2&ZSr|iY{A-$Y>F3@hVA{U zRkTs;CF*Xwqg?StJjjni@*Mg-&)VN!NiXqTs* z^~WSHzQAkfh~&oqwU}NYbuk%u9}Rxm33MC8P;d~}2E4!g4Om65o?JGkVAAtnzur8~ zasCBa%=ir;RdZ-RQPY2W4UhvTcq<1*`~XivL&Kn$&P+VH*ZHsEX(K*TEosS7)q?az znzw&E>(}m69FKN%-~GEXpy+FeB|go;Y^%0JNIliSYlpm*rO?V(e^nlkq7;|3`#B5k za0U|He*10~-3Ze3<2w*!Fe!0}Lx#6|zh@0~~7(V2T9x^dHu>TeAp~1{fb`l%|L!jH40i_j!swF>!Szs@MlX@G&uEKJN@t znW>Jukh!X}6}H4@y4{0-0303h$(%-8I4tef(gQcI&;kzb?FF-R&E5Xak`_bNBegfW@`e4DI_U9eFUQ^SM z#u&x$TC(k=Wd_K*aM?I%HV%Vm_za~4H~qKo?kzR;3tN+`ig$tx7JXC0o~3{Bq`o>r z3++iqKN!`P7tHV1>~q{>)W#JeRSD#QA&%EtO*E8I6l}eZ^F9X+8Tso(`TtFf zO`m#c?iVmSG9(G%^G3vfsvV+JEYz`axn4OYFw@6g@fXs&e~*(8?x35uM*{)_=D;7y z|I^}T4V$(;Nj>lk3?iQj6&im`{zlgY^J|(*nci_cvjV}kuS@*Ns3YqHlk8B54Y%~1 z2pED)G8l`fop@Z0kd~MDt=G ztyQ&+XFOV7H2tsN=Uhs*mNDqDeglZoM>F1OR+Co#`TaLw3`ZI$%=w(N$W*R?bN4sE z9j(J{W9A4HXIYAA-=uY;qc+-m=Al>R`mootoV^>-`AetjgGK$Ny832QbK9;rlLRZj z0qvt`YUVqz8wo%FB1)m8S-)y^js53*JY9No_oJDP_TxX^A@D)7uimb{`>V)EXvPGm z-ujk`s{D*1Tl8}P8pnc2h9y4j%)bws5&jKuO+^#F+^%?~CE28F6o?^jBi=SFUeeqR zn16J-A#_nrR83iO^mr(-iNEQ!fzmDcs4S%R>Yv`wv&P#Ceo`&|Xrsvs-Ldt7Dob=c zkW-I8+==MelYeWq$7gC%YJSGTr>t}kh!swK??5CGorK%aw2+}DtG?%5yY?T(*x0`) zL4S#N?a`YYgfa0V$vGWI;j`S8b>e%2NZO#s81 z>u=xusqXJHa5D8x3T+ANBVy&xGOC>(p^nMz4jT~o1#ESkuhy%j`1Ivzq7Oomy2F=rv_bd`1o{Oe9R&++)4^{9U8-$(fu)zJn0p7fkg z#j)mEagUOJQ0$9OTYnv=BO;a2(~FMWN%Utr?r7-$RPakg>R;QoQ8@Fbx@3B5CDiJ# zLNJ=ThN#E?Vt=vTtjAr0-T-6X4NG%In9mogMAGyE2}kqvYr{MA0k*;N?9AXeWr~u_ z^_9Pn416XTiexAZ7B$RfWBgSad1zGhMEE^UKUbqYZD`PW{S^axi+Oa>1prlbh&$>Y z93w}Q*dX;aJo+P8&;~$YgHRf7P&s_OQAyx42{t?J%+t_~zbh#9Qn!2j?Ea>F!d@|^ zFOW;U%9p{U?3g*a9931F`rIe)EGLo^VV+)weX^!sLkhfpARe^wZ4CykD06KuP^P&0 z$Ie7SF}nMtopk$wu31d2I=r~IZ_%o2xNJ86SaNg5IjA2HWPqujdHx$vT69gQYJg_f ztjqKdl%E)#R%?O!>wE`BSt%91Kr|iHL=n(-X-QdwQ-#ikC74cCjA(&#G%FX*&rQIu zDa|bWvzmhLR?#c_jkCrUQLf(#IMH+eJ0+nl{{z$PXU{n_Q%2pFicQoCgH<4pW|%bY z0WXGCLe*d(N`9kg^F3`ysp=okzj;PG_Tbj*eg68?kQ`|VmMS_iMcs?)z&{EwvH z|MAJ5d7z;k=_c3p`l_Zh((AfF2fsGdJL*dsq|D|+v}J~zbnO2^DgR6={vXT#|NqIZ zMT!MTw-ENC`v1HK1rD)Z!4~H+ zy{@J5_z!BzdXn?<@S4YJYAO}@FVSY4owyPFWA0AfAfKZ_f|9wPRqP0*;?o8IJFlCjiwebNj&h0zB^Hbl zL0>RfF0TK$%lxAvNjKYXgedJE+avQMy8Po)#U$|t+%CVgXgH)lnzWx_0%YmpNabx` zC|ZrTpF*HMu&F%tc9JRBrhwXv_dJq-UDkSej#g%iq!<8tArZEX*)hpmuOp}1$%0i% zwhMNt@vX7uLclC zk}FD*RUAiw_&%q6@3@Yd`;v+hP{^?ZCmUJ-&mtRW!7pEhv6{csG8j@=5UElpTDrV~ zdFu}b{4_XG-X-pSaeq{?LgsOk3E~tJ6vlp+rXQMt_9b*g2t6cu_Hn_qA7;adGR1-f z`D*YB83wZXA7p}5*;Gj?M)86Sn>Ezlp5UO35N7%q2Frd$v1=kf0Q6dEq(CR3dZM*w zZd93uwZ6W=aISTZS;jJH=A9`2x}LCEd;ky&1R&Y;c?L{5lEnq{b<{TC)$jo`OsTqAE;5)|b~BhR?BNRF31ZBYVS z$6mk(D$;NR-&0|S@zpAe0<7BA#lBW0w35rIyi9Q@0kcj8tr|&o88*IbE)v1-7rDA( zndz=kljw#<+tvkx1pxG+L!njKtr)hfz7a*0db;Tzb^1T9BQ8~o6})WkgfK9mBrHlW zktZ|T+Q1L(Su-Am1(j==kZ~DVMHM=KIt~x{Ri#SfmmJ}fX&j89HmYD^dzmWTG9k9w zSb{=P{eY~rj}H+^r=NDAp7729;7h&4A3#1If5milrk`_X_iF!d@_*zI@b_3>y@-pJ zS!vGyQn^$KR6c+x(gwvR5BI|1n8_^Xj^M#)l(Fp1)JPNNWWhbDx0Pyz-M^?j9Vv-> zeC&aJ+AJ);ynIeRK6zANEc;b(m7n#URlPG&_O~GtT5Re-tWtI^bG>K?b_jjAD)RNi ztz9Z+3u3wT6rS8p$T%p&@{alswDa!>&wrb|!27$-^q(eg!~X^l{kPfw`tdW%f6Ux5 zfR+;$MX;!mY*Jk1RhiV~Zze`o74jq`9cYWjBi7Vr9XhXOrz@tt2^P8|5^*k^U?=D829`MtO;ND2G?lZ$OMtz}sQG63Y_)C*=y6 z2Sb57>_xfaSw?epkwdSFNUeKIPzOX^Z7PFd*799-P8N4D?T<*_C+jCKVZu#ghJI>M znx_8-Y{umupOGHQb@m(cPA%$r35d2QY_J@b)8S~#0{wCNQL>aDf`>ml1|iNprm-Wx zY2^nK*T2+tD!ygh$7yDq`NWD)o3yU!+MtN8#2{L&p+{h?Jla%27b;OvVD!wwKwGXz z%blE#;8Sg+Z?*b^32I{zg$u2i72a58>Uq4kq-e_Ku~0&L4W5RqCFpEH2nL%0EL31* z^_D<%E+j+lqB)|ql3y!`uXEScNjAIpCWINsz3bI1LmNX!#MVW0=}Iv$)0>)C#tAwG%H)W9QmbJ8V^EUQju(COYVptn)Cel*_`Vb0I z9H2bO87aafq!idvs9J3817A#4znvfi%IpmaaQ!%4-xkTr(Vl+(@m0S}%EK}=1yfYK z)A%7S?S%Nq_$ie;F2$K@1iR5&G`8?%3y`rtu$MQxQ5eJvfEDb;eDj5LQp`T$gGL-^ zew@CV>n9b#ml$>Cm`Tii=!Om2i zMv)?x>#)JY(4DDgI=whnUOvwHyF30V3IjyPgk)Vx{I)(VmEV*x6s%Pp(jWw4w468t zm&Emem-Vj0QRf&DSDct+&Z2bognQyBA%t<{@SB<&ZAa{#3`?Qm;nbYtI{o$`eH=e; zj>ZQZ-mRmZTRTLLzdrML@SJVlym9-R-(}A^v;2qqsKl&;I~f~wi=QXBW0%*uU+NZY zTc-%dQ9F*Jdb~}AK$-TlUubI{g11tJnI_gGuT@;pDf)>it5IVF^u%G0AG_J~6_^`q zp|8g#nu2AiKLzEOPLCY1mKQpL%NmDL6cfPG)nHv({~_ zk|r8GwfF$!mBA#n?DK^|`9g@e03`Tzyqy5w%q6v|Z+^Ko&RCcXgfR+(1uJ=)109cX z>a~I(EC8nIuc-~wop`cwB=WN9(_!0w-@!dI3`w)k09nqXwjS^DLgaxsix*W5HsLrj zpYHoOgVmC5XtBnpBjI<#1v@krCCUalbyRe&OG}|5rJ4RCY!D@P7JK#1e<9YWh}1SDkVWdbvwi=le`OvzMo934xJdgnJ;b0&(J#ebw=`|8%rk z>Yk`;nQ!^r0q081DjxZdxerBkH5~bBRG3kpAmTpU7O(r53#f&H zOm*QK)Hehgs;-(r*CZJa2J~jV5UIZYscdf`YFrP)nzuW1+7a z;@;{OG51@KIhrv&i|1EPvrzWem=aiymYSgb#Vj=h(QX=k9Rr?={Hdn=O?WoC(JMIo zBmE&;@9| zg;2wCMuC8Kx$WY;VlZ8}YlAi_%$}yTr0h_4$J0LLv@_7~k(6CTS1>cCfdn~&PDofk zt$qyi0nLx}U2I3ZBt-qt5AL3fyy7{Jx0$a7A5bcsvbfAtD`5d5-aFth=~r zA>aZ1yC5o=hYe!i)+-dV$&k5lzB!=K%c_~AmqvBlB&A(Edm$Mn#^KWx6u%N$$qahL zaDF-izt|j5>J{UU5(`btg$vlcCTfZe3DT?1^qw+7_}b1}mx@WH3OHmU{cI97)JL4E z8O9)ir|ZGR5#QaDUm;=dU7GT!lni4+wHF)b9?#^jqlE;(lveyTsq#-?KBvB&UW%+I z>Rd5dBPyGgJrlpPjmwTDjUt81!7+7&vzgQ)tq+mXNKThhndh`WUD2RsSwwTTNqAK? z)v4#vL%nq%v zSKrw-o5WN??P8DHI@Z-HtA-m-p+;v8<&q5$W&W9=DX#jTaJX|w{bF!_18SDFK-eae z%0n|0%$y%)?pj?b0sYT#m;laGf+_eqV7$<%hM>Y^lvHVAt=#}=s!kIGEK*_x#O;h% zh3bsIG4+a*C83!V`(!mO1&~D%eGwtYc*8p$=_^+MtNYiHlsV1xibo_HJTHF*Q4xak z4h}FVP!YxwScvsiXAYyqM9GA;4biD!6h7tz!{_4S`y&l6tG`sre-{>U;~qp9@TPt9 zXWrwQ*bzY;Km^`7X@8GaZ6NEgSS_70M$pjJGQOJ-bt+PE7A3{)%_}=mWnS=z!%k*} z8LFw+PNXcl=-At6WL#3E(29H;$NpHY+VlxJQ>|o8R;}+WSo&XVHBQ4bU(j}dZ)zZn z)#(k6p&w&OHaS3sMFx+=*g-M|W9y>el>6N%Hak5QfmZC%aVYIkS%U7(3ri+@hgZOf z=Y1Ci7Mzl1YtZNA7y;i#2Bs@aqCUV0y9+iATV&l3KDzf4n4c@YDi+<6joPS*+|jWY^`tSz#AK;DB4O6$E#dE;C`Aghm%=(>KZ&uXs&HwP7S1&p3?I7% zLt~j0?~5$%U?AD7XH_{&crM-B=-=ajYhtHL-|@0oao$fG*)-t+C|gG-;j@S;C)gfvxtrTF7#MwkZ0i8d07%}NO5d)Ud)`XC%{ zTi)68$Vu|y(CYgFOu%LZ%=1uYaJpqEZwxGKzGd8nHNl=V3{MG-pvVU?9c5<&Cx${k zz-pxU4wY=g&LlkKEL8iSXr*9q^;zWMu_}yRX&;s($?Ei00-S4HrkdXn5`>u`gvF$e zz9!f0Yx8*)*$k;D?yEwLQ|@ot1)Y5PuQi%4L+VZHOIqUsFo`K_*>BopW4ojE5pZRi z5ZPCw@!92O`W+IN*$wg=5N()EU4(0xMJ*m&4RQjQ)-nUOp%i^W=E!S0K}^{K4T*}x zo=imP3*;fWgk1&wf<8yi@Oq`9xrw3w)2PAC@j>njbAkGXKAzC@5MkM1YZ(2=Ql+-U zrGd<7>sc@Pp=0X~zDtT*;h6jf<+cHPpIYb6I)>sizo2+?gR)N#U@XfXHpYkI@rgJd z)RwgK$7lT6lE7katNPYF=QmsI+WAgwAf-ZF@8F)`uSCXFLRB*_FVn=C;6pB4G15*R zJP8(T>|WvGef|ospY1*1;w}teq~A=I9pTav=BD7Aj0v%Jq7MI{5l}%vKrf5iv5;Cc ze=UXGh777coi81H1O{!3`5aciJdRT-Aybz&Z(2X?4I9(uC+fihZyA=2hp4=Q^wzB> z1<0H0Zq5G+SdD-VW=!rDxE^&aq-$ApulAWSpXsc0X0X}FDej<>R3)8{b=rDg&8(|^ zOY{<(Bb}2L)@q9vzmkyI-6Q-39JqdiR+r82ufTWy9#ksAdh^>wgGOdQ-B!rLPL3s? zVmcbqm*ShRLZ5%eVOcAU8Q&TDA&SAi1mQQJt?WHCm*0jg$swHdcXIef96$ncDR1=$ z$Vaa<8H3`#P@SyqB?3BJMhiTa5v*9*vh1>pvpA`k_N zx5(Z!wFlDe+eJ;%XgzYL_!8ge*-XY@OwBxcEw`Vm; z%7}pt*5_@q@u|9q6!Uj-Y8e;QTbJi>aDIX}GhF}`)CSTm5lr@ZB5_^kTF3~ZYZsZv z5I3q;1V71IEk>D*u27|qVyD>}o3OVkEV#w&L4=QuM(=UzbL8npDt_$Tb=ABl$I$bb z)#bgc4e;jzUl})kD|=;)SR_0k%|fX$D+0~rsHQu{ceqAZ;Gs^>Q+LQ{^Tn}sDz>wb zdO}sm8aXDB|Ctof6JBDc1|)BaNUB%`hszLca`a^Z&V2pRI-Ol;!C;SNx3j2Zg50?I zGqrLfsKEf##6KQM6$Mb0dZnxE%Y}mIWBNH@r{RJS5PAy;S)&3aPt~r;IW-44TOZp} zQgDd1wV>^2YF}*HQEC1#N?nGd)1Mq-_hptKehsP#>7R1J#<1S=od8}^BlFQ$8FH6r;dtDCs35M#ykA%CnfK0xN)~b<|4r`P;a7qvolk z!Y;{ViIwM*)EqO>U6}(~@yn6#ydY<~@MJJ;c`zMT9j?jUo<5sNR66#%Op!$Jz{BnK z1$posAbNx}#j?1x(fX4eDfMf%WcV^a!+>;Cg@w=PTUL!OEh;j(DN$TlEMG*o9LoMF znj1=B9(&L1Vc$h1gWW59N6e4dqGATA1^5{K7{37oysKfKI#u)>sG|AZod-TUp#$3s zR8ga>FCSM7I3o4*3>eRdXbhD{K0GXxn!$DL?|1VmQ;R949J#Ifev&$D5855#l4%oY zc!!5k*e~-Ws9eW@$8&EcjEp6F2g=O(A{KoIX{SF@P$;M513s2Ja=XW*g&Y1ceLdal zPG3SSc!XoAFj>MP9n*@oR6bS=#azyy+ym(Ybl?)TPWqg5ykxnwTIe%Apy=5oE6wD{ zKgij-saOw_)=kva-2|CLWm!w;$t#4JGS(OlUbGsEWSu$3vg%oeX&HL*q2ntsnECp7 zT*Iu%{5VbenvH=c-)r-kMI2Bd87Z>Y6xEmPZp=O|mO4cnu zY34R-?vn@LV_^5fH&>J!Yq=LN$5ISGND-a`=+G~y6lGW^aBfv#KmbobM3R&}A0mcx zTE{MDUf|Up4l`mtBiC2rfM*@Q5^pu)B~Ty{ywR+E^R&0^`X$L!d+Z%G|D6MQEDnbS zZu#9|@{@|ztj_k(Xu>%UOPHAvEMY=4uN8kiwNyYTnkXFcwc&*NKnoa^a^l}WUXw!^ zLcDu4M(UW}1Q_=VEjb@FA{iNPtf9Y|@#wLWsIqHcsOgq8f;!FpFwh^kLw#=`y2<@! z3{26?Fho677VPAvVB>)@$0E{sjYcJVxyZUlzp5IF%j8B0HD#I!q1X8$CC{-+Yx4Kc zyrBLXx|K4maK9t+fzLr7LocWO`!rj80N=HXgN^-o1_6tneENo?g9wshpv9iU$_DNF zIv9UNSaqtS;{okJf}ls=A}eok^j6e0Ht<#!y+L z#X@y-5f}`I5wO1Jf8Q&8hIf)>XsgB`s{xU~3)5+JV)+WF(E84vCu+Tl z?ZP-VX6ie-8v-=1)BM=ZpxxE!z5LdJ*|=j$E93;X>KU1PI|n|hNtZY?q7({O)}tc( zk-B~#Gem0ghbNEQjkCl$MVcbzioTLT7wo^ zCG^5&y-r+viH#2D65P=(68&b|v32Rzy4L4nx^8oLbB_I-K%U`*1I9>) zr8`C{G4{oU(AV$pRA^t@~OmJx*mjB30u) z!Saf%MN@1HX;+M%;q`_rvvlOq0dSt?0`i*m2Csv?{q)0i_I(WzfrCwcas~L!6P(g? zeG)tA#Haq58?%7I&V~2;^3^8LK1+X#3!cGTDkuO2;lEWb(uwG{Ojhi>5GW}zw zvsz5W$4P99W><6T9E-Ohzv=)yGfR)>Fs}0BvMYY(gcuUBe4%|L644T3x%1{bb3yjH zpCzMLBndYD>2E-bWq7RM{rmPqpOZv=i;gjk`qA#}?;u=bF%9;>)+{HC0=*~b2qd*+ z;m(N^a%0`trtJNF)cszi4jOM}48SGWr6p=fnrgb-tM+Yy)Z#?F;U;98;|#n0*@1yo zFH$Tm2L-^%FSJYMCv`v)!wL`ohWh$mV1UY(vu`14VUGem3C3Oe!d|CTkH5BBEFt5m zNjTJ!(?{6Y=3H|*Lp7FnyTLQ^{(=&mM!{nf(JfUNHuzNy(c$0NT&wlb`autuE*yej-h(weD<8hZ!9nN!ANf zxK&Hl7uA4#p(p#9Zm4TgyZAoXlFyH@Xi91-pOK^q#BLXt-^tJ&SnlO<*h(+kY@9Lt zz(FqJ>DHQ0-{$w_s?jI@_Xa8zlMhXXU9qtdb3G2ACOYLIvF8qi4xoX_XFEzV!o6qx z@O>f}0p-STz$Z5wjsn+9)gKM2R*^?x{4L1dYzFj({6`}^`Fwobdc#k<6RP=@&OfCo zvd9T*Al72TWE~X)Ri>ItnilhTL63GVde>6|&{S?%J!XR5oFtqoT-LiY<6@`B#cime&SS(&Py^JHy{R?an9J>t=L0?><7Fm}B3 z_shq1+q$VvJKAvC>FX9I=M6g(oHva1tVc~he6Md=hbaop!qedV#A?iFJ)fKugWdN; z%HzZjiLH^d@(oF8EQ-moU8Y4&%btZ-kRUC0bIO{NGy*nV$2W`!U# zl%ZIS%S_>AB?m1YP3u_y%J=x4V3-HP$W>axkfP#du^C zgy!zqw4dGXOwRP~?iT>6>vwn&Gtq%aMaFpLE!pnn;VC~C!}g$&YnTejB5n{=w2a=c zmjA@@E9Y^bc*SeofRE%=pGo3D9)|-qIpyk_vyNi#E~U8|;6KWA@6(1VQ4~>+!zQk{ z0R8v;%4OA1L!1{~CtJ9-GA2SQnoRer4G%~KX&3U%W*xrQ#C6ASIrVtU`HTaB0#r*P zBR+~rY?dx2{JbUhg=%;AGH1F(!x1rPP0so8$mZ~7{!MPs!hsbcPk(h1t^=Bh+!EL; zf-=-Q*2v&ulMzjFGeAMLVu?v1w8F_Ik$ewrk2~yW( z)_Q^t<`ZWLfQ5LJg$!XZkPv<%F|J3%CifLz$nh~m*14iU z1lNK3d=!~v8%-&|hV%0SvWL6o0ELg^Ywp;4`tuhFZm0vl;a?)>QYj>ijaphsps-B> zs;-s}8@4U+W}Ymg&%=YQ>XVh~33Sx3XbEFvo30;C?GLG&B$`2l(qjml1S$jjINfw9 z2RfA=CrQ^gTR6#9s#H~Xt=ii|7;1FPcB4ZyM*$*8f-J%{7r+8uV6scS%0`1xVcCmN zK^{643osu!Z%l%`OU1R-wsaMwIW4z1CbeOqz2j|7kQc}EbOTQnHoj!k?HdgYF2|!} zt5j|3wVqUNUmcix0CS%#DM4Owmc}PKT=sHg^5bSLX_B2;qW9q>F4Zww)l?>WP)_Qg ziMkUXd#}HwLn6r z>tLYx&CTKS@u43DbG|w(Fy95tB-1WZ^*?mte5ymp2y(p5GCiH^!382HrS=1 zVzaanL+Mo)u%GgE#)G|VZ~d`$B5er;HLHl;6Xfz%qI?q@v<%AHeP_u@ zqKC@QzAGmGjC%iAbMVXDB;Rx^a;`%wX1g4abGu8KL!Tuws8}H_A%rF`>mZjCQwRdomDV#_dq@L|&9J`2YcWX_5P5BYFLZ9%Bb}fh zi-IIO%gEy!zD@uGUrPotbw{-ro) zG`R>zRKE~wvM9IYqj2jU+HGc|w|8wE2c?6mS6Z7Y?xHnB*5S68x?`*Qeb4LbpPhj~ ztT}!%5AngdIeUvY7Z&Uu_1^3q5z{Qha+<_V>HXW4`!Rn;PkWm?LLt&SEHB#8)n4*8 z!yU^W<3M9IkZ^5YoQvz}lT5ETe6p|_Mc3Ve;FkMrPA80F3nK9T7|XXNoxP1F8W zWYJlIM59_uQ}z?n&o~g8xKX%f+m5tF2}kAM!6lIDw|tNb4EzeL9VTYkqFav|`Cs>S zR>GSTI2hGhV1`VxI$LZn+KAeitiW8~Rt21n{Zs>9V&ZnOG}V*^EPqyUR9s1GGX0jZ zAXdmhK>M{6Y?%Iy3ZeGRd((`3eMF?SpoJWS<6cgRPfNHK<>QhYyaO0)@odYm`|3`O7OuA26!(zk(*Ts2&T zUDSi=0za=vk%Ej`%}UG>>Erf{?A=1LK|K^mC()70WMZXB{o`+xm!>32A!|ko9@b2y zy1KgQF4gJ2p(>_ihRPLNmL%Ba{&QHu{qFdpdf!0o%Dv?dUTl@8Nevpw@4H^RBZ*F$ zl|3|(s)HA{K^4Ezm~$J3gJ#q8FpN=~3`4uPo@yr#gdt&DUExnR)F#E@fB+T-41!|c zGwY(A;*b2yq*cr%l^$|ZPQ&p6fnZ1p5n4)_lAWkW^vn97+9A(mDm6$eg|uBmge$?@ zKG7JdVNn?*T}_jKeJLTxh^8xdKa@4zZOpPX2Aeg9nEfktEl0|*e_*NGNW;-oY9p`e zAzc%r2sW7)$5}t|r#4KAk?4CPUC_zEQ{hk@UuO zBPOGB1~(@>$<>&!tAfGW8R&{K-)VI&R%p5Z3EC)Q6G3ekMbuo(#2T-4Mh3UufU$%f z#gX(&CTRCFH<7LNS{Lg|+XA$uA>*EzMicE7{$r(ahs%sUG|b^?!v2h_kI2kP1GL*yLr4s*2oxM%9=@I zt3%V0RT;w{rRSms_@nKmUb16(;7q!$2Fb9A!x*ie<2A`4in6ybHEMI{3r;~iwIv(hPT0GbNaU~UJsJhl^nvOf zepf}2N(H934sqx*IbQN3vRaEucqT6QCT%Xe?A$WDv`W(h33UaR$c0udrLkpitjr06 z`%rF|+ISeiIe$A$`~HFjm8@66_fGlHM(_uJvq+uoZE|a>wYen)#V!eXN70Utgg z4!}xm){&lFGxNJ3+O#fe_0mPV(yn^^27sCh;o7sshSDwTA6>sgcnG=#vY`>F4Ob-W z-*qvXp|54nMCiVuvG6kdoF$j?9|n^5ENw{oo0OGF1n&C4TYNkK0Oq=~KY3MbY4b*c zlS#FouBpw7&HLzB8UcUVy4r#@u=D_9U0Nx(6o}NeZg&tg+7TYN#?++y(N5ri)cN^@ zrYipIS~8j-xh0%JSz6K$J2;57TISa9Vx`_^?q{}0@xNTu>R6~WYPf>ZW1?J-Y!G}PynCdbqhf)m-PFPLgk+>e!C z8(qB9+W8WLg(r@kZDRe=Mae2&Fgo8=m>;E@6D=3w0S>0|jDb}r;cvKwuJYEB&#GGV zIs-)%TW~F~#f)O>3s^;5;+OkHeOdY7Eb^3;9PXl6#<7V9GQ&xgZp}f4hh$j%`@-4N?ly2hZ)nS> zV5&Ik7`Z3HuF3*j3qQivnx95DQFg(cm(?zv1dmh_3s5%SMeu?%^Blz5H%Ug58su$b z_3bdkY$<+LK}-6o)=dQje$1qftGrKQ3N&dMQixKGZ)NF}`FKJ%64QUrDZ-q|a{!mJ z-I&akuEzh&Bu&;MW}1+>kr{iv50xk*eDOwgKlh6&fiCnTGnX6o{qKy`@Lp33EM(Wf zs|Q-Xp$>#>Xt)(2VLUWbW8h}Bg%#P~KhQ8K&o<^InUU(gX{hNOCCAY?fuk@}*OL~p z*tGHxQ5m<+MBF53BJZs^A&fUNZcv#q=UXb_UdWPNL*TO6s&xsQni*B;TQ?*lMmui# z^J;t?SNxK4N2M_>rm4_Wxt68ZAI-!yT_l2s^nI*IOY;niSqyTlSM^YqwSiaKmh0H9 z!wZjscLwRM5Lm}w_=rNd1*ib?o)n;YUaZe^BVwb=t=oHCMxU!nlCVHw<$%qbD~7`G@(B#h2}a9bWYm`-|+;X-kmUjrw~yNtY$ zu%$#waZ3AE!R$MnQNX%H@mwX>s)U$r(Itj&2BoYRw>8DIK4p?UllaT8C!n@QcD-CP zeaGcq-ps!GorW9@Iwn>bUhjt#sx;!I9*4JKt1Og`6Z2^y_pyU}3xLfx^b%GETYwG% ztx-Vpb1hfnPP9<{BWgZA>;|H*lC5{DBiiF{X&{d5NZ@|Zi2gGhQjTZWQmTM5y8VN! z7nTyrKj+|CS1 z69+D-6fVQ%oD6MRHLwTTS{%0WM$DMaGwz=$tEi1jBk(0lzRDZ7lEL*O0B}!|-t_)w zJG57ofiNyMWq>CkGo0h6&h(tnV4o^s5-JQQX8ipa1Sy+w_BxU4WvaicbDBv!rh?ks zqdMu}%Jv|6ET9aqw?Pc6B6p9*LI#>UDxht&dzX=6`HNg!0Pq^$yCv1k>ioQ>rfd2t z{^Jw>jE^k5}M0H1G23}{wF#N%@X4lWQl&7y>aLnQ0Vn76Mx?$0^i?}>7%tgG3j zkFOfA$-_8pNaW%b+k)3cfFY+Lk0EpqWcJnJIC-3c6<@!ZHnr*{Yt7b6mLY+VS||UIb+Un%-k4Ap(9DO!5@&=pI;J#%y84@MN>Q3cI!- zf`tccsVpbbNzeGDh$B;Ssi#dFAQg$lW_b>$#i-QQKz3nLLbT>PsKpR*t&Etg8t4$`1xVavuICPSs>x6wXhe7p zIaf-jS6GzNX({rAsQ?IwQfRa&ZK|_bbhpnBF{DSR|B^$SniK!#T{t7PsYFXP+J>hO zuHT^7BvdF4o-E%GoplsW(DU3(8zqfM!qv&ns649tdc!mQ*b!JZXjcx|oh)?7#t8pL zE2{1|6Z5#2ITwiiz0a1$wa{%w=6OPhjtmZU!*D1`$-`RCd^QDx4y!LmwNf6RhSSxQ zd%!@zhTlWA-~vP(#pBr^hMX)5sy*#=k7^aZB3x(g*3>WOE-n3+8cs>UJTnjFY`1|0 zcr_SaCK#I07^j{G9wIsV*||K76Kpr16FHYQ-l0vwtyU!LLbs$`2hVQyka}#cz@n^y zeE_bHpfoi5UUbG&3Lia&H(Vk;cz_3x;fBV+pEwKe&agacTc(?vK9o#ez_VZDH#Un~ zNV1hhyi~cJ7YD@VkP|m}|1>Od@meoN{ktZ;CIP~Di#LFCnX7%pekMrve^HV@PmXM8R8yck)33M<0x5( zT%U75q%@f5;&W(#&UOhC(QQE@NhmBTp1d3S;578KwHX*JMuRrb{N$ zqkXmvWPS<10oZ)nuj5{RwfXy;zs05-ei1g_V!c~~h+^nwoOn`2RL3z`$cCnzclMdY%80@6Yipx9-c zmVvp;#myaB(rrOhaZ}s-p23!?G4l1{Hj1OB!T_KaWpj@rKf&b)A`>4`Wi+x(Z|rm3 zW|PA*zGc3PB8s<*-{W^&Jm@Bf>?<*SX6@#MKKe-XeOB(uE+*aj_=SbRp)Us{R@|F5p9#aP*A>1Ox|;8`Y5{$WqZF@&58 zDj&4hK(E#fc*MdbpM@_NyP1A+npEVifWsW8n2+JMX{;sa*EGqRBrl}Ffh7UdA1ewP zPs>6`FRuQN=eW(RL5r%Pw=rZd#;}GZ8Z#0=M@FFdk#yPtFDu(QIs1h8gg@10q1R=W z0tmvtf1-kPfI_lwr?>!By`ZXHat3lgIU@jW{i@PJVI&^0qyZAtZcu^CqRgV)**pC1 z?CZwpj4X#o2&1>tJ_C(NkH-VwA8LEspPY{078bD@i0Foz><d|~0qot%3nKaqI;WS8ze=Z8;fh^m}LJCdv6sNXP4{?cQ@|dIKdis z_dw$gjcb4a!QBG{cXxMp2qd_>1q<%3K>{HVdB4s(v**m&-#IsD-_Gr0zj|s_)v8tY zpJqd{J5JB!TBq=|9iHjEm4=WNbC~s5k?ay%t=Sn4DJ6zshH(V7?|4TzbqNr9VK~&7 zHsjTl#YfQvQF2tm`W@QP(U(XG{Kq_W4PU4$^PnL}_1Y?d;-Ya%2L%P=zsC(minA5l z-Po5D#NXq05P4!c+%iBcKPa}>5hy?v(SquPl3bqgZ)R}>Itm_UyjNH^#{QHAkd%El zw?drpBS8B#THR@sBZm4Rd`$y?&Bvmw#jh^tgP8!Q`5^b5Q33l%ygb+n>q8v-aNke) zKla@vz*b8yxgv-|*x7i+cHN?d?NoM}A zpM~b`_0Qk2%%M4BnwS>qP=@DC+6T8xo=ozaTcF2OM}KpYy#gfVcRY#~!=^C!feQxs z7E(t`oK>l2#C)wKS98Bg{b2@|?u8y{Q;A~hj9dMw4fU~Qd1FU0acx>hTKi69@UJQo zKuyc!Zh4xEk2wa?=*Zb$fKe9L-6I8%;h0GJvo$a3K3Mt~q*%|~oHNJ}eqFaLGFSbI z4Nvy9We)*fj_Vtx;SdWyk6o^594V$HY}Ls*Wp{rjNVA;$u$c=6016tAL5%&d6*CaU zR03TPO)L$jb zB{xe~_lk26hg9_h5fNaDI!wYuLTZ8@8KqNe?8&_nOiq-ppHsA#WznWNRHz<5XdW56 z=VOU0*+g$IRdFnWZNs3dS?tu!hJ_ov=tOFO3-wV z6I>Z0Gnb?;Hymf}+rM9r#}OWerecFJ^D&pa6IALTib}ou6zB?MHzFj#crDOs=~q$K z!;2*|FtQc~G4&kBbJj`i=q_4=IgJ$67TX;E#WA7mObz9DcdTx`(D!z$r|H~2G3@h= z$S(##GRk5|+|z~5XcO^=*_BU*;yhKM%}LdjjEZ*z4?+7ZI7}FaOfnmE|I=mNUymc+LjoQvIQy!^S%`GMFe)-DngfD*)-2 zM06;F5Z+dusZkECvRN4ofhy22vkQ1c4J4C<%SVo71BSZO@OFpt+MEDJh>J99ZMY|UIu|?WgG2? zWwV?s7w??t@e~kO*ic`aO(FYBH0|5A#5~ni8`e>gcx>;{Ud#mLU248P=?xK#qSPA0 zSAJ6@bTSHIz06U;z7wg$GGh1d*1w3xr015$*9_ZJ?osMPIAXf~0*Dbg!vkYB7@E1` ztv}Gpd3xL`E{v*1nYxQz>6hhaG~2>tHj~b+)0JvEj2a84`jwMtV-Iv%Rr#xp68b>` zI)JD#DSjHd9?6_#XMU&i;HA>!WJ`O1?t6B}LsY6?Zyte4g8j@d*Swj7(qt&-HB=CRgKv4zh*Yoi2} zHNPDEq|fVc4c8Mmx*1jFBR1Tjk>^8~=u)(qkx=NAlKpr~;E&@awVO_Emiv!q5(q9>>3 z+e*R5rTg&?K5a^@&=aW|-dz(c~OB}7-b0p%@fhG8|eER!92 zoa4|_F;C$xMOmib@pkg)#@+3byq)NWQgPJ8lhq8zBF5|u&@&a*55wjLn+?}6EH3TA zP^JXAq6M=7idFr7V>bSvLqrWgJ=_BmwH{wiIFW%GuA!UpSGoXQ?&_=2p`E5bc27Tk8N@31UNs|$VE|XMEBn)c7*@tOgnqEa4v50|M z>o+}XFIQ#!@{^rC!31>0H?t~eBNG;#=C8+vhrAV(Rci#24|8eHW`|L;%E>kFkyK1N zwAq^}+$0baKx&?{Z~6~A!qBYjx^$nzdkEZszS6Jqt6qWZmW#3XC#1`}FM8DV zz%-!v(R|ZVOT=bd^zdR4pd4fY*m|UL$_XrK-?^)PeJhw6PMx`5^9`*Y*YxLWrb+h3 zxeBWQrpxw0sG29Q61u`1q2lwWEo88n5@~si(fZlskTrFAS+LAyNm~3%5Hrs0i=^p86-4lTisVw>xD6 zW>uG>pcd5Qa#u^{$_{yFM}JclO&Z$3P;+}HRo(KOWSm3NKBxq42+QY>GpIY{2^WE) zcUJiQO34r@u(XylnG`F1i@8fbtZ?dN!fZ4idu<~7o@VX|X=ADFOED2HA`kn>70$Zm z_dNz@*h*)Zwj}QOM+|&Hv;#UL=z-ELlfj~T>BXzux{M=)PRbOm>#BiBt_f5(dfcHs zXI97{S#dw{YZW8Lj5uwHSXlur`uRB_fBbx{xH==7tnr+gjl!?o=2k`}8D*PnRkxB* z1|M8o9m*Y7+-A*Uy{Jz`AQ(`iS{CQGRKAj%$&g_R)p~Y;T^fp@f)jZxrGXYlJCQ(d zciOMcQx1$%GUQHW^)OJ4AS+O&C!ACrC zw>pfl7$`4M-krqH6me+KIG`UWm|GHvbvZz~bj8vPPXb@Zvv8W~%UzQ)X{R>e7!KBG=U@$@K^yVPa-;K` zxN#iA-nV0w5A~m%s zs{}U$GE?j+YRD{a3vM^X+3EEaGbI%$QRsfOSRr?a&9VtcT=8miW$Gj^mkg>WB^yg) zXmmiM!W*2V{`mKv;45(s&`0ONyb@n@a98%?DP00srgAVV8w*2I%VL{h-`9#UJRfV! z#jwSNrZmH}dRjZChVUuP902-NPv+<23belFGCP<3tD9qMW zg@%%U?>+2I{vwpSXl637l>3ZCmO|1RrCg?r$kwZZ>wG^hDys^R%(hJ;41!TxW^;>5 zf9V|y@mKn={>Je`A^*5_0bW0@7Zi%~ammQTcOfcA_PaxpZV4a^dm`_bOA9*G)bBQD z@G=MO05KvXbcXWew}#0(`i$_Nfq5}dREBcG1e9&m`R@|CCSL0;yp}owEVZdlp>L@tbYrV{isE?W5H&lk6{qwYD8q4v#Qm#v zO5_0oi{6MHc~<_5qgZ+OMOqvWm1txap9w$rfp=*v?`G4h(6_eRXz^ypex-hnF_Wb9 zVv)!u!MBitL{Lrxa98utf!N=SjssB5fXp+pYQXhH!((WLON=GcFL@0gwD9-=Hzc6x z;pZ84t5tMnQaYzH!Gz&{J6;dhr5KJ43M$1%BG5eqZR$OlJr1-?8C~YwVDD5DSKh}y zhB74*N{RTEo3xsb&^&`31{OI2e<&hB*zET;C?No|=p8h|k{f0sk(0jr`2oxjsLRZT zjW87PXLx;c3HSu0NrWZu%YLir*pQscVEIdd>5@A}7Au=;@;`UwVWpjwl4U zdi(5(#)>;Q;!F2rHo3xW&QCtulmS!eJ+{lPNBVhugh_wSA$kW@WB%&r#%IWD4k0PO zN=dZ9@@9beWD(AEB{>dK+NnCV2r(ipqO-0_^lc{onX&kZaZ9gQZfs)6x5SwclgI^u z1o$3~lFH0_uDvt8D3j4eND|r=V?*G-jqB2+fP;{z37YxQ%+KufzH~NY>Dpj6C~#!6jei$9s&Ouiv^ zE<9WL+~<5=_RZ*fQ{*a8Ozlfo_9X$SxFmL3RfjEwIUm?xros32bZ_>9&#b%6ic1W`49&f4tjRHt6H~|-116tNuqw61}gis0OR(B{!)!=$T4HY2>F*C7K z?n0T8!uBqzwJyQ0BjLs?O~ffW3vs`sNJ6W&%i$L=%P`wpd8s+y-uh*M7veJ9+X=}* zc3`?>V;7KwXtG}6trPZqJW$==h#o>2ai$;Nl+S(|UX(iE=`TfRl zRp=ajoQ)qg!$fOo^32{XIeHp+E8}J8D^57|(Tqv+Vq{7FUGHuTtIGq;ee~X_emh50 zDt8y*X}xDO6Z;_*2c&2iQw5uZrqh0S?zl-?T+vf!K-Ik?$q8MrDd1hliz#@NtU$dp ze8(aDmm*Umrq)9yc;DA{0$3Z@xoetCC>Cy5htxGr>Q>UNN0pB*&Bk$H)ViLetVEHmS&<($sk%?t$6mB!yD?y{NOCl+xpsK=j9nWF-fKqP7C0_c3G3_vk% zjZ#=38N@oo=gS?t;NvZc?xBrl6^$t*m#D-hcE0mAA&Wwsk*Xx_aq8(Lt z59@Jl-AeoFSA7HcvD2lBvV>5lwnQcSKkh^Dc1;+ zL7JaZb5Zpr0Kp(!)7IlGx!bM;kavL@|J6v08yofI<{lj_jxDHi#!q+9an(Wq9L#~hTW9KoN1EQns5EDC zenX+jfkOArgbJP8Z1E(e^i;7}U+NjxBzA#2t!gCeBd#_`Cy1v3ogFzVNbMbV#!S3p zvP-9jawRe8jfz&CSs_Luyyfus;X4laSrzV=eA}joz%$Cf)M-dJh)z$`@B~k?&BwI3 z*39@=zj}v|s06A)`YegS(k`;Vpc3M#hw#31kO-SCGMXG>L863rTm|C#FmKhU7p`QE zUGdWMVEiwD%k%9YOXyDlm$7=$hZ~ZIXHyU`fd@E0C`-?U@zOi0AVx$6=8pKXgnCQ+ zyQyfkgG|{i8lb0RgKj1j#SOCyjs7}?D zuX%%)Z7Kf~6_RPaa3+bSoAeQ0aZ-HCq8ppB(hX7ujUw8l-scmg_5&wRm5UX+<#HjH zR7ZP{hI)Z~diezkYW7J3z*H9|ouLu9fE0*04Y2~kbo&tN75MTAj_?pk^;5=2?Dqka zxd!K1rpV{wDJfYF9~(55efL|=Jf3vl<&%+XXZ&VxUbiKoA#}*FVZ!W{*D)q6yC($vCDWmg2NfNp#5m;fIlqPO746Uq&k;#1(Qf zN0ruKEXWafD^g!I*&fb**1#s^B2-Qj_k!E}vrlwy+tzuLfJGc)IfiD6>;zaoY~Z%2 zB(5#!2mOXD?+_zO<5_8|LXEWptt>psAB8H<58iY0NcZ%w!|Knl zK>#_^_#X4;s1s{CJfrKSEa?$~JX7meRz|b{5=*l2Oaew?s^VzkH+XK=G43wvesp+k z2rQsUck;|4SXEURHZ~h0OtAQ@v}Pom)(1`3?H0czO7%;5&lr{bkI0oox?e*VfA7<_ z$dsg0q&TyDxhBQoMqa`|BMp{Nto>mF>B(TZc~Vq9GQrAR${tWVT85d%%lh;;qzw~x z2cgo=!u#lK8Rbzpxz550Os|OEyeiT3lyab7s|qL{f4vgsSx(pbjRu#n0(tB+FXC8- zF7XInu!?Hod$SsNOybXk+5xxSwX87I1N=K~X~71@o+`Q)A~x=beXPF#B(e*cF8b^{ zRn#M^MA4&JvEYRnH*q_7F{`mkbXau})z>e{CeuKr<8aHi_=93SL;34rWV}F6>e;39 zxw4Eiwdb8;olE2K*2Um1({o3v%IY#%DpvLwK?OE3vK(^`eZR4^&$W~N&jgH$RYJBG z_@k@qkF-gF$0d%En@&8`@gQwx#+J2hB1Rrx4dxZ|q1$rQEdFV(P zx8nD<&yiPexVVH+2+;vfP5dV3-twE8p;kq5p?YXmw3}V!W_VH5&nXNtX76d1u!K&$ zlGa8E>CnSU(lg||2;gGh9A&^?W-sD{fFOhVdp$#G=euX_GIL z_Pi4Ie&>Cl5H8buf#pnFS+7s&x1~!Hv6D$WdqH~lfj%=3CGD!DfdoG`3HcIe_5o@SkneJ{pBl$6U}}qkQ^scL zbLFrn61oyZcLat4Nqqo-8Y!s%1#qmAswec~*Z6N^cuwF0-!u&*tAEB<-09NU-sd9) zbMbFrB`Y6a6K?S^4L;M6z14>(rzSLutn%O+U$dmxK$>v&Q1y62@# zs`c0LmLb2yOVSYWZAZTCA2)%~3^OOmRuK;`R(TQMcCXv8qz!}_I7pc=fqpEsdy~v) z`Q^P9E2pK>s+id@yvku+kaqW+0|?%D3X_(o!^mQ$y{-a zmen+d!ET?tJZiql&7*ne>P?r@BI{U17-bFfia0cEV@8D_0-N?B$?tX3cSft?mjYOK zwDEfNh^*N5Alq9Cj7WF~RmcL1Zf=Bs$B@EBlf&f%`;Z5$Vuy~QmVWrg1wte-u8f?Q=pLijni}Ul# zm09T1e*t>C2aKYzY15r{a$WRoi}4>Ayr?|J^ynK*sD+$I{)pUC_Nwn9rEyA!N6=m$ z?wDPu=%=5Ku*lC&6+s9}9$5Cy?|N;$vR#Tf2wW6<-0e{$nP1BJV}M9V*M2?WEXK(D;&vUQ&@cGP}`{;ysZjc$0$c+%_kF9Jani)x!)V7`_YGQnnHuDL3#Qz z5t+wC7Lh6#c6g35#*Sf$AOxRSHGyqmcs0FR8fg}lH@rxa;a50AJD+ zc4c%X)_cA%JeO!&3b3zwUeSDLD7`R|U;fYK|M28L0`V_xNSpWrE5hUbZb&76=Vp-+ zjw@cW`HJG~shxZr&J@7-H0o?OI3TQXKch`S8KT%&o)G9xNz%oGJd zj>wA?z*2oOJ$@D57@=iqZW2z6GdatUeR)Pj@B)nh>PkcyQqj|W-bwxiG~s5qLIU0CS_JaF8fi9Z1^ME z7Mny3H39wRq`uvhKIf2hO0b4|-1bj?J3dgfg9-w#!t6rfMZa^jKPj zbmrsGo^UL$+0+6tw_QsLr<4CE1tMo3j_^!1cIZZ@?!7SX7%juM(^%ScC}Q-Vb&6ko zJ}2`v3ubQ=4Ui&>kfuc;ISL|1C83=}K17Ce%!iN_EthS7g)Nd9WLlJ-y^sy^Vr_fj zQuzj@>gI@?DTxvQon(u)beE5jv;U|b)!F=pX>Zbd|D9{n%9rxxg=JHD28_1ld*;vg zOh^5Oc|)e8nyorHK2U)R=IA++YU8w#Y`_P?NyAKvk1}#|k-kO7A0*#WOb6*%_E1$@ zQFoX|s9d8O5Sq5!I0wZdI3N%!OQ;HDJ1arvtwL@Ixo5fHKSoEe&@R=YRC(0b5I2lMZ1#C90Vg$-`DRXTSr(^MT+3Fc~7U5?0E4yBps8`~UJ zXdN{@lWcm%$u}_c9{m;qG|fxu^q6;|f2}i!{Q0q zvy|J=@34=mJ_OB_VtMag6!}=lif0$f^)xh5xpF-)1;$u{R&A8BeFROz!-z&h8tC7F z*-&`EK(qwj%fvo0K78sy$aUA_tcmx^J%t-7eQ;RsS=Mrk@MEd?Wy{IGyAnPe%ET|~y zTXSS&GE2J!)kSx|I4oT(cm65L@KYBCyyU$y=-AcJ+MsyBPu%*c!{E1Ivo>m$ygu-J z3Dk^7ic{08DPJ7VFi`v`R%~J?Zh`l;D?QmT&irtV`b-4QZ`L%Y5}BOG0i!jQI+d?jV$JVv)oDeQ|A~rb}Ku~{|baNOz96}?Ir}b9bd{xPMU{61TwCWWm z%8BfXq&Sln#r@Sn!o83y3V>}CFE5NH<6G5GQ`$`EU^5%9MlT7@Y-~f2pGJl7*+x0# zsmne#z#xuJ7*+b^P|JTwv3D@KqVhE{Ad5YMmnQ6E)M@4OOHtev!^8FB4?}U z92xgPTDBi$-r}33|7n)uYo6ZILXp3DTr5yQd&#&tXwXI++4TB_tEX~@`?JBi()l=6 z(5g^hm!Q}(iI#^F0uqYY>8p2TO!&%Sj4ofuveyzCUa;pY=TU8xXz&JB=$e;}pezsB zH;JR?O%NY*iw&IdXNG#~QTEq|IP|7tdIr|0L%2OxnpX2fB==@N*7Wkh<0G;l5k6po z_X=V#LJ^a-MjsYnm1$0;MX=_oFYu>iC}DbY_T?@qg}Mihc2SEK8wc(bG+DS(c81q) zQe6a*sE#sgyQ((hfDV<|O>Pt%^L6X~(SQ(UB-@#c*~(0i<6*ogSXcJ7NXl?vE&e>F z!-1R)Ief1~eucMXO37-v${+X?}Dv$UF_RARRltYryG3 zfn^n)DH_vLV#qXku+$Qa7p~6rM#}VxZcG4HkPTJfRBlc6=q}i0l&Liz!V4Db|1m!) zpvSb;Uy@hoOutBwG)d@&$TPAP8?}Qr@@uW*WPlVQ?;b+^MX;EM2Dhoh8;!c{Ad`Kyv%j=)jZjY2v1=uJ6V<6dOoUbf7B)`>@*z%74RInrJvr{W*MIjGcW2}p zSYu%iCAL43@YPn{p`_!K+!7`XPNwKZI5{`omDEh>yf##1mBb?gP_K7?J>NJgc&~3@ zNMn_lzK4_yuqXb%-;w$$%IN+3^-phW{Yq{?_w=o4pI2hfFoqv{7hOHtN;7!ihiB=M|aZ?adZdt4=*9fP6>;uqLri%R+!aDGqx1l0!q_>@< zxP@u0{EPau3x{&5N|HVE9`j3hMhi(hEd{lijA|G*3@A1r88*G=1~BPja}$3g`HAZB z`poU)CG%Il^Yjw7NETc(&B17@IBBKp_fly3{mF>iXszFI>5kAbXyDz>vXy>?A7IzcSp9`07Gkia zT3pgu4gfhlT};^313c>BvHSFZsF*PP+R=s}MgSB-9b>Z5Nbu=nm60Tulm0X8Y(jG* z3W5r1eu#d8hhC8q(wH|fz$@zNNQ)_@A90m%kzQXAd^Px7fkDZn)edHFC@9=F5bgU4 zL@)9*VCt?h@=CeS7Jb`F?)lZXy4=>7DjXwT6o#_@)Iem<4h_Y%)YAuDRPhGGYWp8uVhzxQYPC- zr@?6YSjX%}cR3qHPqyau%umti@oj9yRy0c`8a)$ z?ypdsiRm`vSAm4tDaMpj^F(C2D2hGjbENIPE8)~4;#Mc87BcYvxZv{k3dh0L&n;dqL1F0V)I?eLOl;*H>nsrqa zkgO4KV5Wl+Ld8)2AQZ3q@~c3UIX_wEz?xRVQ~(us+lFN<`kLg6T>6N_oRQ0CGzT9h-?E6~V4ba>fWxH0r&Z1UAE zUV`upi&>hf9T*YR@u{WR7=D>vd^XoYXI-pJ@R=Kqgj>wLBRy^Nv-Qn=S zmS28uJDXhv&!T2ut=IGl&dW519TYeG7 z&J^h?6gvVlbt~y5A2;!C5cjAL=MUob`q%SW-HS_3lW1H?*`VV|Q96ae{WZb-QLKfX z1hsASvuCMdK(FGRW&j#i(L=Oft?tX4`@0^p+1|o?IkoGVj(DK8U_Z+OMn26AW^%yZ z-5=6+3){yi-wd<>zg<}D)*F?}G`U5B@FiQI&EkB|{Ic`aO8Z$}UMh;7i{Qcd= zAr-@W-x+_(ZsSB}K%9>|izX^nV?7|z^u_qM8`QCoz-!9@7KFYJKdMLGn>Lb)dV)oU zbfi|HTt;1QJgtTposm4oj8X5fYFt8!go?4P zoF>+u3d>6vDLGH2%sIWL#gyM|YI-yK@sAqW+7TShrSz;boJ6>m{Yw#@f!UWT>Sf+) zsCAK9uQzwgJ^)T*d?lXaT%$82MJh_@3tp7d;6GKJrU|*IS|{4PLY_I{zwx^LTiAD9 zsj-+O`E>`B5R=rx$lD^=D%+?A(e52QGJdcCsQ3QYnhVwY8iBXwj0`4BW>MH2t>H-_ zO{_B6%3X}^H9M&<@6CU>s^UldPTgdFF1X}*$h*=opydtNj@OfNj2wfnSl>y-AGLs+ z1vK<#;Mfm+ktWY-L6cK@Hn6@@Ka$fz9|m%Jmxb6Cb8bf9`%NF`_Q(?1nxa5$#1PPd zLT-s)JgpgiQF3Fz4Wk;_8q`5-GON{${q)>N)>*75jQObS=_C*{+e~8 z$87@ZEca9*8yfoC!ch9rGavq_AidNomIh-O=0cXokoyn6qRfXjiPjRPV$dvS&+{MX z_y5y^{#lp;pid<2mlI__Mjc5bssV+&duO#p0lC^bsb$9g+_&%^W89C@{?HHFc53<5 zk`&RF)k?S`S;Fiox`bTd2^kbiC-I-C77d@KoS)AA=%1>B|rb>H%GPzbm8 zl6t;}g~dJnqNrT}A@S^`6B46#cDYMZO9p79+;emo)I%rFV;tRuU?ayM$=Z|*uf}*! z6o%p3>J;|&dD}i19>))`)LJ7cN;3LG6pq4Twm`RbRUgN$~e(ks>-z3 zX@kYUGr0m9L)ge5`uEuEaGn%dM(W$pM3(5C+w+LKKX}m0*X_U_VJXm=;H{v07V+T_ zz%$!%lB*sMcEgRqRk1S)-3Ht;q5bGdzP~v{b>ey~RFxpJ6|mK2BgJwW50R!B`4WOs zXMQ^9s7Dpj{hp=E=Tf|lBHJTzJ&G84{*vVoWH!@j`JlX9{2R85-({g_!TA?J9B#HJ zQG!t%aVug^hP(<;6uEj6l)o-HXy%4NETE=XSR#VZMNbgl_42}Xj;Mya4J;^>w zQe;i_~BvBe;9P5>O)vH~Qb z&zUzST^=OI$V_$9XV>!cl3+3F|GHCxQ=w%83K;pGX91A3N3T0KOuqMGHdo})aywQ6 zNULM}oyL-;8H9}s3z@L!Mw8T2H-|PxR`L3J1t7>{k>xyne9$4oamHzrz;NblqdfHR z8jh=rvijTP{a>Pm+1aaFj#)HnXx7Mx+pHEa4jX&i^tRg?mtWeU zR@rEBQ*&&Ld;7uMu15fc%->a!)%%512g2yb>w7tOdP;)Hipf)Wa8nfdnR0@Wh8&T(ZPCcoc`FL^kW4QaPjXShu@IgI?1`8j3!D#$H2fJ=|*K*4P{l}LY3=9 z{`F%NHD}6JjF9xR{m-|-dw@=il!5&JjX3!GN^GW;XLHI6VE^AGy4HkcqK9h7$;zb2 z6Ppt!2b3C!VdEX778tVsPQ`N5^VpR%enZ5g9S_FYv+T7h3P0;Q-nmZ$N*L&rLmAoQ zU!>l@*;yy7uvmI!3B5*JBp5fr5Wb5*vc|0ujh9{Y_Q}>H9{tTP)-2k)8CrIqm+5NS z+vMPaH58T^dJuEOL61eLW zCb`b3(-wZ%{kc;`s~kY+buOX9{Mo=~pQh4kb|`v|Cbhnh%Lat(cRe^VRqx4hc3+II zo}}_~4h`*mQZm2%Sd#XUL-)PLQ12^ovB{6CSzAW*7YV11!#e0WL^SjH3A6c(@yTm+ zPP&$**k#+L33tbJ>Ml6thEFVb*Y0l@jw&{%0is;lv}Uxf{;3;+ecr|OOq4$r3;&46 zPo#LHG0XNRzN5)sU=G>u>jT#i&Z?WdZj=h@Co&y7F@mTs?SaEEM+qMlUtC|GEG<}& zb~FJ=Yo||zN;Z#0Ek_?PA*A~aPC>0Ce{IzD!My-pWjICQ);*7R;G4CV>cJh8XjpG1 z<)%EnfgYR`(wNKmqjTAbXVOFQ%tzzi(uw^2oy{j=oeIXU%iqaeZH-P0-}k<2_veTE zc*9MqGB|H4#3;h}YmbPp9zA_4D(^==Jw{gd=Z9sejxlCy@;t40-zRdy+4YMx$@#_( z0K%Tl!myZ--d$}6z0nS+JsOrW>EkjvhXtpFTDJHK-0~b6eHSTlO7u4o zcAa%~BVjfPDp1)Gnmj)g)CM6SA^-5K;7|2cW1KC&ccjv}x)ADC*vOLZl2DK6gdbgs zrX$NAf{Il_gcPE_&_yoXm%5p}U5f9Jn4prm7IWDp{8GE+`$t~>X26)CVCC{B)mtKI zh#cuuG1IC1(Z1FA#~b%3sv+X4F>t@ENl2ek%scv*@9_U&LhyeK)A(8>gVg|HGvxH$ zX>Ze<#{!0)U9H*u1Qm`lKNcOh0PdzDKioEtKmHVW=>pYh-n>F7fPN!P8Ut;;J$S$9 z7df=x9^iF@F8s3V6uzr}Y6&dFa8ENe-7KuV6&2Qeg4|%J2tZfkx9;In#0T|;H+x<$ z@fC$I3q%&gZld?BB{EaN?p*lHsE#9Zlvd2P6u*YwWWvwGa98RS`lFCHZa%`R>Q3UF zGbkxMz<&K5i_Ex7Fz9w0{XvS{wg+xSPNy!yET&)R#pg@ipALEDdF#TyUVe!SZ`R>QZ z4{vII<_k@15|>4PMR5{DKM8+5Czt2gCj9l4XJVKM{7@!1&k=DY6Gg0b)(y2*o1dB3 zS#SZ18B?Yl94;aRCL>B1BO*`!Fyo1Izg_spx<;<^XC1jd#^9v&^+l&3^5h-EGL&t5 zOozIt(o+0)E<0Y;+ZQu_idq&41EdK6JzZenueoVgTgVrq*-y`U)H}Nq{lu0yj9ItC zyu=XD*Mo>J0VI!fRks7X55H&vT<;u+%@pqgY~uTWv7{1?p1r+Yt0G6Ez*bk6+jMwA z&i$ecZU5iZfqmB46yQtre5ojhJuef?DGJ@X@C5S-K)Kix0y4dOr8fT zq;|osE@8AswT)UU)fY>Xsv{+t7}V8mSHnat9>yKS<-otKp&0Lq_}bpLLhwIUd=Jg? z+Vw{*2J@xV{k|HXTD5p00Xs(exQjAfG0)9-JvX}kF(CqR#BCs3+-)ey+F}#xOXPnF zi#59)Qi_vg*8n!P^AlWeEhF*Ba=_ z%-pfcm60c(3OV~LzK~eq+YEotdSqOQ&sJ;sMmZ?0onCY1iBwou37_=r;sWeDsb`3k zcGWd|?(O^6?h@KD$wNohEzWaK_AmflJQv&4%zZiQ*wuaj`<1-*?bFbXOeIVQj#2MV z1m92k=_QfRP;$cGwuw+x`%~ADvJxj+Lr^TAT|OBUw{R=pbha;G+&4Z6K0T>nYhKGL? z&)O=cJHS5*hUk!u#sKnG=VxiTK{9Jx;(xB_(_T4;zoZ}HO&7o10V($KzEPx&rbqJ- zO06aPZc`FNJt{>52{{@X{-*$(#3A#mn|no+TG%Ij3EAGrBwRlgZ~yufW4*An#nbEf zQ>6p^)8USxtz)A@++>!%7}7&bF6j87%(Sh8Nm@q1-}Y~Z zrOZfx7}V;SzOd_*LFh z;mb7Ll;Rhy**z)e-w^Cks+YW z*IsBNT_sqN0kwVtwL*n^zvJu4rySK|t8Rsqfvl^sRU`B1tP(KA ztmD0eM)Noa{669}tj2r5eVL|31pWWmd+VsWnr3hC;O+zsu7MySNP-;P9fBq}0YZ@A z?iO4Q65NA31b26Lm*8@6PiFJvdEWQl`^}yC*7|1F%pc!cXK@aD@2;+{?yj!>RdsEe z3kx`Nfr(b^cZAwWTT;8ds`W)~&hxe`H|s)fx!)$U;is&IL!Ydm5 zTVJnBQ~UOii+4_cZi|jZ+{_*?Af1w%E$XBK?GN|iDOmhC9<{l7X(w=rIhre4wWoA= z_l^%7hdG)T90_bpxGnop%pzDG-_4r1ev`+`hTP8tDx3`6GwiJ`qfs4W&1CjcO;mc( zwZtX2pwxUJrEuh>r}fRTx9{v3({!oT2ptS>^*Li@{t<}}Ar8ktKTIC51H0QEKJ>5n zKv4nZ)J5m}$WS+1LXU&C?^4&;2s&_+Iwg_e>)*UA{5fHEY<5~@;8^`DJv^_U!ko(6 zMerHdlx3dxGhe?KgvPQc@mfU6k)*8Rt-j14_(NB`^B+m#=FdSA{E8?`50il=f?EB{ zSLNh?7WCgBd}nVmsn-L#gX`t^qbysLXP$W2<>YIRpJTw&0R64V8e7SQNRa$f{#kZ%lR5N+SY(*ZDiTnn1NaMH6<9ZPJm9MTuy1Q{4Y*hxd_`7kbk-me` z*6UrPFI>8RqBJDE=|sQYOXLI3ypz{DGr z*8ybo=F^`m4|~H(FAE9!Z9YKG|9mv~Q%kbv5H<0HJ}3ej65wJq9Zby*h4YiM zF~QBO!nEw&X;Zt-)Ebbeh$Qi0L5$l^H_rcp*LdqKz-Vi%G2e!AonbtwXC}GOsqy)>3i!k*Zuca``P291aOrO>RL;{i>yiA<5RogV(&#F9Zc}RI0-Ga2)&pUeYO{< zopf06>Dk9gy@tElXpEe*=AL_H z%bc8}@1e$qWb$4OpReVmjG9J+8|H)gG7R1PS_*xoqiZv&In6*{i9mcphLDPr8D!{aQmC_4QulS{`=fh$zLJV}37;VaXttG-btRlEePkuV$ZkZ84^43^*N z(A`j0=xzP>0Lh9|wOf-KPM5;JD!AsocFUFiuI~IbYMe3L=w6keScwIn>xq~i;@z02IVQk-mW zSe4Rc7rEt_2+&77bCY+H7{6V*AW;pGBo{h2nEhI$RD|~FrN2NJ{R%S*M9RSAIC)Wq zwv}!sV|jPQKv3HrD&KK}pK7oVRap9_@2~5XblN*;4Z%!Jz~J*Rppo5KAmLzGXOFlm zRes;37}$@v-yGI}@wros%^0mjR=HZXCCh_p>L58ysW5)Hex$D@p~jdr0mX*rIfMBi z+$ECJg)Wu%MfmCr|2_-5CN~;Vv=xEjJeHWJlmlublRaOO+ZVH2(peQJ#a!eV8?K`* z-{;>n4M{)i@TR3ID&+9_`Q!1RXc71>oVJrhlrGWDL7MH&T^$5?AtpICbY!vV2z(5? zC89w{27xee>j;R4#;48thDHTaMJUd$0(%a8fmYIwA0uT>E3s) zKSpY}a~3N+^!FYM07xfZ&g2(TUmCVLYHF-ez=ps{OUet;C9!i!cq&%=B@ddB3@sny zc@7t6098FbwjF{{`4nv8SfrYBt>{qd(R`g61uO4?>EDw7qI)6LL7_aYSxJW-I`>tT z1QpSra}$P^uY6TwVKXv*m7a``J=rH^eTn7e(ov6n=L8AHJ9F>vQn|r3-xI4g#hkG% z#-kcqh8iIUVwlAnDj)sLf4XbJBOX%C-HyE80o`rg!Ys+eSDno7^N(O3(pFk=D{@TZ z3D`X$WkKI)C~)|g;iqI^8j;Il4=-(!@DFH&rh5wTgR#UegacnY2Bg80a;ECP|*^#JoKo_KZzxxzDmm1t;u0lM%MFl zJD$RE_~220P{_88<}Ca2+!!Bk{`{*`^xWyIyY2Lq@`y}3LHo`|YYGhojC-1S`Wmtk zUIjQC|7mh~KrE=p#IAH#IWPgbu=$_lM?Es-Qe9%6V_hQxuF+-Y1Fj`1jVmDC;KkWrRR)0L#sBg}?T^a<4MFnLmrFuRMMJ^SQS zm(kDKek6rHI0mE8NbOI6^M63Gh>{m+gHr5y&Dgt~HOX4t$_W3WdMzi1&&N_qX@h-$ z0~gtkKV(j#EPi4(ogf_ z_Z?lr+QIv3du|)Y{S{R8%$fuHXo6a9RI}l2ZNfzu(|Ie-$Xn1|01HTX)ze2gg`dmIC(x(cu|r+O*CA-8ML&3{Yh=Vd~#nJN@itfd(;?30yDEysHH`NMe~Bq zAHntWi(o=~i=ytkWteNb2HAN&VjlE4_W_8sHSPV?muM%HAXAC3!z<;^1F$I5336|j!qAc(L$W70j&n)nZncM{Ym{LVUuU$0sP4>=!Ws=$*0H*jFk?D%o30vX zPWR$8ox2w)ddXa;<3wc;V#T<1YF1|xN=(qcz@v7uuwfRFon7W9RJAL<<`Lo(#-?wj z){U$TML-nucNJU&KqD?(D>5F!5&pd~{q}PGGnRIqi0eqRoICe6sx7LY?NrY=4O|M> z_qjHWMJ+cJ`fkYk@0@uk1aWwFA(=19KBKufWE-_2<%2H@2YZ`M5%w*}mIJGLv%gdC zQXYZn(KEA>Ir@F9S1OKOtabCz&qyW;tu}0DbvYVK5tY!#`CAl4S2yT^sWW%$EytvigH-FH%^}hr*-078v z<+2fdMwPutf!5o^=v@x2LZ!$)P`%tJ9!#M!CdL^jP5neEz;AX)W{^j`%Y+!{dWLWj5Ic*ND#JN{K}_%oS21C0yl4P+h7GI-&v(&P_>$9Z*IIqgFsu5Htn36@M!_w zE{}pgEZ90<;oiEI!M$eL|9tmTP&e;jDiqmFYLLee92&mjvqi4a;4A>SxZ#VzFmG^a zuP{>5jYN_7q=6eRier@DLP~6L|MOf@R82=8w!O>Ij|Y9a_sIqUgy2))!G`aiv2wBy z8&-VQ(9*GgiSd{3=bh(Ei=!b0|5FAJ9LEcC`y38z zi+Dx)RU~!^FtwxDs*Tx)>{R(((X18juayD@y?XVRS#8AYPjE+gGPZDa1le)3N#pCO z&PsdRFV93}2s#zj1m0*e$vZ{nspU@JkkA(2zuM2|Mvc0s+gQ?b6Sb`%$~ubXuc}`g z@(+yJQIwID$J1o*Z?!`Du6P7Qb0uohXMGUut9NDd|1boplpTgE5D$}W3^>4>-vkto z-xr4rv4*zdPO>_lZ~V&_OrhD|T8!N~MW1~cBaJ#kJ&r-gsJ8dsgAz$Se@ELVQoiWt z0#}!psigajp@IKIMYw`!Uxz!v(!%(eQF;3X7UmzBC9{UM7ImBsinu-VFf$Emo;|#A zl(~aAO17GI0JHRB4K8D;DO#Lu-u|q#}Huk0s=W_dlMeXO*48tCqy~rGxg^`&D zo9QNw8haW(DvbsAH=0jE0(S87hOXd-hx*Swc%h>bS6Hf+3Tz57ZXI+V9`*DBvL19P zsF<6{P?V#UYcUg;lGEC5@w*H`5q`Mc@pPlBxVTMQ*zo&?c% zZ2N>eRs6NMn4D!a$UjE^6c&d>AgJtpu1lv`m)$jO@Y&9NPGDUi(C*Hc=|Sc~cy#mD z_thz0rC<9NX4k{_9D)?fs23ID50I{xxYIwsI?!koq=lV=h?asslKBR(k(p$dlh=d`FO9D`TRF@ZB0>^s02l?U{8qMP7( zo6lfYpW66xpZzp_WeZ#y4hoTi*Q1cfrC+U^Puf>SeQ3VxtnhlX)Bgn7Q6mn zGe04#DtBZ-#1#1#Uy^C*y))szgHqQbF$1G88O70&2dF|55%bc&2-jhWhVM#}6V>oq zL6Sq%&uox?tnrSc z8=CID)?3<9EWpr^w2OaB{u>k!8NVdsJU_H3=aQJthW%x|Gw9wXSWNP@o^48 zHdPal_h}lHHc|#w-)9`TkSU?L-23pI+XXy{8t=nWS5WLnKVXuVAYWF^nBVU%gHV5=g={Zl;C=269EFX zy+rf@1_vycz?7a*rjA>2@JoAkPQZeA0=&{f@g*VsZBr`6{1-&OLFF^8NMbZTa`;16)SC!XFOV#BYd!>84ugE2?fhedM!bSn2bMF(hcs_cGm#xTk^9UaMp4d8etW zR0Z>2t$!9R1(N;&j&k4IlL`~0%5t}1N&B>7weis~me`z+b;6P1Pm{D|_xBD*54vAn z#!{WX)71L-zGQazw2k(Cs^!TZIkQ=O5r<#n9-~-HGvwlyY(x`q5EB4;F4O-o3rZkV zhxT=y$swnL*R#?6b}G9;J8y(-4k<4LJx~Q^Sx9Y&*)*0n_zN^CD)Cm*?x3#Cs^Am< zq=ta>>B>XE5su4?dFM1c)?>n){;BK{+SCbM8wSZx&zlg8$d=|#DN2Bij+N)#5vXG(NDSAAbEC{*H8YlyoJA zrnn>;rRiDDmXm7!BI^|F2d{6w)-(KpIGxDP^3x8r`*tXX)mtQOg3BT4 z_Aj2c_L&ESVwcnN)f(}WLTJyCh*61zH8jVJa!%O|*`Y-QQdUwwa<6V+Fp%kqyeTjF zfof8l@Ns--IfV3EYB$hEK~WapFfupvJ6yDaQ>d)RDaaZnzD2vP#h>6IBDYPqhbPs& z26I^Ti18sS(wA?+l7BBZD$Vss7x{YfL1%eT94=GGeVND8QkaK=1D5Q!7-c0b$)g4drUC4$$ai_z&Il^?R})(Ndp zG5aNYwG%bbvd0ASE{kd1(k;=*ge7Z5FVpH52l$dey;nW|h7bP@C=NYCT$aoifAwOH zd4(VDLnbvl)q&|(W`vssCX9wir4U<{Ihx(cnD}-*(KYQF^XVeVes_Ni9?VN{29yf5 z)Q5TQwKNsnJJALp^+Oe)Hw{Yr_u4hjM?X^XsNTKhU+>aNo2Y9FU;t7^etF3s;!`et z@G#iDcZj(z6^vJ~{ry%Ro)I2WGLxTNh+N+w?j1!pmVEkUgU)bKM{Rr!ycd{b`wm?lBV5tqu1eYZX? zQwFzT*#r5_@U5BTDQc8&1k2`-Msn!dPA(VQ`)b#reo1?AlZ^hHhp`2~4}PP7Q68_u zL!b$U^UJ#w?&5@_1DvE(Z_Yi&`EhYS_KPXKm)2Z?8#Xl`SZg-WEuQcW6t2|bPs4-5 z*e(6cMZ3iyLHw{ADQde8UdJCHK)p9g1Zap!%%Wh|4fo=nicKsBgUi0W;l zjh5S)Qo1(2E)c;XGq?=8ovsPs#fvz7c$;N^QPiIxU9Gw0_3FU!<=xRK=zWCg}W>YL2l9qavUFx`9R!z8hC<9TaAbe3?ZP z(@PyIUxSzTnE2n~_e+7F3v^`mHB=hnrb=@im?&77Ns%LsMK|6RsN^buIC2p8+xQ-I za~+ufek>i+i0kP|<^qv7r&1<=iv4r*FB-r_4OFs$92ZuUl!^M4FGx(c}z5S{m6vT~Aw z`AM^vfxF=0Mj=`P%OHDx8cBz|xrIDuSMN8?sP>X%=`DooKCt!6>@mq>r(WHs1&n9X zAT`7#Ud_gP}_gM?|)*{UwQF&mY#DpT6KtcNW^DXB`gX#mD{&W{HRVk-(UNQ?K#XjgsCE zAf0NzsMk3R!7)GwkaJDw7TieVwr4loQk-0&odqi8$Z5?_mJi(-WqlNfz!XUa5ZRDE z>IOat_u*TJMgYR4x5YI1g0Y%$r8yscq++;x;M|YMHTmYSGnZ?{pufkx9%@te)Dkw{TY#(3XzZKSc#Cp0FE~At>g&&* z!p?Mt##Xmbk`;x0eyAj<`Mo-+s3sw4VGzOMbp>mQ*)#c%9Wci9|7ro|-U?u;e90Yn zjlqXdAw(AC)RBR?RF>IkU5>P|kVtiM3(j&!E5`GJ+u`X1{J>Bi^w;V}dwJknL7`hk zOaN=!^nJC_GnqA@Q~Bo3CkLrmhX`Ec&`{P(w6j=Huk2sfC?PpXlc(ZKn@$BZt!rsG zZVs1pyL6p1=|xw#`1HQjysPl3(ED=hT0JI-n74$jcQ=4~ZF2u{i$A(2Dvy}RrEX#I zYKaVjIM!iSfd=)y^>spVk!wbU*{sUawPDj(LxPUli4Jq6j5Un7x4Q#=9WdsB6l*gY z=FpWqjxFW@74O%`{u?_0RDF&Ui5B%iWW-^Y2h}Ig2FeL)qo8JLiwl#MrNNB%u2Sgj z1wi@rW0MS7B@9k8yagBX#Z89PUfkXxaS*nb-XC!}E0t-hM#EUmZq(Z~NB>%IO2pV7 z^ZO0@y1&aMyhF#|*=rM@j0jhB#$K@UX>Xh>tRZ{-Lt@a#xd%Knie9@K+F?uB6cb1;GRL!B>3%!C#d!~bO6 z_mu@C?aVR+<5D|$A4!CrU)mg2rHxospT|;Bt%4G>Z}939Ri5dTvSOUKpp0H;R!}aM ztnsIFwgU_l(*f*QcIr#R{M=xV&L}(*$U_duGL!sG>1GPuBAr#jaxDueyO+l zJgpIR6N*eF0ZQKNgS5=W)cyV2WmiwI?dH$gZWm8RR+osLlYJHb%?WdicZF+d&)_-2 zVDYkmH?I!y+%f5CKm|%?(zRTa@Q@wZU6Fj9C7B;&`#G`2rT2FB$DtUBTs&O-13u+J zdUHmDYrrg9UxqCg`kosMM^vf8Nen^*MeXA7^VCx%CJ(7RD#kcJjb+*;yuMcHV@^=} zasDL(-;I3cls;}Ms7%IopT`L1oX?~RN;~+fpl7O>e=y*U7OC%w6o5DQ&jo(p&Pz0p zC{L@M)JS!=2Bb>9?Us$yud&#fAmJiI@dOGzsjRS56SFj`_Hw$hOLvLS2lZ)fH>3r! zO?gAj6zF?(m=7)XYn2S?(wC1ko#b4q#c^Bh&?l#dRg6RLyW_|E*)eE97HV6LJu0VL z{P|RQ>iqtoUi8!OZjr7Fl^L14OPuZU;b7lc59F4XYtSZZ73~t?uw42LdUbZQ0;n*7 zq4omzf-6PL=RA|T#x4_;Q9ga~lKJz$CjO|0n^CHY;Uc_##A+J~CZqslhAN5;w}}{c z8Tjf1Wve0D!@E@wGXf(0XKaJiRZL9Y0QTEL`4OF&{mpG>nwNRQ-@tL`kVqduCk5I6 zisCM}{S?~7+$=f9Lw6hm==4^dsH=jzpuWHK2JMmoE2KY7?uwtX7(cfvaQU~02>h_v?N93imr~!cNuH8+uOO7y^8prSEB{gA7 zeL5CyIM6-2y`e;myE4~E2k8RPu9NU@&;=nIdQnj$_Z6yW2ZB<+s54ANS(dB4yI*Gt zphxNV@I_8i_?bzLXJUw*mt~i4A_Cvn(~m+rK*r}9dk6}=El*kq%TC~pM)^6tIm1Fy zv;c+PvpIAkmU2RMZjB7HvA172zb^e6`djoTI1=Lux!|(UYqj5?hMRJ^*X(QIdaO_wgDUtMif2NtECw zB$C0S2^{OXP%pH(cM1%=o8-iwGzbS+>WUesT{$JHTl&e1`^^jC3nJdDv){64A`ip< zjO&Qgh=%GGN}5ZHmrdb!xzxV2ZaDNC){YrJj(F zOJCf2i}r~Qwhd`dsZSN#cHCCU zBuSejGr+5QWFuXYDoexIG^?OkIAib}v|kUSC2%~jw2}utnRi5G1V{|93eIW$&G!cJ zZ%~-WgVLw;d~$*hQK^)9Db4BVN#Vclanoq~x2W49F|T!Jnz5!&0l91}na({oP9<=K z3{_<-UDJMXChP4adxdW*sN?y8D>FF-qZ+SiwYKv~6A~XjyvLg;i|tSSnK#<`;<4=} z-^l|Z=)em(YG3WL;Uw;_@v)fbtAfM&nS#zNId^YMm-g_-DE z5ZHCa-u7e&X=+LqSypfk*kSx7@QuB+oXFM?B~Sb2op#h74aDQ1R54`LvJ)OiN8B3% z3s5lQ5z9eh%ka%t*g|QS(;wuRYf%%p7C!c?J-Do*K zk&{ZpkA@swq8~ZQZ{#Jj1B(r4%p!}758SZ>BSinzF4Y(H+U*x$qOe=+vztoKxH;3+ z4xw<|n#LupZh+Jl&+9I1wF6>a4&J!xPLPg;6|;O&;7&9dvaSm$Tid7a`YrY+QG?~o zJc4DFPM+3)^5yHIh(G28OYb|2AmVvW6;(OxA(cC$RZG8z6N`J-JL zWBQ}MG_4D@Qxr(y>Rf&{=K%GQjPujj!ktLXo-!uVP_9x5?;LmMd2?&IE&@{M#9n=4 z300A%jRC@w54C?FV+?&>+Yvc2gDy&k^Srx4jpcHe;KGW3B$4z&-UMEes#-sN;1vo? zuzoAk)P0=WM~vDR!(9IR#m8mI*#);c%R~15dtjD8jOdQH}x;|35T89EaH^C;j4La8%wDIN; z?hMSV)gdR!CPWdP^;z|r0%HWQfFU-ebw~%;O)nAZrOxAj-~mIKKl{J`{dmzZwg( zp>KQPAIsKVBf^%-?R&(2M{L&ZnDL71S$*j9@isf!per9`_%Fk+$G0WkDhpctv^TXT1}fnBB?}3OaAAg z>vt!lk%OsgGvB+Lg$wFL%!Afe5thT6F-wS?RB=uq7m>)!2om#DUHy`_?xujwVX04k zwi^u2f%b{@kv&fv-+A-^LNT0gElN`chL;=Ff}w_GCKd2K&^elzbh~ zwa`>4Vhc#={0&ml*?%{c6jt!!xN2Q#*x`M*Yo?B41vo<~f*)A10n26y=A8u5!W%kk zSLESsNxcOuZM3uui-^7@w+94RZO+iiC?WbVa_k!aTN&5LgTp@y7fP)MXKDG5nI)Cn z6pm@J{uzcsd}!I7;qlsmINr6wq1Qb=gDo0Rrm^Hzj z$~CuYH_3QVOI~uPHL{n82N*ZU3+E~FVHL#%{hE`1Qi~t0z;uW(-S6)yb2_k~fAPy< zkyr_?c6{I=iNoCqnCNGg6Mc)?^_25u?IrL+ux+%w@QV09ebM3BF(N-oDMzqM4pK0b z&@qf=2${=q(McW8vFf(FI@#~Dw7IaUvpAAELujN`e2duppZVtW`Egh@_|5P$6HId! z!5sX`U?MS*lGxxKhjR?6v@|#p?k6jDeXa0v9c|2K39)0`SE^~b9ZW_cw%hXLJRslp zJlD*o1469qTNv-A`Bw1xysXxAizQj|0 z={zMZVBpu0%w9$U_Aj=o1`Y%Qfe(P0Cg=inuGb+Cnkb)X3`W-?jtgP>3Guh@My>Sbbo`@TECRw_m44mxI0= z)w(pTW2V43*+PStOXpp0N3uU!M1Rms(w_2!@-@^yI9+>}Tyer*`pw@OiUO_`13US+ z+&rdOXD{W^=7heL_(_ju+x>9%hl!%=vZ5zpfewP|8LGe{6Cx|EjgB8$3K{qE4oR4q zLC$vW3T>X%2qf<(JLBQ6?B+`l<1e6qiUPKu*XiND*-RmCC+0N=2O|=Hwf${#c6sYi z!!&5}mXKmwvXagOnP%l3$)I6GPBl)Q;^Wffh}@;gyfLagU*P9HV;L567lL>$m+d|_ zHqrahK)=4EsgqSOzW%l^hkN6GaGWXn{|QaKhM+b3bLQ;vX8B8HONDe!a}e`xkuCtm|;w z;Ae*TP2ESLD4)Ib{^_WjhOce7MId6ea*~pesOqHlfbHj><14-4DgLo8kTp^AM;3hc zJHFeCS01%4jSa@9t$A6k>yWhyOEmV+uIX$raK@ZtJp=IPzEZdisr<#m+UTI*tZ9Wx zjUkVee>AW!BQGItUjh&}5f?1xn(1f#dGGWCusjUb!nK%4+|dabSaXU&R-55N{1VFF zq;}o#sDCKJ-0w}+@q;zBejhN2S6s5dQsT;zMf&DY*N9BCsU9OJ$tLI61m3nNO8H~zDCe7?|ABQA-z#a6LWTJH~+A4 zS;l=}ULbb=2g!9!C(#`F>d6#)P-K9%i=( zCEAxPTv(%<^2c&kVM zihIaJOnyhLqqdvm>twA=pQKq^NUthx^-^`=HAjiY92$Z*KNV->HdmhE!jb7>2ly=? zT-9&T2V$3SWMZp?CI^#Z|I2(wH&^k)l_~hr)Kvu>>EahWR&ht~WZdkpPCdw&oXSUs zmdrqY_oP6kEnyCE`k2cYH+L1oI0`Bt2HhUWhq!5Oq3F{Y5!i_1(CGc6pzJ+kQ~(#^ z0U-}Ri$C8b)}HR}6x$D@`)r^*k2gxQEo2}iO0YC&Aty+V@!H;?ATKSW#a0(sDiwfPLxZ_!KPPv$WvL%yOTj{g~h3GNuc4 z8HWs7hHR~dAR67Oj^iGE)JT-(E!YG!?f;1ct^YC4)&EMO*Z)Z8 zRyuvv*B5XHw?K4PJ6~#677g0Y_z)Gg|BbKi0B6FC z%sv{U#DQA3nsN5*UF)~0lo}RUm8t)wKUN34pSCqpVm%Mt6N(mTum#h4b=ZQT@S*^g zVfstEfBBb$#NcEo;~94YS&=A_PQx{Co*B!-!h3pZIO~3VHcv`6sn=W959L5#L@Lo0 zyne17ovL0E7X8B;4g|u6ZA0*Wi4eJ?V3!@=7q4)^(amA1rJT-mkcpEoCMDJv-Zf?A zHIT^H+RKPLD-E(KYqAdzDN?-yIo0g$^PxyB8tJ%DnBQ|<;z(n?xesJaH}tq*s7cqB z>LCjT2Q@SA3feG%`>i}aU#_*vq_hpMW~VbL2v}YuVY>Y!W~Mh8R*iMY^lKhGQn2Nl zl|Rt2&G`)qt#tAV^a=5mbFeuuZ5GP^Iro`w2catk`ra#;pfr!PZn3l*YW7r}cTu(@_ureg&J zo5qhc+D_$T-_Amhr@}{#BUM)*7d7Y26y(K^)m782a5E70A90tW7X{ZwkY_tpKc$bu zUxO=j*GHG$Y2;EUOSo!zh|6larFDc0Vjt7VDMbin?Bf)!_z3J7zNZgQm-`KB16KU@ ze4WzLrMHdblkz`jyoOlMEG4O2)6T242QGiDMq%;#2*y&n#bgjV%dhN`^({2?Qky_$ zV0i@B&{J2};#P1*L_g_-%@o`bmfm?R<uKNuB%qp}@PN)<*1nU;utd;|s{ zdfQ-lQ2lK_@v3jYqS~~Kj>i3{bw-}3gBZi-cl!a7F5a&y&stlb$g;{<=RAKuClIO- z;M?QYB++OL9p5ei6YYWij;DO!IQYZ0ABWmA@HcEJqCTx4{ z_2S#8X>WZ-S`k{U&gppy3@dBsEyRe0(!(|MRWSSQysHRuvFoJ>xfu ziX7wR20-^$`Te`p6pW34*Rc(ec+_2hJkHT?JkDSQ>%<~;H5Dd9PzYRkk=?O!fTd#8 z`ha-hVLZq0^LPvxAY+d1J&{1(Dj(dm?eWa*q$a7QsN%Hj$EU@Vhx5x+F`3><3 zw&U7gXF#D%?_?(-@T3qwLPYP7#QwNzo7;qiAm4wh8DI;13rsdTbR1>DdWbygp)+tR z5QE#r|4xmRKa+bVn;eQ_a~SX5f+cg&tS_*~O%eB>G|OLl2s!5S#>$@8hbY&iv|euY zpcsa00J9v?uY5Hj^w3@?{!rYNP!lm< z>sy*6^5IKQy;Z$0k0MO=ZT8RkL|G!&4B3@4Vq8SCrO~rHPx7QpQzTOzVW?C1M1Xth zFnRj;w-Up&+|C|d1;{{FfmuTi7C1BE3<_3dAKEsGeC1Fua|n_ySLCmOvDRxxK=i_c zfhTkqx3-;oS6FMgIGlEkmmjmLRlPFPWKAA5Uz_x(b^NA#!7Qb zA<;h%wwYo3B(|+&o~Ft&?*yrwG3T9EtgKt5F9Y4l!!D(Mkv<3cM>;ncIOKjGaa|~9 zxZb(w7mV{e4zSKGd$~N00c=lo6KBz{WM9HP2K&poWgkdVRXkvZQNL`Yd?Zx689_Mv zk+82JQ-uFjl3I&A+xi$#GD#}Iwe~beoOs?9a~0==@CTfk+kPXtgriUzcSIgR<5BaP zHsP(v+Mt<&Pr}=sBQY@m46NC#rmIL)??4*c+X*`EivL6X#?1yLc+#_@7UN5kv{tspUrUZ~s zVctzw6U|Yg;qtu_+b?z5+Z5sl{ZKaEYUWlnyx(#|jvX~?`TSq1{<}Dm_#3z{--KkU z(_RItxLQwm7kkiqC|( zUETx9>A$IC4SVO`J$xR!0io!gKUNLt0*Bl= zZQa-Z%?(CZP)R(ErpVMpE9f*^BAkTNP^1e+X%4nM^1vk&$h6QCp_l?-gU2ubl9nHE zIu2IH*@(90^-OC{zBhAEcbGWY7r#lDBekq}~K{Y(4 zJLvate+zicgf`Xc)x^7I{K&RH2Tl2-a6ky$!j(q%|CZBlQ0FB8ca7f2;Y{ zYK^V+LJ%Fn1bOG<&FDWJ?}_zyUl;1F4*iSuUljlD_y@s%i{-}i-yIHp_!p7?IC}p3 z_MF}FOyN}eiifs4-&m4xnvFkogScZpas(w~T|hJ|UHYEz%Xe%0rE>5%>~LOicQbIne>BXZM#>i4l z6NTCa9Fyz{FlStp`b{)o$^4)E%$ewYUwMsujqW8QJVb4vd8KodmkYvn=VDO{%n0+u zD-bm{X=`)BxfO$@iLOhgG2WBu7I!%);iuzMmGr}JOvTNIUL62802M{HhScNc%>Rj7g zrm~&7soq|^Mp|%}Y6tSP{on8sgFpx3iGSwYM&-C%$->`g?g($9TsDV>42yMi2xygL zL9fEms6}pz`6?42zva_c^IcEyNto1-<%S;(lDZnjy_`}%L)Xar$X6E#LJxRzZD%m+ zBD~|ml{i zP*!9gtM7@#6~$MBr9&6DbZ_DRH)q4ib~^*tPnzr|BPr?=ylHiHNW3EQfQ*khjhJZ@ zq*4Dty38kc>kM%Be2o&``bfe30#~+RDq;1u%fF@|4(1?TnSVzQ`$kBVb-n4;1@Ble zL#IFt*#o$LIh6$69}VO)20BIIKYP(duKXJWdcsWbrv~wid}|&ZvZi-Zm@ptAP6R(|0vN@8#R))jrooK)Eg<~dZJ~M> z2MM9KoEzup7+FP*31KZgSfb0(26rhRKE}=*|DrKvA?vvO%A4!f+7@+2dG;IR4Q%&A z$@KfnLC5f?kQY?LcgLP{0jwt*MzvlluX5NnmFS9S>eNZOF1ueqC>^QTS+EK#iwbW_ z3NbWb3NJXO_nS3DqeO2HqJEaykBxEbg#zWg_|F@r;n~YooW1@xEkmCg~*a($@wijRfmMe`OkbSCwe-YIF~ruE#TA= zP(05E3?=nQZyl=p*@VXye!yBMMy*aSv&jO4U%P@ns~+Si1#_GY&9N8Pq_3$A37k>M>3bz83t4@Pac zIw|v*GO_(_Jo|Ix6R1#m^QY#;TV;#vnu7PGH3f)OjWj~PK^+$|Dzc`eIcN+Q zv=jvB%L?s~x?`oKkcOn-IGq*1O-uk3<$OmAq;#PN+%^%hXo%0lVP56DnF_(t#M>et zNDLfk6=l}fR<=<(Wce}@bRnnD(a-v(Ro}RC4Cbd>iCqO1&2P{%fXZ9MVTN(xd7u81 zNXvXG`){nlrTd7Pr=>+C(?5Ek=4K`K99z8FPRqWtcT9XZUMN+P$G+31p{%?S;gOtP z-GHu+`VjZ1S0a!n1Lv%LDNqpKzbZa==1uA=*?%MJb1`u^I9ABv&;uzn%@q%~?Qp5X zfXBev!@Bu6z=an6vdx>4{_1YRb)Xgz?o1tjrdRJKUg6~I{oJQ>G=0~x`-C0SM36FN zp5#^JYPN))+mTa=rNHKHlFUiYbZ^qXDuo(-(Wn zUx{f5K3Bq-ykIvJu3#=l#d6VRO4?;C^W*=6y|)aCYx~-Lo5tPU8h3XME{(erJh;1U zoW|X)aR?G15S-vaL*q_xx1fQ@KE3zAGUGAT{)~l z`mT7IA87|=vg~Sgm6hOW6T+f{r3${rZq1b2_p6{o2`7pUtRCz^bn#L$)#;}wOFe~6 zWB%oY%;L&>Oe7fc$>}s*{^*cK_T~>&D;?<6iq5uxp5$AE6;xf1H-vo3kQvs56ake~ zf(f_=)UmLP&vWqE0ystQSK}>>ph6&|l{W(rcb%RDvh@+IYxHrre3rBss|APc#zbat zGtb@qlk2W{g^*UCU;4k z_VVk0#tfy)F4e;KjO=*l=6oK}1V!Abp8R70FCG}#+*#9|EwTmpFA_Y~{N5lD_#1#C zO{M#!O%!(s$-rqdq_~7*p~d%8l_V->i0;|iOk$>6N_ofWF|Gml%)Q!X_MFe7+M6{< zTqAmQM%wyq%L!bJ&y5ac?bnv;H&E?<%iY)-3pn`Yb8P=aeYWX`9W1X6fk&uJwJY-S z8h<~A;6*LFUmOuueL8>ibOkw z(3TYPQ*~reWPnMd$^Ya3NU{*mh#2*R51?%ZCBS*((5PpvjraB%@!2cgn^$TWQFYUq zAJ7xK5NyP(6ehA%+2|D*J~Dl&#hZL*)CDB|jO6WAgQZTvnAb!hL8b;$SCvrxQvFf= zisNuW3FYZgIYW1!QzF@)D)6BS8Y6a;WYynV zB@q#@M{hKukeaep5RD>_Y=O-~0aK}rE!jT}g6rJFbrL5QWqwBd(E4z&K<6yX5_0;% zSqGz+GOX-MLsfxZPJ+Sf^p=C06+e;;(`lz-=Dm_Cv3ceRI5!VYbmGZUDZrka;xmp= z8Q7I{F!&>i+b<8g=~iM(u;(Cf-&kom+imNHsO0I(;5&R>nyewSwC3g;T~Nuz7(B(a zDUr)^4IO4I1@iEsYbKS5#0o1{3@m@$vc`LnL|3ny&j2#66jP$dO>r~VqJfmOOP>nO z3P()_d`jCH(vYS;e?fSzv!i}y9pmGyw$a!$U7;2w0n)n5S*I>-O(9k?ji>D`-dBWX z&&phgp|Fpzm{?e8@(}OYxe^TMgS}R~v2?!|ulJU}bP$%jW&0t3#LboZaC%0Plz=ZT z(p=f{v5`}JIBrzo;`QxOVR}I17f^S7B1^y^+Rnw1itV!=dC!}T47r##VP(6Chrnk_ z>;NPw$D;#ypHPQYMB4GK$dL0i8_thkKM0=RtWuVRi8fpJ)Sk=bZ2;SiGq(Of?%8U> z%tBg&+68=K^BJKIDtsum&PfVjO{5%e18 z!Vt7;G!z_ZmQ$&|QHEX@CoysPO95dLu z#Z1MFQoMYnH*F&TJ|J70ol1}w9x8U>f30z7T(I2YZ{x+zpdL(K&!8UpJwAF8M zY(*d;eO4>CGhS#=u+_>`Z2YB>Jv+Cbt69UCTnp8#FR3^KEQ9pT|IO`4R#$c6Y& zU_<(`8zT$k&N?kd0!d6HIXx{Xv8f7jb;t02I5H*TG3fE$mN_}U3xpit2k&$t3A|#Q zZZ-3xMs;ExQXNN`>6a;#oy4yzZhKP~MYZGX*NgsX^>iPKvLnFZLoy>VJ+#U-;^Jmq zC5nKy&2WMZ$26~c!(aL;3KMvz=y$Jqb>7384T1Eog05LXN$}{}0SH~HL>Ee;X5Op8 z_*5j<^l49qBGUPe51MVLV+S zILmJcvH;sEnaYepbw;5dog{A4KbTQkCuz4t`Z{FC6g&ArY8#)~e(;kFWYFaiA}0FQ zZh$!jK5CT5Xltm+!_R(8WA3OAUncG<$+SYsM;ZtF$rbqj+&SWb-5|%9^F6+Gu<`G% zak`DG44X1|JKe%Iq#a<2xwYG!p6Ioj#D;3Wm@Md};LfzBMR9zL5qWg7Fp{LEJV<-ya@ZhYIO^VuNU%|tPFRg4 zOUUmI< z?p8OM*=ABmjpXOy3>?h0vyUAH=BZlD{`i_V7g#byijD_*Qg4Povw8!fXO2-fPS$b7 zO2V*hDNu*B9y;SxMG~_Lfd;^lmHr`OCSumJ6AkgWnoPCP_)G+w*Pwla_)FV!J$G8% zd7PyI-_wvQS92p>hBXD`!0T02r%~2wcb=-h8~LFU$CyY-VAouUKbWn>vD5uNC$hYOoWzvyi5v1l%ByB^AvrblDno}w}j)&(8FgZ~E)JVQ|#v4-71wPF)5DdZ1K_!VgBfj+fGVSam)kS5* zyA4lMzx#B8+bAzV2CkjQJp}V31NBluaOUXS@q(RM_h21 zW0vAIRmAXzD+|;nMa5~Wg06B_#+=^vZD!O87@P^pQ!Yr}vE@JcH=w;%-9;IF3l1@& zt{gN$k)5Z^HYQBcAYGDno}kSW?c2Q_I|o>7zng9eA!eu>e_>G~?I|VTEnA-PC+H*@ zDCNWLkXn4)k276lTFlj3lGb0H@c{jnMhLg?{(xe!ke1=W{;`p^X)k>i89HX6uVof= z!f~R6V4mh?nl53NdeG%XdW3Ta4FeC}zWko~u01Omb?%9D2afV6z5e~$CF%MB3ryQW zTF61^)GM-eE*GcT@cb}L7n*fgM~W8^A-Uhn#aXr7)AQ2Vpi)|{6&jS<;meEFGn7ak z+eGn0jO6j8C`SxByo4n&o4cy>8&W9fiV)caoYgD}ToTX%^%NsWW2NEveX22{_++{xv+>Vw) zG0am)j2N~9#hM}=C^69S{di6CklRj z2SY=P$054Bl+7Qh4XEot(eatKIy;W~8U{bnuP;d3uLa;O)2*Zy1*yrU=bH4MIDN20 z6P!!#eAHtFECGFe!1bK%n-q`q$K79t!=F4H&1$2k=Sw)GDjQW|z}4O_o)j`PDqL{= z!#gy=%mCxTXUu?GZ~q#I(__bFD$RP+{o~$aWqd&b@}Z0ue@0?WBPFT3$pl&)qHjmu zA)!b;S-{ok>w7X0aB@lgpf}ybZ_}7!kJY^-|F3y3W;~w3R8>A$>1;ON-o>EkA|(TI z-ug(w11(>%Da@2fmbd4c88WD*I_ziV;oVcL5#_tvD4ugi{m<^D&-|2osA7;ZT-D1h zz1S9Q`~4s1+Ldx*F{Y^g>`pb#&fL#VP?^jFHbV5Sre9#TK~m!$BJI>2TAu!o7R_Ni zzg^g$_fc9vjOt#wrIZy3mFdq+*w{*~+6WO@#(&W52YP{03LsNMAy`c82QfwoQTO#Qm zIbc^j3)aYyaaD6A$8pmz1@gmhn`jmN=5^9S)u33Hf_KYQU3+#n*$g&92kmwwjIt4NNR-y9Zr+L4 z>xfHss0}sH%*$0#gRk-0o`+_urS7_X=+8rurV}PL5_Tzur|O%s9)>S(e(D7aXtbGv zG?PPA<`>xhmtSY_Tx$eQvRRG9knH64us?QXwF*b+xd=j;_}58a?g}L1jt#FX;~yrj z*nK>V4$6VjdPY1XlE?d-z+1r4zf@972(QJm!EECoz-(`2_j{!f-8j# zmxoX~*HJOr1}%K_iRkvV9?Ff+PPJEpR$Z!?UXEvpTot;b8YP>iex4c(5(X*w#4D#VuA`RUXp|tSxE=>Z}M}}oQ_Ga0uveV1dKUfK1 z^F-7$OLV%O9`lT;#Yjc(WhP-Qq@VQprVmzeb!ny1d>W`Xi8Bl(5YP2u&VM_`W=gq_ ze@BF}1@Mm*pZW$^Fo5t>F zfleQ!U5kVjW~&-L4(13)gL2U{i2$-18N#wTEs`s(@4B(QTbh+S$BF_NiOZI#u*)@X zH}X%5V+!PDC>B}@$60+NsmWfKR-q5}wzno0)D7KTahAok}OloqNvkNSkzxBuE z2gbLo7~4tnOhjr4CpfpFF@DER(&N&f;R{gbmwUeO$yX!xO-;lFhzY~Wr3aokFwck6 zq{XWBJysvKOIGJHK-AsqGsf@srePQV#cx~HXkeK`66Lzhq{L&&hV3_RsS_D$XP#=p z%>w1tW7~z+n2y-FjuHLQPbp`yvVQr%B|qH#N6jpK&HJC$-!;%3UEoH|TWVh22rFhmzLA9B{v86+^$)~Gopt?pRF2YZ zGF4e@Sk3zT5{wbxNfMmL3E}TQpk@F}mQy@4Cr4uqIv-Hav7LZxhDu7|$Q8p<{o>W? zWx-{MGt=-oRuYA}x~{mg^PgpaNP4BgJ%XVs%wJ{<<+}`bQOo9Ne^sG5N)FyOvplV6 zCfoFX?xdx-nIS<0bA4-(=|hT{hYe-}i4fkk{;%+hjaX-26`GH)hTbsC>cQYtymweQ z^8?0HSM5b6FjuR>jTRm*E$j)T)fVr?ZSgQjRTsxNLe0V9-awrnZo0L;;t0+450 zir8$DBS1)(i?QmZ;H>HoLFdI=LqSI@ymZD{w;9GqR4LVvpOSlouK87{W#!!1v@ok8 z=4#`as!6$H0MYiD3Nz72pV9nm`ZU^LO1#7VK#&X;@?rfkpO#|kM z7E5bd&1uu`Fkb3$NRNWCRq!ye7;H1`0Y}F9f>{eu=M45SDQK9`X;U}z?X~h00P`%L z30eAGe(Fcr`U+mk9o7{iD8D30Ejg+u9*K1l;jVgk%^O2%S&9w)e4*j*Lba?g9Z5L#JyK`vT)IB-EtSTLQ?UrH?0HRH!4s1{KqaiD@?` zw}B-0(xg8df=cLKL^v^Kc$ZZ}xpo~#e3X{chU~p4Qrc7xqYd8^%zehyJQBytpGn$I ziwiu~Cz(fL7gt7^ht z;n{rjBa)NqWNvSes!lrTTQRifYL~HUiO_u;;C9_K_hl=^7R8pyzCV&?X&oqDM6kj^ zPsY0p9o?~oe+-}8UyAO!QC3|3&fS z)8`!6Xshm!G2(oe#TZ#`M&Bv|MY+Mofp;a^%Wwq6t!8%SKkIYoUjn3;aFe~Jj_3|b zyN#T5U$ni*Y6K+5#)OFqv+pq@vT4rSvie`V3`1%ZUN8y0<;F-nUq`EoygnPfCnJld zst-!$Env=xWRo*~eq5}bithHNiF6QBq|~3e__v%N>d%^5Ca_TeKY@+u5GAj@sB4xk zuDu9Yx1!uGk=w`q8TBGhY&WMXeNa1<(*OP8N9l1chi3v)Y=mNF@8>bNSkcODAkbnw zU9o&6Z7+FBrU?cr>JBC2I~&bA6M#7~>R=}iXA4a-d|`1O=Fs<2QLQ=_EVH}lsbKs@ zTcNz%U|g@n4bl3@M2}j>&i#Jdh$A3o^Eld5DK|R-nb^X9@FJX-Wth{Jtl2q*nM()1 zr_7!r5${pUmR3hEo=upkqfi$K(IzRp=PUG*etu|Oq1-It)pJR~jlEP(e7pm5g-5hr zmKBZBdJAdnTjU2lUQULITsQe)0r8xSKKWMN0!vlF1mhC(C6>T`tOY&-uh>}Tjmlh@;$U}PB4Fw$`#cPx2Aqt~;#;vp_Oa5#(-(3KNim)Mz}vR5yi zf%_iubOj!C{q1oM!Wa%%5dno`)NDPy%aECN)to!)>WeK<=cN)~{}0V`z;?`UrXt;2 zA@>QK>r6MJ{^~ign`~a}EcGpLLY$sG!bWr#Te4XaGCgT+F-I4ykl7uX#YJwH`PLP|pE%DZMf=Uc* z@<}jXE03J2mI%O10vfrVZtl%+IPTGM748;|1p_A)NY|YF7kGLsH{rFnjf1B$&2b zKiG+j54?CW5ips6`24*P>O@xidU2pi&?ZI{oGBI~jFf?iL^&oNy}~oVip)&CL~$I` zGwJ*aKX}MsNR?h>n1a6w#G3+Gx>E_#71w>sQbAY5WBmMv)*nJF3pv z=)~%90n-5G$|+Tc>Ek==Wt9Ujm%93y$Pr}ICmcxHy{xYtk^pAp9_r^hyx^_nV9NIn zlxW3WZlpsTy|QOs%F%txk+5WkwIR@Go81-9TZ#JiL+ca7y==Ix^MXnI%r0@h#di+p1_ z95)cX$Xm@zz1(Owut*uo*eL5gr%xHrT4J|o>rHjl}#>Abs zk~khqj^*0~Yscts%d#$=n7J7E3fk?QiBC``@&_(T>3pzH%v24lP+4Q?nhwUQFN+#- zwf~ITHhfBkJi66%t`hR$g8RbI&$;3t3L^=ty2c{2VqQ_>d{hAucxhVH@EMhy)BRTd zE1L;lvA!Lf@M=sf)Le;vt$pX-sPhO^L2aXc4*RLbTD5M>Q|(fhnY))TXXd54qk)DP z`pV8z%V2k@gg->x(u0EFCBi;K^!d8BvA4-x&yvG;Gb`gtvt`&y35fzg3y+L{MNV#X z8@|G=Owlz4%j^eIv|DO3O|8Ktas zc41d>WML7fJJ>{3Jpd629n}3P^&4}+>h!O`e?(}Ac^$zY<(VrkOavSYpT2w-og0t) zxRg267ipDjLN6|?w=+hXWHxip3jHZU%Y5P_BS=Z_+7-DK7xR_#FHJz~`6uYGXC1X5 z!V_{y{gR98a;p{fGHZ{_pIf*X1moAp;*UO{3-o~%_~j9c*98mrMjc-HE4#&nr>s=E zI&T}q;U)IZ+^!IHV~$BWYxcN@6;hRCMMNxU9&Mq?Q2AhjWz4K#ahi!O21Z7LK(ID; zxadZ=QFv@6q{OjxI&z~$;JiRMEfeFC$qar%zI`|ZrOh4736Y_X@KC?g#w=(KT0bQ_ zA!=E~q|vaqnV=VY;AafL122vzTBQyPr|X&|MA`lkgzK~8|5J|m%&nY|ZO_D1R6qm{ zyDCVq2OCYn0Eoxg_!`-O%V=XO({%zA5@Sre70$nqLwI#$MWQ|dT-3>(2v~PfkS6e2 zD$?Z^f7RJOAzaCp{|%@wlL=l*bLRu8f0cuCUUmXBAV6yf!G?#ko4x`WJ7ysEvWeMe zfMjiqnq|?p6GrK>wYl0;w5DfppCsTKP~litTgb>sOdj zsJLB1tJ3mBR+x)IH-VQZAZmI~WcLAt+7jLOULG47tZHulK9w z?3?;$C@v{+!#;h_^-GbE->JCu9Fc5g3V6Ur|BDw)BCJcNBATS=lO;xB`p{R$sMCd? z&V~J0i_UhO%Amx~1hE=kwTW0t{M;2uu!kp?O$#hgeZ>3&mZ@Xfal1Yft{lK>lW2n| z4Izl~k3=M1C-`y`0T1<;eshS=seCak^v|1YvjkVpGM{Oip)7J#T#+*EWie28T=HIy zY~+wpyzugv&TOXUuk#=F%q}RGn16x(lm#v3JHz_%&0Gg|c*$ zqc%!_RH($B&!)Z;Pe8bi%uz^`LPF@zcr)}4oo+XPX_${#7_20}MyQ5nY=~Yj7bM>A zs!?6XKEl;6ch6z>eb|#+f)`9rzDuI7z8)cl^{K90Mf8!#s7~0>dBV(A@Wt|}j;x$F zeVb8y3c9-W*`eka{?Q0pIqXZ~ll^;v7~@o^Dx(s8tUsz0WV^baS5JCM;A^gQI`w9G zgb}@VsSK0c*Renoc`T8{Gg2ub6;7nWD{$g}_)pPEmQ}MD3l*%!_U=NC->11EtkjUt zK@jy?rXt5kQ@aWciMC+e4p!wc=u25ggP(l#$b@^As$bU|Lt1;48`};u?J z4I4ohR&@!fK|2Dly?OV>x1v3iQDa8OT7Bpfwg$P0kLW_*?Y97WwG5kOro35FKp*dV z90laj8^T4Nx8Fo^sM&!{KOM!p-yL`UthJIo$vhc%hvXM; zT0}2AAuO)0($1q?Fg|ie>}HB20`M|O#7;)A7f5eh0p>Y6P83{!euncLzVMf zi4nhe*Cj9~8uC^-zJ+?TiOIzt1B(v6Ol*7%R?Dzvx>f|e{w=AB9_j=Iy87y7%p*d>IndqqG~!G=`J9*#5o?M% zk8{Y7p3O-OC4@aA_na8dy1yRnBCpL&2JPcmh#(Fl_Mkdm0@6CVmiL}=chzHN6fI{_ zJ;9{zXGV)m%BYllC37~hTy>lPbFGS%+2GH)Rrl zs;fA6t9v!Ky<@l4w3AU3P;HU&GrG}rr2SM$bYK>$a*IFKcyl+ykO>u;VlmF?e)DCR z#g<1n=i{;Hm*phRsPvN~m8f}@ATZ8kr)i$xypPcXXtvKo)KJ##zZofwALBndpT@{hKLvC z$;3HLvGjx8Y7>($C~+T+eP=SpT7qdRaOw@c2hL$WT8sAgGn9I%3~u91#Ww2fSA%;a z5@|;djS7i|zX5pglI6&MDiWrU6`@m|4YL#ZidHY(6B#338xJiH;g2cE2&z<@@J z`dcjw7+RO)y?ThQh1e?w!`8M326Rk&2y zHh2n?pW9LB@r3U%X-)J_OGC!0Pv5!x`Gt@>`&}q(ILuEXLxYjYS4Bg0eb=~GI14qz zM|)j!WkQIkm+<=shjZ=ZkR+VC3h1XN#PepkE3TWW{5yg4Q8g5DQRY=NP7RJ$Tq(!= z=ihkWiiSrlU-WvZol48h|D0gD0q5HA?#ri-GpOg@mkX?ZQ*%UmE2rrC0Yg<}r)5tF zxy;awc1o8u>Fv$B1#BY`IffN7AMNH{#J4EjHT?C&NEzBI`fYPrhoDA zgVmV&llIWab|KS}OT~wIBXR`itF5+eO0u5)*vHC8j0aq8D`K&`L8}c47Pj(0KBMn2 zp3YSrfitFYK%DAk?4>9XJhMxq-|4&ei3@+@E!8JrcV*rX7Q%40r&0eRbuTv=Fge+l zbJ*v}ILrlcQ3Te5R991BzEz@XxtaPbR)hO3kt7FmA}$#o;~JxX1K6Jr23Ds~Wb0~z zT1)DGo3h!cSz~DbFiCNQ))sE%7Olw=(c3A5HgCh*`Z9=yzu8FU`dgW^lN6Jgh~$yV zd2xNvHQ>PvYc4;(P>Qm&U^lg|YSGRC7W$hF+~xTNesCz3QOuBk5H#0Q58vi(qU1pE zL`HRrjqWCG6=t`w`)g0JeL$}vVjSQv%A7^_&%uvq?a;4d9QW%)twxy$~E^sf>q%e``K_WocV!9$4!V zM(p1#Ctd^foB^oj=W!!i&|>0%7g7dO@@5gXsicX}dNt155F*clAoWEk*{YkZLHlwd zK4W!Kdn&_s^lEJBDb*3J{uX5MHKwssWh&{oIJi)myyEKY6moIK+>P=r`Z4D)!7*Pn zifb6X-Z_4zmTdEeCeq7VkKV}mHyC0gStrZ%%jlyuuf!N)R~YNO&K`t1Vo;*>1H3J$ z+tBbyp*>0CUH|l~^@3>4jBR`i_fEA-1=3xU@1sP=g?>GBpwkk!Ptl_)OrM5dPkuTI zW#-n(5oFRS%4Kr|Ov}euLxgc)a0&}+(ha@CM$7cnpAode$z;&YkF2^@5pvzOv2!ep zS0=_(&V?cg(uuG*R1Gg(J7q-$*;~JhP^cQT2u)fEM}{Z3`_vM`-^@2ygK?SO)KWLv z23|I14S)420z?idKEw-I>r1IxU+#K{enDwl2<8Y{a>*@$T}GV#4H*6RF-99Xj$TI6 zBnVxXH8I+;lVm%lP_f3Q|6FjGP-`Zdd~6VpF7torQ*qui3C{lIi$u>~TM37%{k5QA z5|@z-L?dUVK*v!l=W|AwH1)Bt!uL6?nFUYURXaaMDAW~zTXdv~WHhsk^@eX8)pYzi zG(K9c9f;_g5hpo_^99=;AfZp;owJPy(Z7c%)vM%`GY3+r&^wQh(4A`Url^sZ%kTwy zkT!N;1nfrZ_%#-^YlPTFQ29cEiXcRTR@D%N5kk2o7v#EARsgy|3xb~+LT;OXV}=(} z%N3`*2~aA(b%kw$)cX|{yKvG;zjR;1x`$W26ntlyWc5ij#tR#ZLJ*&BeIXpTftI+hz zB5jZ48HP8Bgxif9lSI3{ECUg&o7lh*GRIopMekLPbc#91V&$Zko?=UEWo;q1Z-T9w z1u0xiPf6qzH+}duErV?h@>ODWc&lIzG;gdJ>JY*`fpDyPtD3p!Nqw8Et?#*FeXUmq zu&Z7q%T83#G~_Cy*1yyJL%E)*D@G-H0qhYllGi-`HI&JphcnvVFp262s={bOe#QEB ze(9#d<%EMh9A`F_8*xw$;H9G%XDY>E#$0&~zQ;(A!|TuF6J;dYf?k%Bs=(p>yYG0Z zWAUe82~CW`&erkt^6RBI&x*Vg?xk?;T|<*KONOm&^Pq4|3R<9h)$;pD3gTE=+cCjH zfm(sBn%tSfw*pe^J7FVVLT2qO>q(BxA4av7gX+wl8; zd~P{Mn@Lnw0EZTGHjTzAy)B)li2Y2oXni>WU8O0fqt%otv0`Gx1gR~)0-|q(a{Trr z#O+!cDThE+D+Gwx2#sh_u5{LXN=Po-E-XHx-~NE$8`qq57ec&Cz;$v^~Dqw1%VNX z`JUWrfr&U&?MG42al8FF421)SVk}h(wR{(jodV8c2g7phULV7~nrMCF)9t>L>-*M7W&s_3o)wfO^{e==kdp|7&-?q%Ewu;5%)qFMq zcef}5D|(ZzWKB*X*f3LHxd_hC0g1-u5pvUs4%Vu-22z7zL?bqhrx*3gbCy;@#k@r? zHQSgJRKXrvd#W*~j0AGGReXVCyc{kzNxk{}wtsm4p;rChxlaG*e5gN&?C|vnZpCar zazBDknd&v{>O70pOG2hZO%{I=&E$+M%9&KPaL9uh%>@%mD@I1fmK!JVEnanFs5Ga4 z>ixxSPFz&B1^>eQAAJw36z=>!lWG`sq`hI4%wZy2@y|_omJqG5UZrV8!U7<*bvia- z;UDHV;>+ZO(uk4_;&DAq$V`wc#A4yrl&dP*4QYsqgr?$4>bdFR8lpU?nx*^Vy<7LI zljsW*Wmj-RTqmZ%>XY{^2~SztqStP&yxg1IA8vaS)T~f@Qd|Zucl!Y;{;g(c}kv0Cqew~gu>KT_*n(5HSs1%{XJaOf%gFjKFFM7E#a120n zV*^kfa*c7rz=9KyJmJ~?YJml}2R=7F{pYtllJyMQ0yN0kO$gOXR)9#>wj_oa9}6fL z;}UgteK-&~w8j{XKTbC?$>2F~lms-LYix`;AhClyzs_y(ED5G(Q)-kwNU)^=Zs7|h z(bD0SQS)Rkcso)6fMnva-l)(3!3dqqXS--kT|=f0(KR1|Ms&Dr!Z`*V76vR_*Cr$r zAS@RL=g%}DQS1Ie4ysoz*)A3iVTj@+- zaYr(K4tDwe?L3Vgl@EsM8%(2=CY#T+AW9&U6pt*CucavUjlXdA7vFl{Py$sm>WA`R zfIR1;M$Vc54_CyPx}Z`nvyh%?s#1b>iGpN~-(bZ%6@eYLA|-|1RTL&Wv@=yJFRNo!&6;aay@jp%Ei$B)WPHbwF7~E9S}FQI;Nj~S+h=FgslNf$ zQu9MJL4d1^hVNT^KpPreLEQDHE$H zrbQb&Z&fDpM=kAI{VN$x@m9Fou=c7xp`U9>(nAJ|rAZG*LrFeTD z=g`I^RWPJA7j3D-a_w#5PvQO63>&!%N*`+utCc!bytnj0zcI{~cowz#3WUuqlqBl= z&+ZzL+v6SZMcEmdJug{%enTTpjj6 z)g_LjG36`_gbu5n@B~40hY#+eWl?=d3L)kSBX)i4skeRzn4 zLF!qlGomX|9zt~06jf%YaPdZ|bM{a%#p}EgeSBtL#y2@me|IHn01@DitT||-51xIW zR+9aD3F*~(cKubfF@kBh+b%hx7-teiTL$y}8iw&3@?PZhEgt_SmcIcCpb%XtGTvZX zot;QQ{whw3x$5n^ExbeE85sj9ProB7WYCZ~ps7%77so6GG=Z^;U;nx1UFB14;a_g& zpRLBQ^M}tJ*1CP|4ds)WQ!TrXMK2R`+DeK`qqX!f9dNB(uJuyxktu?kZ~eWAe$BZc zNgST*<1t>4=9~5gO04UjI0?;zs?C04I~jiiP_0T}ACb+_ zxw$k?Fi}jvY}V;pE~a~Iapt4xcl#*Zt7U6MKjlt}PHC{#Yb@=z|4gwHIGc_r*E?C| zCR=~wo%va@IWr&S!;PHIt*&l?K&lj10)X$|)xZ$z(Dh_XGV{V1PeC+XE>Ui2{4PAn zCDuz7A$7YK6a+ET@hyPqRHvvqGSHBrXtF!ZOp2a;8@s3~uBQM2$-KEXAG5@Xaly@0 zwzH5aDz4JJLp>@@Sh?<=eL~lxA^VR$&Fhs8cXk}h(?1h3H!CXL)!yAIY4L^JZ?x(X1z{2tp%yx&Bi=B(|vSwjor0Pc@s2e$LYbUkQJLPBa_v}f)lU4 zxFooh!8|`aC^LU>IkIWmn<-c?(U`n3cx1!jXL(?FE`4_5OXpYe1Akq90cUm*$;U*e zCLy7#O9XQib6&C+57SDk@LWG6kXKHH)C-Tdja7gkQ1O@L{Q8T0} z5p&4|_~iV9W6Ie@40?X>m~`+2qJ?AwWhoTs&LUwXPV@38tac1Cc7}A$kc)<0_W@tj zCL{_*20MSHgKzN+n}ZC*6Hg0A^3NXSCJ$Q{D;F1o3zuIO>?L5)UDcTx>m;XVFHCa8 z#g1=Uk6~BC*qs9qEzdtGXY-M`#+b7-C~k5ueT`HW!oa}G+E4ZIn_R@*}V`!w&0S+V9%Np&h{R7$Bc_WWetiz zSTKO`8N+>|zi`eeFEhJmstnvrt=!JXRk-^h&1_d7 zFDQZ&@km~x%I*dWA2w)Qmm`bB_t3I=h4GH;5f)8Ha5aQnKe^jupV8VX!bwS%<8b8E-KfPU7+p61EeGH`7G^v<)X}nQvU>fm0SxHv+iSESY z%9gs+4t-BYg)a_!)vD7bXeh1(=>Eu!faYBce$+B*?--kHXH9m!z70{?PA=KE%d2 zWeJj=qnvRic&wwzIvPta@L2o6VH!E`)4*$xTlw?PXn2#gFTq5W>XohHTC=6r8w$v=qyF?5gAB(=S@Qq%8reY#g zeUbtWE)6A8@x`t1yXH(h-J*@bOO!yqk$;1@!`ZPe$bXb|gd_bjQ6yveA>F>`N+a&T zmNLx2`G7fHO>aA?CSBG!g0)o6^81RQ?&$Zv=g7{kQ-a3D+J)M|77ZlrczOvs!bq6xMqX!_3*M<@SeBuOY2i3fb1J*GEuy}KgTW{12NO8Q`yQvrPL2v| zGv@yOp;_m1@;?{Z&xu!`H1o?$WAbJDWOZVSz5J8cgz6cWCqtBZ30?+}Z#o;hc1an& z{Z~rNg^m2Bs(zBvi&zg5Xq2xYQ&soRbwGp_mJbKU^7;!$3m*!gadG0v|_o% z-3g`ALz+NN%T@&9^eOz``6fil+6H3saIgXE5JIUaE#wRPpF7HbXu)Z*SqglaQBLgpMB&mL@PwhjahpR$K7A`{) zWD~b8?R}lPN?Qp|69Q5;R899t!#-Ypf`Z*sqcB3MTzc8M1!oYogDrV)!9+@%%ZiE= zWx;;xobIES<^1Ch8LAyST`q1&CLs#?09&qHuqSF#MWAq*Y2%m^bBZ{=lnvj#BOct- zG$JT#sqWcQ`#$UNHq%Tn4J;jzv+{1H=8Kc6Jwvs;x6f#LUl-;FTOLvop~9z?%0QpW z?Fsz=LKd{!deH=jTe_VBpi+ zUlJv7%jCxZ$bdsI5c@@+?uDHQ66uFs%a6g+|JOnzvHRR{p3gAFa6!z#_^dORCl1)Q zxEg;fLB?dRvCs31&tH|pzNYokVzAOwQkxecuA83@dKzg+8f(!zB@4|pGSkV;;gM;YWSgJ_(2Q~r*_v8#OY_1^Xk8uS&Vw~<{`As>XqZ1C!a_B!S_pk zo~6x{Uq5_QSACOoHRp7c{nKyZsjuYT51zg+399tw2%2#v85|~){r*zGC$}PT?n%vy z6)WEKf}xw0x~ZA$^pC-hs5~>NtX~!-1lsc4{4g)K`A$h$=qA!IZnn|qGFeS|xRLs+ zB&mYf_f6++P-#4`K4XlJ`LTC*_R8%r7JFm2lJNXDPhyz^n@7BNly6ms7+lr#+ST|2&kq z{mv^6vi8Df3)%PnxlD;@YT=~@Zvrlyr{Xl^^&l0)gDjreOM#a3y3gNT*zvZ!_qw&9 zJYJ4FSJ#2BPHN_SZjHB4$Fe6!QH?`ay`*q*$t`bTKeSagFOG3O{k*^YPk`V=lzkEY_EMm^}{IrVH zqj+S-pbuhlc}P;oz&LVso%MMVV}>xIko@BW`6r}XC5PuAlj^pcW{?LA4U?e6OLtGE3h-7h>nC-J^8e~1vEZ)@&X zCY7n;-e^z;eVrHo@@G}UDJc$0ovu5%>8F1MQQk8{dd;i}=$(~@U78#Sg|O#E>swoI zdZ;TT5x&8dT_Pzq?I&(O4YR62Rxv4uok`tE;K@^2S>~05tK8Per9Jfn*zEoF*ylSj zV4JOYQH$&V_zQw6ox(v-Q#WPFr9l#ih)8pL-;nl$=Wa45eySvpO;<%c;b zj?y_7o5Jsp#)O~oDNe|hB?~wN-R5w<9Oy4TPdVd$X=WpOTi6`~WHZ0YwWT6H&EM*> z1l^*|y!-3wtVTs=!n{&iT0i3;*gj#9bdYCID=RVM$H=DTy#GktgDy6zbgK-9?w$9N z9CK}5@0e~p{wikr{_TgF!G}*P>Fh{n&))eZQO0{e2H3Y+(se6lE{-mX-{1a!>43(C@8IfQJ8~5}^U>Yc{h`6$gPlZ{adZpA zA&Bb06tiuz@kFdvEc*ZQu0zm0ImX<}@$$M##-*$YUziR-hCu5(zE;??@lZ`e7yXL* z1e0*T{uS9<*EXsNyhr_fF#P3aAyI}+S6T@ zJmLy(;Kmy0G@iD9ee_l)ns?3d0}s6a5lR&K=fLr}-3+ov@bOsBR_ zk5$jlDDin#E5z)goz%f9Qvc8yns0^cVEi&nJ?{Q;?wVWZ{EKmrYg;1cO$W%+qP$Jo z(Zb7ojo6vchaUsekuRAoSAH1re1KWXM)MP+D0h{EJF6{ep2c^|(zwNcd#YgmLc3b8 z%3b?yE%i#um-2K%0fOJz_I?+C>#NpR{-jUiMvXC}F0^+luHt0}ToTQ7C`3ogM87FG zAe%QfGa3aI&P*>iN>XyNn@?+h>!nb@CB(1DP(&o{*Ni)I`q@wE;g`@_5OMGB0B_IP zilF=&^FBXk@*dgd9BTQmnMr9?qRE8pLVL{Xp&%J!Rc@TYFlXgsacyTJywbO#LeOpV zcExLa84B~l;(mg)FnCUPuIbbuwsUxqe|o%jD}jHKJgbW!6u2h_nDg%kjy9^4^>Cq? zICJH!LWlm%E#^7#?!|s0kuyfMYx42XRYw01e(Z$+ut3t zUzL5L8-70UX(`Y??MBp zDla9a6f+afAZhg^uUdw0-lvQ*idS){k5omT^| zKG+ufyq@-;D|5$ss!~5ltJ?2mWwze+6wG|;Z5-X0i|SAIrcjRYh)-uiYt{O7Amnhu zoP8{cRFpj&ci9EwBOYbFQJZBTq?3NzI0XFyCyTUl5!}!7p79Hd9E0OQf%z+nrNS}Q zG~e-=i%y7L)KtjJ^EdYS>xY#JGcTW&b~pqzmBN?gLxnysCt`>8n@%%3ZBm-~U)_gl zogP*b)jImjWBGcpuC5TeL6?&}5sh^rU~^70s(5iL2{?+*8tdw+yScoZD&wem=21q- zmfKaP#3v-WJY!9+gjXUSEzR@2d{waF&U3ZFaArVwU^4D%;jK>{Bb6gnF^+hK^lt;s z)sa+__wC*?FWIzy9Nc#Q%K@!^JN@WQDo)?CIU_sUo!Ki`a)Adk{q>7N-~g`U>!Wu> zrF0#f5u9`mD1eg$(J9+Vidyz%g`3G?MkX*8|o5sPfp!Ys$A^fg(&CL_>rQuA!nu9`gju2=NbW0*beMu%ul0jBf;j=VDK(LcdcL z3{^lp5Y5SlZfB~C#8_9tc~h#oUSBT2eBMfbBg((I>y=O!Z7~3ZYM73%u^*2;ej$5Xj7Sz`o@b1A-k36aM24`(RVJ?w(2Pu{ST+#^jF7h z3QPiPEi6uIwuR~nyt|*Y8#Sg@p zPH{5}39FF(3dHF7?in{b$&Sy>smvLgl`M65o|DX!ZHtfiP1;6N>?PPJry0?=={GX1-Y1!YRu$9->?$U9PTRBa%jpq-dQ zkXv@?y{RtUQmK}D_D#0eL%Jb+PU(V9(C@;oC*Klo1<5p5pm%C!F2+1r$*TBaN^(Z> z8Dn6iv)G3B@0*W;Mzx(i+D_4oAA%kl9K0^bWMs^O_sX~Ql<8R&c5FCgN5*8CZM3-6 z->%TEbCKg|hQ%2iNy0aKL9D{%06;^&NDczb_TCzm0b+XsDYnLGit=SP*8rF-{&A zP(uG9O(n3kwXxWssh8k+hOt)^A6sjs zN4;(DO_P6DnCzMC{5f^`oDW#-uEyyvUw(Bvu5w)Jn3qi+DFa(>reDWuLQN6y-hOD! zixGeQrw`u{UT73oj{JtqTMMf{TVdJ2wlM6(+Lz7JsBvD077AC5dim(;C9WoNiOMFT z?_?*7nAI)2!A4pSNb{V~xn@l;rw7drHW>Lh%N(-_oRG?P-K7=j#>he;bo_n*b*c?v z_wKGm1OxO=rZ9Wjel$gh^Ny|IFVD$V`>{8{EDAr`WN*);4lO8BdDkp)##!YUuAv^D zd8k;5{;}n9C6R>Fqq#4B39Y`U>^vO5TUAIdP%8d_fM~jsecml4HA-zmcX&#q8i$VN z+Yp?y%L-o-jQ`a3$sh3)os)&nl4P;jS!E8a+xJ#{Szd$E&IlILSulbt(Le6=^c9?G zVPkL@O)OnD^XKKr4R=~w8f>1srh`)?V;JA;y726VUzRDqpPlR?J|p9|EK2da#TX&H zwOIYTQ!~Fwj=}PdL;T%$c13u~Tg`-7dwk^2K$e}AnUAimC!LUbhv;>2|00|l6Q=jy zC5ugkd5aXQU$ZamX(FI_>{3aooMb-*y4^{0bS)HVB7GL;WEUsMVBpuOJhk5VBEd?r z2!rl<7+q@HLh}TQMIjUfcja)}8T}$$r0)snWJ6E&R$qhsT(`MJ_qL-IFk{n!+vQ|1 zaG4V|b^e}fRRe3=#kdsx9_t(2=t&LcB9~gv8#v!L;mAu%IR992h0NJ1`$T6V$75do zF`*2Vd+@x;l5hyZP#+2Sj%fZkxapK4HdzxMIaeM5=cILFLhpojYN;Cj(ZzF&<}yos zXQ0|AaZ&C=kQCsTqA)cMkersIU(fqZT73*#)Re*oqQVw?rxTMYEw`!bC){dM?+lM& zxw|pUJPzM0Qv+k?e$;|l+_nl|=VXulrHB{59o6$7VV1uhvXaT<)*|(S zwPRUofB#6!qZ|IZ`nWZgim!GqZ3e(8XvHfT%Z%vY%DD@xk<4)%XP2m}gA^m$bIf!W z9N_Hl`=Rn1*`IE%ys(^%>iSA0s$~z(qPlhmvX-Y&jYDocftZ|(-P=-T+C7Q5+FAyQ z+(Mm-3#@CWSNDnd_vz_(els1}S8bbuXk%|d-=s`CQsH~&*Wv;Xoc1JztX#ex`qT0b`ScdeU4+1hCXx3)?1laNWn?Y_i;6q-2_efrRHdt%Zl77dY{{%&IYoRnQ z%kz@_>X-7TDmpB%)LycQ^V8+s=4AD_R3+Zb?LXcrQzB>~9-r;qQ%0l3>?wGnJDo&+ zLT@Ley(bm!Ryiy(tk!m!z~a`BW!^H~8|${cak3sy%n)@>s=BLd7X@$k^&L;rYK|r- zF?=xr!nd13`e`TmAjY?(QUu|9mSg01U8xMR{-tBOE0^#+F0XoAUgRR;iDwia4D?AEN=!vcYTi|u@@?Rl5CD_?u1mk=(D_}RJ13&I*2>czwvaB zhF>XR1>)yto3-9KfUzdi9aXBG%2v-0@Z?sqFPuihot;4Wk;36A7jVsBC{sTRnc9?9 zb)pi7nZXj$WGOD~#@1-5qSpb!{SY2iyIQm)`3Ss zKI10+-m$k7x1sKMBkjnOM|nj2q{b#Ef7y#L*D))&vumV$lMo{jDBBeq76Za4B5*U? zp!}n+MY@WUp#axD2Abm}Yb=X$hp^d3Ysq-$8T3M2Ni^w$W<8MiaRn%<@+!1nqfU+q z7$v5c33lLgEjiU>hPqGtSXh97z%&qKz2?%C3H{;?~)mGn3o4O8jRS{h@FL1QT%A@WGk683h- zwPZ@hbGT6d6E#9`otc`C=De(&TT)I}I5DJJMSWh5BJW5?meL_=I)#s%_ZB7Kmvr>56n2E|;&l`+)^X3KUEH|7U=L>5?n!<8tBzP*e&Ww+DLkwm`f`a+fA znAoDVUD>Y5V{E|1rhVn!`rdb7Pf+{sk;}uIs_Us3T6T-dyq`qX-LPr|0ynXHv&LZc z`W>({p4UaGiw7M#(pvF+n*p9bhnl_`=d__)vWx5eaqC=aqIKz9gZ@l7OEvPl$Q6j_ z7R$?sA^iaou+c$?^EUh|#E*Ns;l0mJk!bSzsx33M2u{gsO6c0Da}A0e3c{Muyv}BD zaD|%E;w&EH0@zq6JSTs@^9W}2Rm;r?m*7?tQ>1Zg&x;E7ASPE~pj}iINn(Mu+;WCv z%~FHJFKAWO#tUONzf1d=($J9+hZq#EDKXah2(5DPf6%T%txaQI`YzXx>ie7_`(8e8 z!$43H+1*nIgcYNx8Q$AfN*F_NeP!W9q+*f$gUBj`E4c-iC}wfZUrGx(i0KEPV_|TP zVQxMI;n3HX_%<`&rqbC)xEXmD`gMLxF@b16Ry=>%3vR?g&V8DFhqwqSG{I9>iX7yP zRS5Cou#ocq9MamI5^1HReZQ;unWCxlV9NLL08iA)w$QNzs|>ghaN`o&{ejNTLy+KE zb9&)0NmE=WSnuyqaeL}+itfi6RxoT>6OfRLxe*xKLy+l4=IX#>ze3b+h-!iu?UB?z zs|hU8MtTvO6Ty-50+D9!n@1JSp9brSD+xm>plsjGNqNDja*#Pz@3@nZ|&)qJdAszn@3$An-p=%*ke-E6_HbnBsk8LyWU}XS27cmfjYIYfje`H& za_iGo_>q;v-XRokDUgmHg3iq~*gH6DY$2|_t@A6lPO98H^0|hqZc+)gYEq@#0#-M1uG=qH&C#`r53`$I{Z_>JgEWWdk&q znC3+PIh51pdx~4VwM#57kwX1?owWjwm9PmwJ3Z!P& zxGuF1-p&wmR$t)QH)6?5#D|@-opp>WIbNo_#%NVy_D!B@C3^nBG5LHV?45HL`Cz%& zmKsSqG0ngCmq80QO2V&P+1K@!pb2IWL+igU7XiP&y8*&AV6s^3ZHj zV|#v5zH-yrf=`0|`u0&=ExSQV_j5BJXsJ$*6OiecqqKXx4Zq@u85R zM2f8^u4fNw11-bmzkrvREa~9fY0BKPAxE>z{+==;zvrMrxg!-|6|+TptvH`*pQ`F^ z95vTxDpAV0AUKqh6SXoS`gtsG`%FNGt>Kc*9Fm96G6xR%{FFy>c#|lY{k*n!EjqUk zd=!&zj%O5#y@00Wbg9qZ6{VM|0T!|$5Y9cluj9}{SX=x<=iZO`^Kp2{L3uA%mmKi< zHUhnTl(s|aiRygA7_s-f7tTD==tW_UT@$A#EBNiGDTF1AJr3=JcZIa$1vh~7UWBai zLyF0(^4ElIThdq4hoDbePX9JECX;5Ug)@qxLy~Rd$Wj0g>v4XW*qOX}_i|wBBo-WF z18EC+F?{Yk3XxcQ1Q%*cI4hRnyCqm{@^*X@=^-c_TTR!cxdrg8JD9*vvo<&(S9;dA z@sLuz)<-L_>>S`TqlFLbN4%$JoA^SGFx!95()1;+l_d&>$0}8%CB<$1rc%bse zoaXgc%cDq@vhbrAe)qYEJ=GVu2GOJ`97|q+P!u_0C&(9-u^tQRC-+cHeq8W`7$b6i zgvgv-EVK^A>5}&ZdoRdJ;1lDCZK@Bt2%|^wLX6bM1BaH}Y-se%+i@q0)reDH#7>q= zvMU0U3)#VswL}-}4hz^~O)l&UOiyn{pLu_>XlqV;DNbWmsYTV@Xq+-`o>_5Y+efD( zU%T$<_(>rjcaD`(`%#5A5o{jTby}Pwyq(?*7Q~aZ=MxrN!+iz+EykqThm>m+tVmXA zuWEPSwOFyngq3NIDRawaBuq#C>hYiud{hR_gDov!u5-}{zZ8GemD8<0pMifx{6@yX zJybeBh^={Gj48F=-&lqJ6=hfXK0*#b+ep2erQ~f}if4%5_FuVutA6$5hCBvZ3(leA z)Yvh14pY3X^d0~lzdFO(&r%H2WU9SG@XhZBD8U&R#CX-4Xik+ZZMH8&Hk;J6I8Lsh z^;mC6V1-A%`z=3o-EKw=9E?B}M`#S4xZEyMWPObi)?I9zuJLbTd1A`9E+$O#s7w4cP-`y2r)DhryBf)JU;2~S8$6Wv!l#tL5Bd3a{gVUyn{F$-f6PFU zXNW{0gde|WQ$m%yzL!%Rz}f_#TR9J#bTPrhC8qXx4V~`5#>rgS8_v}9W^@|p6a|1T z93e}@#=@9Z)^Z9!s|l@vG)jaY$~gMz*>qx$?c_3|24^>daOG(x2OKr&!sL_?m=c!$ z*N;qB=acDnx@6f|zhAv?QvLqFx~Odu((tzOIfb}Lb)FT=b_P-uV%sbFF&-1gVOI<< zofN*hdqs55w46+&8Li$K$nYx^Ol>WgrR$lQZj@@!XNhXs%XfcB4~u7^jsFh+TH9)VR5^qVDD z*hOve$1mNiJ#x+gB5Z-M&JmFcKCxXYr&g(iRhu;cA>CK!>>ppBnBCa!3DJ7$3SL+| z1lb=^4IGR?TJwo-74dC7vljOJWsJ3^BGqOYE14{|AC+<|DNUb~bL&)DjQf(X(wCV)%lEgYqn zQnff_gJ#KkcxIaW){h#{YW1RjU7=|Q?4$YkH;(}G^STj)MM73vPo)fPs{B)_Rhje~ zl;;)T>QdTASC1s~`{h#Qiz*UgpWml*jGiw}AP;#6@)(S9b{act`Dpm4RSg{qq39S0 z-A;j{z4N?WaVbKKB=x7+-mjxz|V z5A1x{D3gyasYujXGkR&&=>9_JSA7W((>S)$$_j5LBZqjwX5WtmouO)f?0( zb|eY(d(Q9+zsQ^q={C=jye;-e*5t%_+1I41-|VSrz@FhrN8*3m8{)b5a{w^zxcL+l z0~??r>&Ps3qk^d3L(}KEg?qSl+jA!9o}E>f3=JdP*-SA)D7iO9pH*<@7Mc4@?tN;C zt}Xlh@h$QZabJ>+Pzu(w9qeyxl^)OERd_Zg8G@E9yDTY+maQ?I2`{5-i@&&myt1wM z83tHQOS<8l4$?@#5N5S~-A?bzP3z}yH8xmtCm3mD;BlTfTF?3*GS3~>w@qTg1LJ(| ziH#6Of$pyt{t*di@2}1=HKEaJfRG-tts+oy@=S0E44Vc$2UmTv8d%JM zBbO`XuC?A;miAT5u2Nb8sz5frY?2>>5E<9cR>4+Vg6UWMhFmN3juFGEj=$PtTPUq0 zC6M>gcri~K5`$wfi z<@Gd)6@PMc@93p9zSW}#jD8}><*2^zU8Sc^iKD^Y4)?ivUKXtredOt#3>0#vap;#y z9x(uT0r3av1|5Q!;jULNRxt;%za^7z-0MXycR^AT678roXAAYjYFAB%>E~If0X_wP}Ishgk`d~~( zetgqKXYrbyja$p6D~t7H|EuWS`N=q6bit6`^?HS~{-8Nn-=@|mLG1il6=7C<=$v|q z@F)S!nQRt;>E4BJCl0+YpIbQt)dOooF(nxbwQr9T^wY7H%KVO&73Z`jf@h2E()uSO zZquCYsm$d8k7Du%@6Gi#FEA>=CeA-ghz`7fM<8Vqp?wf+kM9gBzKw^t_h97K!kDo4 z6WmneoUeBQ@<>D4s@nPPyh-h`NWz6aiI>z8O7^N`nD5aXPk6*hbi6&DnZJw&8{K$(PPFyBr|*6b;@i!i1m2F) z;N{2LiQi;Vjvdv6FagoZ?WQHq;KXYuV8#D=P2uer6m}0oN0RB{M!N9F77n;$byHu@ z?T=csU$|?@vfI{E%omAHiCYnPahRj>44gEvki)jz^K7GJM$)|0h>DaGWHwzeoKC@Y>F8En1!HgJ!L-O^r%vE;S?OOauFnn zvaum!^^94mw~7$J$~9?N%=gtb3Z}E3ifK+`sdc_ z3E6Y);I!QQ+T&D3z>)ye_JdZ(8_0Wgv}AhcCu0H$)`?@g?pJ=5C*ZJ`zjaw{O;AwB z`Bquq*$$x9KL1zxLTMja?rw&>yYXYAblFDwD7)Vt`7>Z%6nPa|)}v2Xn5MbO^+|O1 zB?m_#=ljk!vn%_^cSn50xkQ9yJVt8K4SU6|H$5HqRN5P5kMTdU1KV4l7tCwwg$6G6 zA>W~O(MyLQU~St8-+|L_A!4nb)3}|gzgOG8$GXt)>_=!R+7x>34`*@n%~MF~GBw|$ z)DkzR^<&lpWKRlgzVOp^yN(c9Lag|+Fedt+GRju0iE<_ar=udYclMsLmUx#Nw97UJ zCmJs567JrJ@Or^+d$0y})fWE(*IcZfmZO~@}N5}W4tf&q>C@;*H!xq)?Q1riwmF7o6!rVi~@JOj|)#O=!;2G$*|Tnw6#xYgOs z{m3-x@eHhztb>BTSkVD6ha7BK;d#^Oj9|i@^_tDCanLmPsFKr!*8&SSBE_S@q~-)F z+I4(tIh{b}qOytV{5)LS7u9p`TUdD6@>(tc|FGY7Z2%Nsj&X0TLblSYD_85$PUu5(3W*>=s>Rm=>9?id!bYS zc>T`m>BqTt_^&(;Fc_{V_FrR-6J4a^| z3?Rkr2gdJ<^c2L%vuHmsicDsUTu<$uY_?9BR?1F%fonFZCgcEA;#a-7X{77gY5%u< zRZ)0g!$m(OsnmGV?mF6%!AzW+K%fZ#wP|r+niDFVUJK4V49O1FwMadB`||;yq9Lcp zY>j?6m@XoVrJ`I6YW`lbEy2Z|+ctC6?J8lju7Y>IZxnavO&fSJi6@maw$TMp16@ft z>hs#0Mb%BZ@la=MX%f;ZM_9~PsrV)c2i#~rxc3?+*=#o4RK&b%L+OfKEKhA4vKYwO zYuRioV|l#QS2r+;sb0ic*hANY{0<*#XEkyfV1AVu7ncTKHVbtn+A~2)T=!KgB|fvR zUe!j;U>{j)CAga%A!v0@(;4a>`0&QI=AglxIx8&_05iW~HqmdUw=A;pd+D=E(56`L zVUt<6LIzZhQ<&T>Iy>S!XqNbFyw`+WjtG z7;mZH6=+{YR0kR(N{Hn1HnhQ!n+bJ3dxGAl^p-`lT^~x>0w>P@f>-@L+9(2UXjibL zklI#iUg^N8jcV965TT=bUShuf0@V>ce3dhNam-6f=@1kNr0}BKc@Dujdxk0ZmC~`v zuaCHxAA!AAafKpZ9n$9zemvgoSkHI9*u<6nC z*xd(6k->JUKaD5$V`jG@qxJc;mwZsrZKN2er5|{`F=FjQ&38Ft0m?0!I9?`5J7Y3% zKws!Y#;^u=ztYV7Ws3*?o_^xFHPYcAAEL+Rr8TGQY%;$-F_ddCo2da<$1#z z7A?%UcuT~{`oM9WD9Ujpag7A)R|8t&4TMRLp6D2Y7B5x+c%9!{9}v{n9n}z}!T1iM zdh%wD{G487MjIVAtO`fv&N^GIsT3k3Qlq53 zq*vkU9&eEJ#cP%yWJI3RiXz8Dn}e-B#zdoozL?&9zOf5wt2(Vv+P1eYtwhI^yNEDa zef(Gc$=cet3oSMs3}mNdvjEs4)Ps_X*7tV17-qTLw_3#CjAI{0_CfZHb&)pvNq{YW ziRo7gqbuiv+i=sFbZ@O)|NeNr7B4F3(Ui2TmzzTEnpgW*Oxcz{p>%Fr@ifalU~Fx% zJ^z?2)>}~`^?Ey;QkG?Ko1l7X56iWEWpSwc5LEfpoQtoqLlnGeT@|KZfo%G8^S3f# zFJN$4(`Yl`b$FK1M#)b$wELcH>{=M#X5KOf$h)?Uyb2Yx_ifv*0YH^CNJ9}c`Ck(b zZjx52Fn1G*bESV|kw3IM)gGT4w@i4$!FnI1N)pwMm{n!AJRmP=PgcLN*0aLXkkdEp z^}dAs57ppt_LGd`4~K{Dq9(P#^s}UlX@bu)iLOnB-BKDRnE7sropl(Mqhvx@67RQn z&Vv!b4-)g|cQJ|ksX+Rne_e=IY%j7DL!ag)Wp@txR&dy;cU|FDt)>z zD?$SSebImu-+6Wj3I*KVUtUNw>=Gk_Z|LDL1Q(U&O1lwk)Hj?i(;qwbaO*c1Ai9q{ z5sHa@tI*B0Y#Y(rKe;)2`eIzK0W78{>vAkmwhfer?|kSyTJ<^g?UHaKLYf#;y!$$$ zRhZ8m%Oaaa5u$$Lcd)CGtZhJT(f0GvGwaM?$mp15>K#Vsn(D>5{^FN(Y}(IQs(G(y zJb0$xL9jIt91(nCY%?9XRv!>zN52v|>}o?=-ij+Bt~CwPHsun5m^HbiN8&4@2ecF4 zpB#a{ox?4RO4*EMS3_v*ZkN6E?pg<2P;KkinZ>e-9VT*sEIj6ee3(e(yy43t1+yr? zmpT=GN)*K`JsUZ{F%MbY&Xb~z&}bgPXayn^GqA7Qc=t1anR#=qBGR3|&80eeRutND z*~X{o$!SRM&6C)%}1K7Y=8XUw_iAO56arON9P4I1eoZ%KKrN*Zrqi(?=3k zIWt~duH@c-IyjPmk&)E@3{cVuZ9W>w(al|mo+moQ?O}O+P5Zxxm@4o<$ZgL^A}T$F zvg;7^BMGu9W(2FeY|i`1%|dYb(I(9|U<;ZBw3-K(Q`4UTcSQpoka2*(YHJsm9F7$7 zXRPt>R(1Eb?|mzaUDjSi3qgC?=c@{W=)Wd@+f=S9Wl<{2o)(_Q8;L}NFof#=p0W7y zMDD&TLm|Obf}PGwYXL5DF(fE{Kxm}Jp)z^_&fi0@$Xe{x?jNfYy6bx3Qo;o>=q@i% z|Mep(VHcT2>gc)Y7OQ)YS9H+1OJO}N8J&PMv}sMauuqwyreTtNbiMHAm+J;+eHI#yoGj=13nkOIU+zHWe#z16A79s!VaN&>;??~zRK`A14-C|ucDrR=@6V3X zz5n4t3Wm)pO80?ZIpWo?qSYE(W|m{I8~8i+3kjL-`|^h%PNrFi7X001GI8+RgHO(C zDw2fSMT<<t6#NCwwO&0SGJmIgTXdq}x@gZXr10?qfeXGW z@i-9HxN>=BKobrrxV>J3PwwrXhRwU!5U^R047@7?CvKJ3k(lxM?KtqN_N2KGLnVb- z`4~4dNS6~^@DG{i(V}>~(Z(2;3YGMIN6S4mm~}d=EF;%PzV#5~v_1)ZzkpDm-@d1g z9n)LFtKS%`J@d={#0p*-fDqi9eywFZ&BJ&v57t!hI!$`BxyM7K+CkTi7oAp+aBm^2QAepBHAmy6KPOFc4JT<-`AX=3};KPG4X z*-&79BxxefnjmsfTA#}|quk}oS-Ig@jFdHr&kZi${IbX!O~odBZG$yp;+KY{7b>53 z;AnPv|L4zl1X!biI*5}OA4kOt^R7j2MHXVk0&p}FrM27H?+!SDe_W+1-_tv(ZaBId zP5r0ZK~iw-sqsIa{zp?vAEqB#1~x(hACj`T=XOF684J7W0ZMlvIixF6*ycF7lYSGf zx!xX^QK~uLMy%@^XM(x;Mr|xXp#yn5O3;!Q-*avdsoFmR)q{XZ#h5FJd!h7qd-)Ix zU#jrGp)NDLm3H(arGYCt^;_|L%aB5c$TCD42RLp2AsDRdY2(!>hB zu$rpd=)f4G{?Gm?0?b)p{^_Ep&N?59k^Mi(_xFEnHrC!NLCj))keOXyor7f{o#)h^ zBGoIw^BJ4<;s$j?eqCre#kIFP7lAEdDw8%wM@7 zbLC^)7dWseE;rR!6f+lGcSFk?!f>s(Fwy$?E8m;lOAnu1Lf91PnBzXiG2YdYK+M`<7MZZD9TCWtNpS`Nj$KBxrNpFqr% zW>{5+-lwc%RV76stG8>iVN6yh00hWfcDoU^jgMB#XqIkBs$bvs$I;uZ?JNhRD-(=Y^@jD(U-4H= zn)c5JqcSG(WnJ?^q6ou6qtJaCXil1wF1hY#m~)#yd&4o=xkAG_`17Sc{OqJ}7fk_d6M@va371N5 zDPs@(vm`=Ho?oj4kcr2dtyVR8nX4cj9L@r~CJtC2IOB#y-2{#^1t(|fkqgDzb9*8W z*xtLfppAVLs|Sv%|2AAr#NnZGtr?DuOXHd!a^X6}4$n1?OFgYx>)7t`N;~-QCQ^|Z z_yDl?!P!YiE9ce^#IxP);&-B(Ti&hN!&vX+7t=X~6d^YiDJUF{^D=c` zDa-t!`~|d_=P}_pLMg^sqDZr9J&kHE4%pbAl-=lB_=kk`=fvUi!%nZ`0P@7NuDG@( zdj6XWEgnsy+*_$ARK@$Z8n1jJM{{kZ59MGn>>l3aM(oXY2yG1IG|mcaY))z$0r$2r$F{0RifT}6JcdjyiM#KtE%B&;?$Gs@mJ>foFGkND|4cXLD9gz5Hnov%E z{*rPkl;uQlR@#7bp+7P6%rKyEZ6XYAvLce-@3@M1Iq!r(erOrD{i0u%qxRqaOlof0 zL*&b6AYi_$ZM#tSK(ei$hRGt~$ojusL7nP@C-ILFsA{OjHl;)tT6VFq!#mVLbKikI z)BPB@w5$zN&Ti*85vv&TK1hs`mx)%~u!|R2(!d`f>xxs7CP$~<{G6U+LD04^0hE&vMjOyDa(-!kUOniP;wwv zF$d{xif~4efQn)HO296KNk!!!U{J8RoP$u+;9hu z9MD*ixTJW-<;A!tpvyHh+h|aFhY!6-g-B=h;KYU%iYdU;U}Ec!X^xVdHB25&2W#05 zzf{>rwX%5M&}}S+ma9M6q+=)U{I!fOeskNH01oN+w!cSv+0vtEQDbjg&wieQx%2*Z zvDI+7-Q<8pYV3rhz-qz(W@8CpwWc@LP9mN+YB9&s=>|r&Ty}BCdg41bOEXZW_%6y3 zdHx6_eB9yLlP(VkEWNtAV~>Z@fpd2;gSGE(mR+2)4*XkfKiMw8GP1`?r$0A!->jDE z$Bd3~RAH3%ZOb)F_uw z(QY_=33+CL1S=$P?1LZt9QZaIvxB&mC>T9chCB*IBUj`!B1#h!Ohde&6UQQmX0ycIO`? z#a9%0aC*jwJ&N{8JU3DC_#;1f`^;O7GD$LQXCe*3!*zC}8PhIjT_eA0r zkeiQKf1KmaXF+ojttX`0j{J|37)hf3ov2=`0k~^~&S#Mfns{7i?aAy=!@pPNjjMZR zFX+ZN8x#m_+xk{2DBaKbeRC8GH+v!i#?%?_+_q%~*e;Vg1}h#%cbeL>LFDKI`5}>) zC<^D|-G9WJ(Q8wNuq5jsu%uV_2n`3zVPk|?TQB7iwU#$IK^EDx44D862m(yvV z2@~8aMg;Mr&*oa}`=KhyyeLE{B=Ui;syy(kRpUU)o`z%}OTHtg5|(J;!)^lXys$d_ zW$V71$lhQ00awmB2)=cRahZ2eJsZBqe&j(EVt+9nf?!!_f%@O$Id2J#Y2KPFjPD0Z zwG9?oWcB+oKIr$G4;H*LB!%=YUrk!nQk?LynfP1Wp9QP(Z))xxJjpJ8f^~&A7wW42 zP-aWC4PEA3#zgu$P0`?ik2-)^K4%r5n6i}}Gg7U(*V{i%ON=xVX3Q~1#`wlp-tYb1B=@BE>IRX+`BxVH>c$`0w70sc zVCxTaRR4L48P)bj9jXe&mM(3#$mQq&wM!5*Bk5bdPM8@79Htn18rdl?=pt=V;G#$+ zoMo}j3$KvvjIJDu?;FI?vfFu<@}xzo=V z!FSF0#N$cG@~htS*JZ;4s!8O&r^kA{*ZCo|9I|lwsolRseMt27A}o9Dc+KMNyY3a7 zksj_h!C&&Er@VgH7@y#xZlr382D9v0HVUO@nQosxl43zTnOF2{z6aosZO%XV`oMI; z|KtSx6(sW!+4*_Y-B#O>?g_OW4+y$g!tu89BJ{EKj(x{Yw4XR{CNrj=KWc~59D`?{ ze%cKY$DumMm0~lLp*}{OBt?250e{n$;N8Q2I#*{tmUNwsadQ2&(F6g@dCQ+2Zm~R? z`I~=ynlByxI{Y*oJdGC{^g_Ym?(jTOziV$j{X6GO{1iWDbVdcdC%J=TzRTNjfNTV+ zgk9v2{55V=FI68k%!eeTvvpteGSQamkv%Qkzc-zGH+QXl8L1TR{7nYE>((xqSlqL7 z_`2kwp{K`|IWCTXWiK;&=yitejPLS+;BF3kw=uZ632`lYCV#ZK0l;jlpY7J#2np>x z@l~~4ID|G2ONA!%Ap%|xB^@Y(9|J9!n4qRzcz+@$0IrzTUr8MX8!gbYKL6DgceA>( zneiP*tl*Wh^cUi*QI4#*9<=5fgS{jzgz`i(9BiA>`H$+Z*mNU#hiH9UlG14f|K!R@HexODTIE>>|qL-=Sv$P zB>4uvd4ODP;4*+NjYY_;$YAV!$amp}%Sn&-y)<{Dt_>~YO!J&K7hij0LZ-WE*$O0# zo@1JpaX+?oU3_1oCFDq$(NlK%w}}}eWTrVR{R`FAGZZS6v&eC{a~%Syvv9x@w|tqw z_F&sZphIO0)o1o8z#Xu1kEaZ*T9dkGr;CQSp%&(?6Q}h!TJd{s<$#VjM>MSNvJ;TP z|C@lp@1ky^BmHzE6E@9~r7r<2M6SUcX2zky!G}w{0W7q}$dY2}^W8 z8dy{R3;P$bpN=5@c4al)v_+=K7gl`14JHvR(ro9#%KaCq z`2S@Vq5qz?I3EV}H|Xqr2Y3iZPREru{2g--C4`1>h?I4>dY?yg{%XCM_JIjs;mQA= z7hqT@;ny;+HJqCOV&=zV65f}}Lpj~Ws9_RBbm3*V!MWjek0g3y=;HE-zGn-M_)>#* zm->k`-}sfSdm0&ZtaHvpk#!g)$!pa!&h>< zTia3zCIRWhyGbhX_ABcL(}_CkvFF;rJ-az?4c9z0+5&m2*n$Scq&vG`FnB}`LIK$R z=8f}^J;SQ0kj48q)TPv<@v5E(rQv8_y(O&P0%O)U%YuD9Kz@mkxl)H5@}!dDfm-jV=c|yrB&*|^MJP?6&(vyCdl}t z_cwuBFaVD%w*1sxa5{*UJISo*^USQ+1dN-S%f4D|%>MC%P#|m74a6Q~wk zSfZzka~wER*fY$ZLIf(&=Vz$_IMpf2USHjh%ll9Ys+E?HCxG`9`zj_8rYdES z35mw!_wM8f6P*Ff1=@ksiBL0XmP>ye$_+)oS^^duJJ|4kNR&NG~H?iG;d%BNTYOMIgnXv z;UAIqUW3oG>4ZK45R3h$H3MMoOejFp2r%K85DnFn{ubj^LjwvYVI}{Uv zq()fRA4p)aOB<|W7zv1cA%Vpqx+Sg2@&D~x0{vFZ9{N=KbYu&){dEjhCh(gez+art z4LyCZ><}FZGR2?tjQy9Nj?0o#v)uxVZL#fsfCGZ0z)od0dm*n-tg8fNJ(cW%2bLAU zbZ^<^=hgtI3MTyw2+e&f^ykTa=K_N6N66Ggb=&OO+61k3S{RF<0ut4}oCN$jSBMCp zB?r^(r_iZmT>$S>-y4Ood0tnP*l&W%uV}19Tg+}mx`iAEBH1W=4P+j|m-Xy3ffmyAn*E!ZWwKA1%0d9Ja&oz!QN<}l(9!;6-)}S( zF$+kz)m5;L{5f^o_Wo&z!Z8O88c`M!4P-WuI4)w%Y*$}RF$XYNR!U~C{Hk*oG-zZABS=E7|j@j4lrOM-d$AfR5THgB^G`>ReJ_l?itA> z*bCoY#W2B9V*P11>)<&+*oN9%1fsKTQy18ilS;=}m98Rhcf<-7^oBRKtS|2fg7;QQbI5n^28XC)M}71VgKE1!DC20 zcjLvjpYWqQ+aa4uB*#odRO`^bQ{fo0BPVPw(Sgr>#&fj_0~XC4AK>9G+izn6>HwM7 zN4_Ps8Zzi_hdUb%K$-&LlG7ynMTXZ7o@x6Rb2%gr$eL+FF7SJmkw_G+dB5%uTAF=& zdbs1aeCJ$yA8sl_<#~jywE+a~jszg*G`1)#%u+5{KT1$yrFSqn#^j4@Cvf#puY|dE zidd#qsOjfF{7;;qE7{gqJ*+v?C0_*l6L!d4v;K7TKnvZSEAs0<-PXU|p0m@%A>`?H z*+#kdwas1fPjo7A7N9!sJTMpXzt&Ms^JS+DQ*>+ka8WbJ4Hod~;wN&t%2y2XJ{6@o z@}0ynx6E8Di(uNIZ9eaFCJI-QT*S=94h2}L5{q-i8DFwK27JBvJpe-xfIj^3w(VT( z9DgpD!P>yA@FBno8Lx*#9eZE6FwYk+CJ$h*FSwP&1?M3M2ndLYS18bp|8#B8MKbv@ zW32*q?!w`8)($LY$61g<>qa2_PUg*H$`4j_T>@7~ZHYb3@klSdFA{(6#d*C>qt_p0 zIRQ{0R$7jL%(;IYrpi?=j6tLws@i=@WSj9Q5+*5i6Bc5&o^iPJ z$mch~Me6PGy?-8qe>@kaPe(gjs{Z5bdT}k(k!LQY$2+g`uY;jt+5V!6mZ;B!m={@6 zMt?v3k84U+qZK1R!OcYe>A8;y!>_Hy$;jj~4n^842xg~f_HnMpxhvhe_IiRIP(UtR zPoNoKqhD9oQ{m7qJ zzLOhXARr+8nU-~iz3>JHxL(XFtis@~<)=S?*?8 zO>e4>d)qkvg1-I{;ESJ^%&^vuI4^x^tRPUm+ z-o*Vc-ri(l-Ud~z6rFJ&0WQlASimT3AN=(J_wLqI!H z0q+egvbOw?J@DS<0hR7j4|93uC5q6}#hw+!1Fe389V46?x)kevybs~24sU(|&q7P^ z-L-bXW*CU7bsqux?#bKY@rsj^poHGGWwW*8x+={tNX-D>^Jw9HjtcLIEP_+h$hina z;rjkwM#jhXZEdx(?Uoe&{gbT5d2@+Jtlp5lBMASamDBkl@)xhMe&#W?gP=tB7Ki*h z=hMKFe(bDFCSX?>NYRZ`R6D zWjmRZ<|Dch7 z(e8iWDGhZlI-vq(5pe(+H-kj=9#=9@q#~qA3V+=qAl>OX`XBdI;m^|9)8*oc;y$~2 zus35uQf4NOMZ9OnHBEuMdt7cyS@oDX1iuLoCgib?9t~;Oa)M0^VXyW5j4J!lfGFPUtq>fqy#b$97DWSm4Qn4LieS}r>Q zj+LUmX&0s9@L#e%l&b(mLQ95k7+l@=P~4omdg~N$@E06&(i3F_2u_odr()q1zrGU@ z^_QEH!zKQ-{_5=ymjHTwZ@~a^WbFOVb_*-kC_m3spOI^JsBM#3xY3SUrOjSz5qbu- zw;TX2u;^Ky|H*YC%{H?KaD@U9O4$h-Eay3H-`_&v3Z zpm{Ut`C}l=0PM7TmSn+IX-%pii8~{JVv$|UkN|&lqBRR2-j`adc`wF?DYdf;hq6rmmlV!snUm3ymncw6e~ZuUvLO}4)6y%3!h_(>P(+y0EiX9? zd;MIW9ST~VMaPunil z&XUA?yaxBkX&yKKE||4LFbTFFu)p)5v&+)`|0Eda3!;lTn;{9{3KJ%Tu8ao4qC+ zQvCTy!3geHs%KnUXW~}B;`wtkew_RNw}*7+&yC+&3~y@wCRjfmct)G~C_qd5zJP?) zx^d^}IDddpuUVh_?Subw@W1OAnBq%-xXgc{Aj5wml#(hB+bi3>B}}gfiG|ElRtTj& zR#G1LA;C;fVx)74{QVh6yHMQo_Sg>)3-gp-k=z?}fcgDqHow?XLP#XC%k~$U>kh?d zjT;n6qj|{@>@~0CZRPe?JH}rA;Np|HcWhyium;x(7mV7U2P|}bTMCE|TCrCVY&256 z=#RtqdPJo{a?Ixzv89cB0-xbuZ5a7;F_=E-H5>VXxzpZ3X&cauP8f20`CfEj7MwRS zwpV*s^83fRb5oFuF;-zwzmDJAy9+tJ@PnXEBlN>LLTS*Qe-+`9j%4_A z$bN2kO>jdr4h1lyLpzwQVv%j3jop0l_A+x79F`I)z5{{=Yk72EL>+KCVYenpc*6uA z-KxoA;1pR^n9O+8Dq3-vlLa!%g|$Yu z51ulciWL;l?m4UVSY(GsNYcuF)Hkva6EG&|xIh`W1^I_K#I=g+nSdUyAxD1iEjdR3!nXMF))97hEU9 z!`+ASMp=hS?<3l%Mrwq}VDrO}kvO9D!-69w;qbT0V{Z|V+x2A z(N*=jo#;uejW(HD10(Y0)q?0vZ~VeRt~sPdv8X_-dyMmv55qOp0bDNArJ9f6R~l-N z^W>v^7T@Vjng{om*jWl%fo|IuIL-m5i)Lokp}#n9jjKv>3>MfjY2eNtoXX6FzMe=s zc@f7uVi8pa^y5)8%OvpGyCp`eweAZr6p`1pHPOh}rHlq(>~hsE?* zM2P?~2(Q$NJ7dpQ{WA!66A&EH?XOiz$Yn2JIUoil!mz=8 z@cV;l2&trR*?Ni+AqF?%OOEIStdQOURdJI;VZ;-^5xbnK7SVAq2LOx>K8|hMeqa_O z_wX-14q?(nmkRAV05F^WaItoP^T2x$s&a zg$8iqYn6!JRgtSy!U%&vRB zCb|L`e}9aMNveOwPtW4x>K27wY&zG41ZneP-&r-|982MPS-Vf>t53lSiHN(GTr)X| zf3jtmk{>Pe^PtR$vv=aOwCgYh@dYj{T;_}0tr+TQSYM3ZE39=cO}+h7n&12Rc+HQU zrabylfyom{HE~@QMua(6eq7kcVYqw~DO_Cp%JT`N^U%{#2Wh*48=3u*5VKkP**;Z^ zuRj$)t3*B~A$|Vba!rs!Ju%)?cs}E6?1moa&|&2(dXRLK*av(QMTay03&RCbl8K69 zjn2uf(-uQ^yF;FlO1wa^-1X=>p|wLC{_BYZ<|zuh^=X;KHBvE=}yLNiE)|guu zl7$ba{n}~weCJlQ){o@j`6>JK7qxCX5m$K6K#7}DdhC~DHmj;3m^igB1xx+CxD^K> z&4l46{<(t1RPRThdd-#iyx<*uvR(54MG}Mh)S+poO?6q~o~LFQ=_F)B^Wk77(MWgp ziq=QT?&@jVW(Gk^&tEfH;>f$jOhnlg;niClnNiRE-#&i#_#Q+P@o1V~-OEY7Kc@Vb z_~ujYv~`)sSL?pWSS5Ra9Tq|?;m`5DqsQ{Ecg!XW<3hc$2a~u6D@j!W+Cpc!@a4cX z+KMZfqQW%^zNy#_cRT2>7vd=l+?t>4r}(QrG`gcfx{YJa`Hi>-T03GA@8D`rs%&Q) zwrLo?ivK3q=i+*)@pHp#NXR`)a%YMdSA=24)KQK2D^=2l8g?)YmF8!j zwm7I$_GN8`Chgn3ERhe*x9jSEyw`ge(Zx9Hp2_g#Ao*cQ$ZShx?4-vtEU1v7+Id~r zNl<@KXr6|eODj-S&V`*~${QZ>;Mce$1pVuY<2938U`jmGnqZ`R+FegGQGD}Z2U5jC zl&J&oD}RBGLqZ7-5+AK*YpH9VJfIXCzJ@i7dVx8uyiKZHf?_i9oQmO^CWXyUV>j{Z1apmh$=0)$?$BtCFf+i6!Q=4wz^!GFLT|a zjR4v=fKxZQnVuKTy`pE&wzD+lxAZQS&-({f?6UJpGY|x9J&H39;(M;|LD|mx!}&Ks z!-?)AYwQCe@9RSPKpO{3ym{90WW>^ z6gL4~%Q1O)4)kCgNarXY_#qC?g|#%i*e46^zCuHaDLSwm*H1aM1alJs3s&&hR>Cxe|!a7WMA>`Szk{ND1Xa_=r}9 zQunv4luo)&e6ssrKHRG7kDGQ7-#Kf{U=_*1@eNR~h)AE2(2$J;M;~TguEvIGG2a1p zSJ`*@n}Z=gi@5^~!jE3B$XqMdepmM7M1fT<%E9I~YeumIwdKIiAM*zx3T@j6Qv#`t zke3R@LV|CsO2)^I`|o;OVHWzQHa$ptnFpHDRgr`&xLLGP2#cdi=05Kkg<)4QQG@rE zmrtN8g%3PwzYO}zHjhYoWPpRfDu^fnq__d#18n9X$H*FT9 zHcNa0d>v#C1b0u3U0L2VngP_DtutP~zq~^!CBFd?N0O=~#{+&s4p-Vc;D)7zujE-U1_gz}Mq_d=WoQLY^i5CV*6D zy7h&m>B+4XEN)$vLVO?ILm4b>b6+-X#ku}m8>3J#78eY>QbdHV7$0!C0R|Pn0EZ1h z&RZRvbrtepTBKhpF^HxJw{_+-Etm9diaQ#KI6)rc-RS@duvmPqj@8oZ>>bkR!d=T zir!h=0_DD_OSkAw^ZaGnhSOCxD=8MX-IgX>?P&fqyiOMP#h!N)+F7(~)#|7*Bu(Ua0?R zG5o9T9Hi`;MFXmAx=(BBCAjz8Z^Oa_AhAp|oS;GI&4HPzddSECLwI;Sr3-ZjF0jsF zsP^67wg{*ruyc@_t}eWIF-6tGoBRFcMh=gjNF?U zyZ{B;qRXmF{vSrEbve>W+Gc)dR~X0&8BJrJYeG#f0@=VY_A)=5F7FPX=u~5fgP`U6 z;z`-Zo4$gZCN9!VF47f&UV38{AlA?GHs{F)0>_)Nmcq6i6R=?k9?_BmP~M1 zPyYeeIctA-_FPj0W$1$_O~~P6!(F5Tu+GJq+ww>J%g7GDd-ympg0vvn^59FbO|-b7 zU>~nr)|B}^XL47=;m*cc=3?XbQ@lbGjGj@i@yw4F6h6c$YO~toxV}U;oTS)aB zHo6W!g^upqkek>XWSQ4*HuOK?X}ggG=tJUaZDy0Zv>Tn101t@x2DR$@L#dtTHyI-t#2yM;pr^?T$u`4BZtg{%>+p7JrR7vF#8 z)jgShT13mu;QhSshfq{48NPdTv4_;m-Y;w*DeoIpy;rX)f8`$tarw44 zm-0;~+CegreO`o@Z=O7~7Rptfjnm>{#oK9(nb>9L%^5pF6 zS3tn*H8sJIRqeCQpN~{cPcX&CW`E|SV@F5<0^0V>Vx8h=@RgRX3#&q1tmugEu&Tc? zP`ni1UDQVU1dM2BF7agnk_6xHENwqnX=PfG@g!wu@EDPQG{s-GLbNVm>Z(5AF$<$F zHVX93=bJcKU(94>-}oXo`xfzHPRBa1cY3e`wxg4v)_ID`*QI4_5{Jg+X zs02*_)C+3um%QdmE5Mr)Rg83N%uKJBFe^Q@gts3&bFoPL@_F4(!0YY<84BcI8Uj%E zh_`gsegb_{_bF!o61&=(k5vDj+&y^y6r~F<1vdft1 zM_g^Bp;zbDfEG09@LfK$T7d*th0{dk%d(&K5u)g|9w}l*X(bhZQ$tKd%07Yn@WVXus&H3+3&i8%DQrs*-_p@VUaE zoI{`VGRhO?Y5-rY((7U4ZikV3P%gJ~l%kq?)dh6IKQz(!D{ZT8@5_wma#hBPJxRv!oy1UWQ1lsH?($BR>=A3b-LI+x zmuf|cYR@$i&TT8Clc+YKM&^)&Jq&J8RC6}soOv+{Mb+!LFvHK+D3cTs3c9D%DILWJUlD(u)$G4z?Um6O(A^RL(JC zK;YviOYKX z04A*iF+uyzp~?-8qK=hC5m7Ky?5tDVO}OXBcyGqkm_i<>{MN0Pw+veTa|xY{<>-UnOq`bTW*&f6VC;1@ag9rV^rBGO1cI8TNt-@nRN~w@ znHe!EZ75&;1>+uG$@Nz54|}&M$Cv}A_YX{?T$Z$)h9)qO4Ud9u!nTo*M5^K=7F7fo zqU|nT<8Rhm`_51DQ!^~Ec$%996BKo@^o`Zlgbj}QGJ{Xi6Vr-o^TFRf=Ba0MWJ7NO zrs91|HSksZuKz79t#<3vkl6xV0|p}U1B|QjaAmp#^PQ?^WugfgCm_X5Eey<&_eTXN zcBYt-0CV@#N-w(_l6}d+w{8^_P@#D}A`qWgH&^=dn)4?(?l6VxMnrW+#Cp?b`5)Cf zERolVtJj}fq*1cRI@(rK@4uO>tvOxA)ATt$zP4pnKYHLTgd9;hww zE)Yt1^lNw7!4dix%Fp;I_Y8qjZQZQJbeDUkgw1s}uTBq0Q7ejYOs=72?|y{Wle2M2 z(>piR7VuP2tu`=hD_&Ca$^OE;hX4HhH-Quu{$QEI4Gj)l7rOGniXGt%y?Qs4!`sQK z$l=P|P?RHy#G{Y1uZc1%#^ zOzfG1AFPLW&{D*j_jb06J)I=Gmc%E1g((u|WjH)azG!xV@jd-R+`09-kSI0_i>H32 z@DdzcLHgYbB#xTR5lbwp&|*bKaV?%PlEeE;W~W zrA7Kop2y@ZRXN{PYlU-UH(eu&gL7oHTm`dfFHX7-;#n(abt>c4p6DbD3gPVy}WTxp(#Df=ys0hsQ0d%6$R&mfy;VBbJ>aZI0p+xv9@>zPuS zL^L%22a|iunEsiy>bqf65a#^87As2T7@qF!6v#x;fhkt{U_H!`CBuy#*h8k3bm3A1YPV+ocAqaDE^K zpPL_N9Msruu##Y=WY%rLd(7|uP}u);L;aXm_+UcxY?!?7rFTZ^Ku;GkEgb<#ZuaVmQD zN>@3RqtyC{b7JlrpolDDN4|3fyTHH>&rI*&NHJ=mHMHM^w`SqOVZnc@aDrW=IZShF zfKnk~fHt~eIYc-7+wA?FsIl;Js0OQQ^$$NL9x-g5ly18edhxYs&icU9qR2@4Pm!i6 zUobR zXux5|6taRTgDwy~U|eW1>i?vWZV{V5qlw?#<%1Fp+-o29UF$_ZDVl6&S_8i^`NCLF zDY~ooz#!pa^RAT%*KO&&BeWi+un{RN-_W{LcmLBWGs5OU#ol_0=9xmvWm0MJIJ{P^ zJB8bP2=ZGcD^emQf_BwpAxMB=GZ@Z;CE5D$~dJns$8s_ZFI%{Da^JGHXMM@_65 zfh0Td4aZP@X&(N3hl;Ft+`HiH)m09w=hM)i^x(?{G4FUnMRWn=o+A}Q-dQlncmT#$ z$SJ9=xnnjJ$o%{nBfIf!RlXfiQ{Y@+io zBNR%PUE;aZ`jzR$nOxsCy@2IoD~E6m8h|!Su$kp)S26C+Lri91g>wHYQ-jkA%Aupn zyX2bmxX4h(p+a>|Xm1gOa5}5jSU^-y{_WM~Lm>p0Ux{Kr7=6ma#aZ-p-#!G@9}IK% z->J5y*8Mn3x;|l)OK6mNfN~+=^TX{~VfSSo= zYbw%N5j9+63z!1kV(m{e(rc{p4w<|9!2C)dqQp0AHX%Q~{gu`y;EFiym={Pp$OcqH zGR}M*Z#(p;#+juc>!x}V+x$<_>Ym6OWiMuz<^m~gK^N=VmHpne;o@~4$Z`%YrL+t!(xlo}sRZp|&j`fRtA;~w}b5&17RhU0ONOkd+n~hQEBd$9VKEC40~DG#nrsbm)Gl`SPxLp4Ir}rn zEYHEU$r67yTHvqr{ymFX7DJ0EQLe=P9bD6ACkw2^K3v!iifsVu%Z@FZt>o7nKgtK{ zm)LjggW_4js~_^6ef&jP)|{Ul@X({!emgOHhs1E-XYIuNFjL~eQ%K_1&dH+5CIc-C zyYN@Ysd5qa>M@1fulPR>@%Wu=<)XC=u|>!SSf^)#`t$bLv-oX^Ul$nm3p2BktGz_T zWIjPFg-8iib1-$nDgcGx(Nv(h1!5B8VW_8OFw?nyo}on!%QbP8=0XQROc3#%@8WO~N-?Tq<)HNXo|SK-3(Tkek=nyu4BO3$4R% z*J;nlaZPu}!?U_2T*wju7Q?NSI@1jy5x(%EsB*rk==0{DkOn;WR6xfCO#RPvS9>~-p!taQ1Xm_U%4CRvvv$5)f|W$q=zIE*6Qix>Is@*BU$ zj}aMQcz`0WALFh$(%Wbqo6>p)*oFP1N%5b}0(7_kC& z@YrkqDH;o3V!TrJ8?D0B$f!x`U>WU&{daP`^!=SUIrH7YdpO9~ta35ZDKz!)zBxOu z{y3FrgDzv2>~Ps78)wFEfQtExjMG>~?D}QRky=s-hgXb%C*alxy%(;$k)w!;7{OTs zF`fGeE{7wM;XwKO_>FtCIux4vW7PIm=4Ur-55H}Qzpe*QsS71mkY~FHYL8V(-*y4H z5AoUA1}olByRLGFLvmz2wr1m$WiaQU_H(RRe-^)?jaQx1(o6?= zXIPToOwc3>ID;g7S4o?d0eIWj4OtDsZI$x@i-Y1K4){C{%6#MIB2ePKFN2zF=n}&i zh>=$XOmXQJMLfaHSMhOB#z!YbT#>h5Fo#foq&Jk@FNP&GJZ`bI$^L1?oOl>J(@hEI zbAlK3N98o$Su{<`AvV$X@mhrT>;_u%bY*;Ix_n{6}u28i+Ec`-kO!y}1&5f}3?k3`!uh!udmp(MI zT)M7F2y>N`fetOwUJ@sl`bHSta@jy3YvF6`isaSuQoZ`7{LvhnZzO?h13(nx&*pm) zKh0Jgu$!TxIa_+|m}P$bf1B-ga1ktZO*V*c^!~;3yYq*0XPQ5{O-S z6Qj&Xh7gHF)%gis3anl}O8g-{Wp&DlP_C;ufsPrJ(`oepZb#Vkx!%#u~qAWGF zE(!V;F0_chShMs%K0(yNiRs1>LhqapSf+gzroWKYu&D~!t>W-`j-_WGyNa3*m^CGd zL4349bBO1YH891Z^`;c~S>|Jt!h%%)mc4*~&Fi}hSWyA* zfLyOr0pLde^RxlyM115JmXGJ+CdFwmzkM=DSQed!Eh^z!#6+R&Qk8@VF(cM8B&Yt` zDX$vS8bBj|Lq6Y^e}E5|+j zcv@#G?wdVjC?@NzzaYgJABE2(nM#%Ro6_LVk~v z_kX43F63AFnh2`7(-)P~9A~J0HXOYmEigOq0f7BE`c#2mw3AzI{SzBu5;C{@M@F24x)vGQt{MtVM(X$hmeitd$ zalS7zn5dig-Yp8EOwL%Pt*?fo$I}L+NWPn^xc49BM7RK}%Nx$4(ch&@(KB!m)_e~W zoE$2~GBh|X3T`0-bA~-##6s}ccac^N9d4>qz$SDs*A-=n^C5hBS>R5$D#`3@la0yC zGUs&o6}sBvLO5g}61zi_ZEVry-4jW)lOG=yU|}5M5@VaNaiaT)v@m!Q&)lN&{GirD z?EIRe2uCJ$^S#3>F>3u+K<$J3DdP>jn@14ULW5{OvdO%~n7b}5YAp_0Q*X!9pPbJF zb45t~1x}bi*|5uOHlT?$%je1fWpmb~V&+1BlXC6VTnssS8+vo7_|lqEP^^g);SjoN zBAd}X$rpB%^Y+%fnAm-S_f}~do%c8sP5^86B>sgP`(_SK=k1p*Us*n1@<@Bd(uW;h zi8cB4CECeC%y1vojIJ_gIO%9ISOIa)e0rDoJs$F@9!k1T*kUs7%*Qqh)SWoewU`J% zC)oA87eV=pXbnyd?&B0o?moGNbgLQaj&hF!LE|&A_j;v^jIaFm{f75i%s>C+ytf@h~dO=h7V# zAKyC4&8w4=60|td8o*$;HV>bSw{O`2T1>F6NW8g5Q5yisLwpwUa3A+jWJ=CvO*%$XX@fJj|$x+M*QBKCe56%x1@80}8(h z`hBZ;IG$ZkigxafvF%rz8ge_pMF_G$V~$`EW@FX<)7V2&Rfz$%HBlGI^=IS8ww~;7 zZCv4~EXtxM`Ku%@U-_CiImKA;5R7%PHHu?{RGkJMkH76dhar7H)L`&nbawRMl>U|Y zzV8XVe$2}dV%(>a0Ei2DxDSJ*JTAnBF@5+&=_}rtvhvQaf5x6LW$~RD$n9u5B1L#e z@K>O0c|T`#9)qow=U=l>R*&|K8geE22xN|5g8od^L+;5q>uy<%=~cU~)C=3@zU8m4 z#5&e=K6J`4L*`IQc7L?9v#sU*QhWC_@rH<#}@&+rY* z*(Kf4GqbI&%L+4BedC`$B*sT92!K5ICLXNO!&*)pJs%rP@hZzcFRnfcI67Ll>y#9V zK$FAw^ykYda=&&RQE2bvd}LP`6Tk9u{JAFPh9||YrWB88AIfslZ{ECExEJpYuP=XU z=UkaPrx_n0V8-s*953M2w6rnw@G>9m5h#%_FMjz0TwRrAXYDbZ0JoauVz`5@^7-jJ zl^b!wRA@^UK%0P7g0U(=vhjK`~14do_fsL09Um}8>X-7?*{IG*)8g`a5L zWO@UmEi)gE+ga-KD%Eay_qsm-y!O$|a;|5;hL9vvLMu~{&b}JckXujb*I#j(VN)PG z=g0gGDA{CU)rpRC zzglk8H-zkQmi*EPqy0orJX*ZDSKKq~#m)d-Av@L5@KDa-eqhRoT zx3e8laCaqF8WSUuxfrkBktj@d%7^4C4dxK>p!$>wVWZG2P035+Oh?sTq}VoWe;`+CEl2@ zS(A7x%N2TZ+pe36YCqypq8Ygi?YvTO?@)@36dVA6S3{S9&>P96@b^ugr(ik&`%s>gh$^dxU0j(cQ~aY_Bm!*T8Ro#Fkh$XU`#X@r z_6fliF`$TSQQXc#rn08GnC(R3RP^j5{9ELmqgaC1Vo6zJ9CX})_cyjhLCXFHmsViS#Mk*@1rO=TCaS=h(K zPT+J!HN=88I`4E@1+wQr_OLo%1e-i&+aCwr11X;sNL2-FMK*Yq1*%YV!gNhO<$nC`cTIO z8PG9>!;7AoL(7ghksO|Md5`uJL%!H6rF{mZ#Gvk!@RiFqz?Uyxk36EZC5|~v*o@>3 zYAx_0st*V$j0+#yIx8>JQAo#onM5>iPVw`=uB7FAGdorsm1@_=U9(3SRK%C`32v5T zN?arHjvxB;QH<))Kg=}akq}uAv~Lk@rBDGEcMU#kVb&NuOG8#Qx?oFptbDs$fI=SJ z(c7(*)H>GbY`+OWN^4vfFY6VKjfMuaJ^-+64t_%wq%^|$!?bTpfownBlx%}8?g9&I zSxTHL56O=Fzt}qus3w~3;U^G!ktR|slu!jkkN^rwhtNT(0i~*xP!tdaB~)zn65 zrnIdYX&=tbb78VPE!plJz(?Lu=FRlnOK5_EWG8F(XX&E_Z5~}hlbb)hn^A-nzXLwd zn5iSc)dcC~>3ff;KU$@Re9!t>+!C41P(xbrZuF65Q?77K4C30>z4UJVmp&ap&)6`W zcpW~W(v$H1e)&mb&-g8-(j#R%`pxzmPHh`-dysv=cgmT!#bT$O^me+=I)N$VrCS#} z+dS^xHN~71eNx-&k|=EVo@^=!CYA=vve9|8^<`1hv3-x$#~KSI-rRia{x#yNN{=)6 zzU+a`(>pviv{#Nk;2cwgh3}jmY!1#4ynT-(8~8ZS!QCT1q{&f^(>ewYS$GUT`N1)= zUE*RpvK?Q~16Xj4Mnhv!f6zNTf(clQXK*zx{^A9Z{EmioM=lc3{@VonOc(t;4@dTNe7LYVdRTCC z*rkH!X~e@O#mbZ)R4Mt<$I>&Rl(+5To8qGjvOC*MQoyp`H}rgS-gV_1=4X%IPG3Em zK}cx;B9xdNBrg)WY1~$GJi1-?Lis*VvP{TM#*@3x=!uIq-gy!%pdk`H!2F^QSTcCp zE@x}RKP_GT9zWon_k!g9?x~Y?uMM6RT3JYI3|wcCEM1;B)5!Nxy_YCD zPvn{nv8%DU+_{R5MF*dE8@qOL#)?8r&Ntg?5?|=%te}55=%~AR-|P2vF1FNiz=uM$ z+&B~2wj~P5GvNa#-{`d+fK1|Q( z?Zzmr@|xvw?qGt|4H?v`XZ|T1{Fz+?7Mr6 z^(Y$s_2JmwkafmN;-O~_RGW0A9L)hdj=xbQfV@4aa7ogZVbc|QHEREhep=`67cMj+Z55k|Mwdf3`yY3ctK=W&oKAG` zAey>!Ln9J|6T{JI3;aS4IlHs})E^pi)GZiP}W+1=gmTobAFTS)p} z@z}mPakq|bvcvW*Yw^atJCa^}f!sM(=_9Y2{H*4g+`A&~Ta9mB)CW-Oa!g5&-S0fx zWLZhTN22=j%pI<$=sQs_b{Ell7T>wjR{r$9vNS>5TZjuG2iq+3wcnZVe8#C)O?7&|*PFJu#^Vkb-?Y3-kPepb zptaL&LSA*B9uKn5*OL62pklKAmmHOlNL0)R@8!Z?$K<8ddhH8fl$%a$lGC z&QJFp$H3oH{1|dI@MMg|K~lG5C6A+y5_VZS8+O@^UUF2;ZF!J)rddDl`~~16xA~sc zf%hshdgT4LPOD5OS8v*O=f02k1|_ZZlV;EKWuvFNCwbq=4emSX`|xDg=DIiUOk7I4 znx-#J+ys7PPVv!5lVY!!wEZWK$5#no=yhc{^`=Uj?XAH(_TSHQxXQo1(z9}co#6tj z*P+isV+O_3EYHMzZg;XjCqH8+M0xzShm1DF_u<|V_0v5Dgi2%?2V%(0&KZdoz8E#! z4(!7*gxYJdkXJX`SBCJ`|1kZ21pZ>Y2fQL22c`cMT^_V#bUe6zdUjpfz&mVXqZEs z*3I+@M1)N|$3{Q+tFZ#e`~^(&KL5hv zzp36T1N9@Zf0%yJx_%V2g(9dGk1mM)dEy_YKZ)T#On(r)KR-A9_)PS@OADC#(f30< z5qRl5)*>9f^`<2H=>c-)sIRXR$Y#8C&Oc;T<0L+AHAgMJt6%oEf{ALxta}PD2(`~A=%N2(&#U;=p@D#ZIPXB?Dp$_URf6LG! zCgA%r<>&=YLii(Y8{F$_wD%l6hD@0E=8vo{a`HAbUcw1|lgab}Gg{_uYXjk5F|=e= zj{}{zKL(yE|cfgMRHYRr5ARJM{qlrQnHwNK) zxNiiu0+Go@Y7`^Ia*+p*C;&#Su&kBO@Trr?)-vtXir>W)fHymbht*FA;s&|7@g)O8 zJ7+O*A^KD6tGIGisQ{yenvPgj2cW?qMuX+lejk&MyxV40SU8Buak9oG0`G@K0hnBX zzgXmP9Du25+lU6bObgeBPdyZbe(<}PaAaXVW_Vo>5L1~Jp2O}4Rtv=RLfxKz3-@f> z*q5K@jT;q)>~e@;RruZB#E$Fc!8HPXwiUosd=E&lHzB1#Ol0i2YVeB*pwWCApk<~8 z;L&9=4o9~BW^W3>E0nzFLg2Z$0ZhHt(|EsFF&qF0(Z(}f#dTW?#8f=dcOGbUK+r~^ zd1Nxb*PEh5Eu!!WZ;)JDPyii00IM`E3iV)5v56%bR~Ui6J1L9jQuSe?xRdef;WR-kP-Vl{y3h@#5?OioyJz?0Q( zvGbC}WWbo2GlE3p-fb6e3@TI^!#(0bfV~Nh%>(|T`!urwOa(!o08CgUUzrTL0{L5* zx)rd;T8o3IaCpD&Uhev;od~>H3=o`Q_((n)Hz9`WN~gu`3(hM48jl{(3L7mI5!Wvo z(1%9g(bLb-ICl6cRy0-xoexT`D@NIOBc-SDj<{NM;U@HLGA@@z4J(EPwQ$r?7jShL zj@3#lL&Bpz*aOumCPU+#;aFE7!G)*-##=54HT1M*rN*?R!l6x zRHzCJt$y(zxYI`kT#y?19>9E#3)jh=Sv-bo6=%fbE!1|23=86Pq>kHc1?FksT;&$G z-bm}}qPK{tnARdD!GTU5O~;xVFwBK$9K+$AV*6@)@fN@sd)^e7AZ-Ok58M|B4-Wq^ z0-yHa0Wewde1Qk#R;7J_S5+qfL3UEsBJckDqqN`Cy=~w|h9-FJc+2mEc z106my8jt4K>ku8(S{CZ)BflyupfjiiNtf6vX@C=Af(w{nwOM}UG-3$~l-sz!0LJv| z=n^%1YyukB$X=%DH~nmTIWiUjC|S+6gi}6>sS@uOVGHjX}Y&yr44Y7ADiXGO$->S zf+K=7zH%C62Zs1d3F%T~;l8X#IJCG{RimXBPVYF7jbkN1=L9EMK=CgeJecq-t@YBtoo*Z>ST<#Y{m2QUC#g*qQUj|uE84&dm( zI)@1z6#`(&E0b}e3jof79>9rtRfZNZ9RsvQCHO@E?t$}Q^w;jBBM78x0YfTZF;xJA zR3DepC=`dh3r<$R6X$AdEq14BBREzQ>`rqNtgo1QQ`m|Z5%{|iKyL!(i{RyoJwOc@^(ufd&dxIq?>J)j6;lcj z$>YGB5}n%!^dtsg(HL>=FkCm5xGxZa*9AHk ze?=G|LySM6f_E-^hOPjFSFx=&$g5EG3v;Md`SS}Ut8rtoH~rTZ7kkrRaC^n7Envz= zIp7FIAdro2eN_L6(FIJ8(Hnbx#BjU1SUvs|LyMT|rF<>&H%6&^K=-Z~gx_^z0h5F7 zXjpdx8iOAzw);=o#sa2-(AZOWb{wJOWuBbhb$dk*7ch0xBQ!$;x~VF>p8Y3=7BQXF z?i9>tHADR8n9%(p(dqvaOt@!Zz6l^ET>pQJ3Ex>P?+ASHBsalsl_T@oXf9$}vDy5E z{vQ;4;N;y3EJ(3^gv?3#-FUtj{hA`AYj`O53&7YMLggT{4#fqZ5K@-BVG z1D}bV|2GUCdP0+r`YL?}_yjF5ld=-Jyc!6xK;f?&aDi!iaxQJ~1@Z>e_Xew#gTp)0 z0duoP;4u6)Fu%2iN9B6YmAMHllH%FUe`PZXPdxc*%+>N)}rB@5-< z2wcn~fn8Ws0(#bst+;L&Xc0L#AqT3Qg9BGlXN7-ZXlc)a#{nNFp+kb#PT;B@cuC_2 zxC@Y=147vdB+$8d6|DN903&$JtlknJxP!G(Oz|DFm#M#~6>6c{_E>pzu{r!akkbfv z0V@MuJH?~EasrS5s<6mY2q3s>v!y^zo>)C}F=x&%tN>+~aiYTE9|B7qxSrbc+qtJf zPTW}4c}}zE{zRlW0*}TZ;j@}SPFQ5vudRSiF5?6!@j>!|4FY8aumLztgF5Fp&AQzP z2id=agBNvRm2+^w0t}e`^%lD*Gh3V)o{L9Ms!>g9w1SvQXYX;%Vgj}G!DCT?&Ti~1 z7Z6hqeD-4a*M=4^qJVZR56JsrDS+EPBD=|eF62O`Wrnp~ipd3BTE;sNAn$>8K};TW zTBfV1(RY{}u}DFnJp>HE<3LR8p-5?9bqefGHgK#ua0ibTRNKgN5cmstWe0Y-64q7J z=sQehK&u{n7=`zwvjKg+cn^N@E2dPS7nKEp*NwPd_(f3pET%R%R_)PhDisU*Hn+`U zngBGL(|MtXkV&A=2~OC3XmDVf?bY=ib6wOOJNv{shzaj{1h|cvu%P7U3Dm-&IZS|u z=t*QNpgA4zS(EA+QfTM=s29bmFpCms*b|_8v!h;F4=_e(%zL|_?YqRcy$Jx(iUVDR zMR5WMBoK}8na251Pu;->fCw%z!n?pYfS7RjMl6y?3EW+I`?fdXkfOL6Ab>!_Xa#&8 z!t-KPAI^_@+kp`&9Z(1~Y!sk&78B5H0F>bFFSgi40T2^#(IWEwV>xGiElCWVU5uNvxWe-K}`4#ti>!QkO+Djxf}TV9w~qT zHP2xJR+{FccmffQ70Y05>ZdR}P#AK}_g;aOn#8n**2t4n?BS`OHAR^X6Gh z#pl4z6@^;a3V1a3t3@CUk91H0ZVci+&UUL&_{=P(;-uNrd?R>{$KlJd>R0R);b-xV z>33!^4W{hGKbj5cuWT(kV~@2?0_Xs@3b9~jITi(C!r`s3i`g$+1O~$$zc#cC6A&dg zPBc(97AQCf$0mTi3D;XYJLt_}0`C9Au^KVJ9TgxmkBkS=p9+{}0;Bz_ZBfPrn00}- zO#9|W>7#U-_HvqIfCemZ*Rg-rI;gGrvkeT0RbF)(t`UA7SkT;sxQbuJir5lNzxL`| zx8c}DKYvxDrRSz^_57l2al&D&X6x$Ri(RAsMa})U+K|$VyT8=4hU$M)M|Yql1pHF} zg1{eO8bN~7j8#|4dexHO>MRa|$EJLnxq`OXHF&jLZTFUdtmQc?t3s_scx6>9AN>PN zD+KCChkhT^kF>26pWnx{a;&~TidxBywYt5M{69?J2Y>ZB|1hmSR^Lhf>rE?l%7>K~@xkHEik)AG~Jnj-n{+_a`} zEf@a39rPw=7leRCpd}k2>v9j*Gz!fM|EM?JnZM__^8eez{-7bw`u+VlIPh>;{l3)m8 zO?rP0dH2UgW4X*h#F{I(43lHg=+CVzH=1x`ja6HY$$q)Em1>9FIlVSgOEEbdS%aZf zKZ!l>&r(dYH=I`+JuGsmldFj25=_Ow^WDzyX?_`1;AY=y0Y&Vn;bFmJn-uK1DW7G^#wq`Oe`S? zK21Nn#WOEP_-PP4E`D+M0TLeF^K}<^a0Ky7{fh!i2!d~*fLqk_B~j{uMQvTO+YO8Q z@O8IX5`1Q7^_5yeFm=ulRwZmnaWA^r+qw%mbimUgbNUCYuqN~A)mTI=2-|-(wET`> z_43_^OWu#8n|+38!G~WYmSD=B$JDjN!}+`KU;QbLoPF+OR-l9oxZ}9s=PwgWFpvY5DH)CDe|5eXLayHi*S zyz;+zQ~`XLY;kwx^dctk0lT@)PGP=w@TgYc6+FL%UF;n=)^=f+iw-G-SgoNYnC8dl zMYRj2f1WtMYC}tA7Z2BD;;ZoLhloW?!1F-xwQo0m15?HC7+S;hEOsHz?|!33@bj!I zx3?unQ447R6C3c>$l3zvv{3w4iDj6$#()=*))vF6-@_D_fW`%_DTX}63&HF zCEq95fhP;G>KeFb3x|G}lm+;l*}S(uNC3-DAF;?CUSA-63sS$^r5Yd*$^|8>O8iHl z78=50;x|F9suqh@fB^q4r~?oPXa|5`0rv`rermC|6!V&Yy94H?~gF$1F(** zzz6}(7|7-Xxb=TEeOQ>$EX*VFCBG_(FznPW}mnFy+s|+6YypG*=@By!LazC ztn<8~+1E7i3wFP^2pR%jx0#cVvYg#r2+_|Iu?vUhom?KA?+t=8oQ)f!sBgh$URD8wQ!0A+!NqBHX@ zEO+@0c6LO~MRLu`UqLKC{BygD*SK>sz`K0YKv`g!w&sVH97Mo(rqIPU@TJ$>Ki9vg zB=#GZ?!&=H&GD4W7m60;f$M|2K#?wZRP&O|Z~TR{ zA8aja1G6TUV490S3ld&^;SwG2bA~^341C;OV1u|P7J2I%7k{)&rNp$ld;fIr3ZwZvAErNO{QofhNk{wFoBkkr{|3E37!v;tdVgoon_O(b4*Ed4uV@wu5$^uH z{=uoGn2P1We5LtP3s*PID0{?w<`VfuOhtC{3h^#t?LgY|F(_~EhF1jS)4}x7gLwOc zi%Q0T{1Oz94{mdI!NhHJQNq{ExkGb*V;2feXcRM$mGb-5Hx)pv&;#t-UnjUFcse*R z#p*W+-pE1A;Vrgf3demv>*I?~J2U6iJGKpWy}9d3jNf>$NH6ysRi4^SH=?w1E$N}* z;PRd)hy~4a3Dmsx-f~1QgnH)5tq=T6-tj(nC%!;#+p~t>c$?;R>74Id8lxxj=#5IH z9^!30A>;gMpXB26Sws^B_{OW!RJ->F_(lui`N0agMh(#cv-)jUn6u zr+)N6Z+}UhC!eU!V`1kyN^*_cXbKNwW^ZrI0aL`wFiRBr-gQ!?Tixrno}h`Ny4SvY zcZ2#VhaJ6JPl`SmD?4-;k>VyvDkqvL{5WL<_vqxN1N zV#3p)R1P~T<~p*&F>4pvCgLW})isR1b=~NN&qnUJ8Ika#$0U_*Uv|9U%lic3`?{u^ zYG{!1a2(XtsKu6*x#rB+@=7gsCm{ba>oSPNkI>U|{`~l_BioPjmnm5=7rR6l{Aq(F zyEuH%0oHGFmhC=VCcNy>ay_$$P)h~AZ7q{4sw$>fTJ~4z#oqKQ$rX+MpbFp0FJN*6 zK9?{jA3mSJy$u6%`o?DS9XbjC0c!-_0kI&kmPG8laK#TEIiQ=>=`yFef~ggUM+3iw zRh|G?T>FNaFY@jl?9!e$G7{5FyzAwK+BQ-Ja8$ z)kfoY3@u`MqQ3i{WZ(U=j3G9m&2kAYIP#ZMtnr)VuNKSS8OJ9JY?Z-HtMZCN_c8)M z;xq5w8WM|`&R?~u+Ny1Ak|?8Q~jJnpB;-ljF3h<-%uTq^2GJa}jJ zq_t*SvGZP4xZNC57R&6p>P`@O_X`9ru4aFuMyCRw#fWz~R**l_L5~=e3V7T)&UtcA z!kW#1Q9#X?dUuQ4UQ0jaVCfLKvb=WJV1>M>tkMUEcpmiKn*7oa=Fjj)uO=jjSB{Oe z%omyWa#hh>5Bj9EIe&7pa@_Zkp z>pFB*s=xJP0Tl2-6{=>uU2%d<#eF9cqt=qa@ccn1aR&R?9!)Y%tK#;tP*#h81jkU~ zmB+%LR(Ju_GCv^)=69oCT{S~2bx-uCs^*LQL|}o_Qf>Hsx%0dAI}Rz$r$JSHKhd*P z=7;G;PQR<+hiZS2xdhV>j{Z&SvH!9DMRusa>Gq=9@BROW>HC@5*S;yM!wP@taT`7?XjJK(OO1MrjdOT<=6$1X_j2@y{~<5FgY z-;9?gfV1y;C64-iJ15`F?P`3@w3Gu@KT5AJ$owjSniuGPd1~5gBmc2J%kb!gJGkA) z%{)FqUgs&ZM*1hAZ=g;-#y20UzsASx@K)Xpck2$WPp}-{v)wpn-kEtli|#GYS;S<~ zTcA$+gd)TX9mj_5>Z^H4JtR01epbl-P#zvJg?_;3F26;_tbx5uK$F+-&I`^{u>-BD zm!Bejrup0aMNHu-tjS4nhDW!P{1C01i+)Kk!6BAZ%4T(yd z4DU-!{bMtDYcbXjiQg(*UXdk7V;9n*qlG;@<0bL_FF0^LVIgE!2Pr>?d<=hFen9j?+pxzC-%&Do z_GSrfSp(P26LEfT1#h5^ia(ExVU@BULnH2s?99_*7&w33PNVQW)oKkbas&MKK3 z9e@#G`AGC#*%d4qato-Ff>@Pg|d*)Do zPu0pk{|M866UKj-{($NKkC-m~H|^~EDBJJ((hDJlLJ6UJXx@I}``~)2|3I<9Sm(dQ zzaae2TEdHsCB3C?Um(NRga$u~J;Hy11e9O*8oz(m@iWWh81Q9>{iZi(?3#h^JWw59 zz1VAtlY2|e1QoIFl1&l9bQ1biX)_x_^_-vzE-5$4ryhQRSc8Th zLujVzTWKzIXKwW;R2F8Fwv{8NC6lD#>~J^Q$jv1o+;B$swCYF$(SA&TlLmE7wdq;Q zdIRU=&$fmH_xKerQ{MWp;jH5qi0G#{x!X(}3e_6oYWe#uWK+3v8KT2U=_#@x+;VgR z;;=fVbx+stJYleTQ*1?{smo^3cQS#IC6$`o+gJ>=Hl_ww>qseu)f8OQ?V?Dgh!j-3 zD`-X>LY~D^e}bABYNhO7C(E{;AWqzlj?^)TIZ!Yu=IuF-2khJyD)3>!4kEwUATqdy zrvLtN2l&1O|B0M^7?lUShmG&1u}lZS<#+V&VAx7uaK4#~TIxq>0M(ha#Be);0%N2qd>H$@1YInl_ywUU0{fj1wi8;J+hqQZQ(P75)(qzNk37|*y999D;K zqEp>1KEPlm&)XIK+W(XzpD#^vm15Q>G13#Hft1OQ_GDXI?2G3l;DYMDl!Q+`HDuv; zcGzuBJd|4L$Eh4Wxy|}4L2HnscZi%0tAnn5LatVM{D?tjZUUKlMC;S zL=q}vglqR+W1#H9cF_!Ti&uZDN_o2w4 zck0=3I(PGiP1ZrYlxhBKXQAc^W+*Cg=D-ogB0gugG)j`BdiAp`)ybB}m@@T;IB1~u z+k6dKs`STEihSlOT$P3gyBTXV>MbPvb5u=CFUv!pI!AHU=Vr$B*YmG0A@zfxD2BR- zbM?v@?|H2QN0gQ?kb|_XxS`Zk^$Kzt-_saUw!8Zo+9P5fW3TeDhtwUoK-ZmjSw*k1 zh|a?NGIt^Q{T)rV;rB)^O|&;}i&r*>!z*70duL zqvEWVpz4ux&!eYJc_!N8Y`D(fTVUU{vssyG#w?o%L!3Qi(@XnEL)jR%3?ZD+2VGRz z{kA4P7Q_@%=+}fW`UOYu2NGO~fFw7y_*{+)l%;Xs?ELAh923Tj#;-=hdz6{BiIa_( zl+@4q2xCk4{<|`S`ywf!m6Z?(H8s<86@GG^pNgZ}w!Rc3u_?PyVf*Wnx7-Cf{Anki zd~lZ|t4nFgZXw?wQ^G_(H92b2NWVAphL-R%JU4M#29)ZR_oH;GdqYIou4aiv4EOxh z)A7EH+|^Mbili+=XXEGQi*(`<7Sb9E|M6>OwJQ ziXIS8|MTKv8Hv#cdMwKP^;8~8?%=K*xa~pO4KI)z4w&XxR1WW$le8s0a~PtyY5FZZud-?S%ib~L_JK$>?&)udft59-P{)loYm zu>Xxl41cDy4MI|=Gl}_nmmbBfsFV$`xSYf7Z^FvEl?o$8njX)*I}_}6%UEoyg`{12 zxduI~QYSK|T8YCYD^5(kEGK4{-hFvA(^CZ@matotQXMAdiI0*)m4{57iA79yum#3D zK`|cc>1NIj4+uE|RoGyPwCn=C0WMdckZ|S27zHZ4&c1*-<>Pbq09Wm~I1NAVsw6fQ zPB?@kD=?)$?gB?1S*)Uj6fJ7H937}b3QLXOt}w8b^qxnEV&!?PzX@74QX_n)h;rQB z<88Mev=s@KXLi}yMn1V$ASl{Z`gwrnn)4mF3^ENyZgDV)kW9d~JzvxBe0ox1fT8}d zi~+9RvE>5WB8Q6HmC#&OsC&sw=>F7BaxxpN5jf~r(F z#Sd}oP+lUW*@l!cUP4w|_yVi+xnP~1r&H$>Wn?bBTTjcxBCyGoHcJTAZhn5>dKw0{ zc6WpDr}>p8C0RVA{KWJrhYEC5cS&z9h$bba{{rDi<|I_~y_zg$-F(7cG}tGZz>md| ze4?MxkmBr?TF>iV?=oIgZ!kKweY}j0*Zy72aH-y-qhvCtgH{@qAYs)&gs!cW?j1GRIS^d(heGe1S*`OpLEu0?*F$BT}tvhmaAo1wq zs`ItyZd~|So&>WxMwjo%OC`X;C>Sat$Xz8mUauWMOHG@}L0^wOe49iaT0JCeXlT;W zb(NRp{kd$vVva_WFAzskZTbk<9#^QgitvmoxjnDQfEkf@lz!Dlg+~OhB>Ysx;ymql zK6SQEDTo+Fyfsfx(7wQMXD25G6oD=Dk<^PZ_v1VGlF7Qc;PHL3l8xLuIQOY@#9p z0WW`qq_>hwG@p6M8V$@o_#?hRMl7>EC^gp$u76FLc2f1>-RGnP*rb@;vi#Aj%GdHf z?g1w;BA?>$B*E!MkdV7hhJ^?UBX1ePqZbvE1SV9%$qF)Z&z|TlTutPK}%CRZBY^@pgh?~s$Mt2 z&;3Efe(&vYyQgwj2pD1rkC?#9=m?;&Kt4^U51ln!Y;nG)qBlIW#ydrRAW~4=#4IRc z?^iBBYd$1S1AGS=?o{b>DDkekNb{#oZ+}c53*EyHo}>bb>AEKoIn3L>A!=vUEf*ieCeX4IUtom}w2gLPISDLQs*Y=1>pW&{Ca2rH+znb3eogokD!N|GO%D6tdd-XNhy@#ed@ zD^$GXd0>Xr?VbtP-OVL)0j-%9#TXCwC8uRQn?$pxu(3eQNTs2T!T+pz1W~80N-$;R z5u$pH{irQ8xA3q``kc!h`4;W)2y;2kBX2lJrsEL@v-p@<bILB5g(&cW_PqDXvFmAp#`62(=NCE%!|b=P(q4F<+U1CdF+ zXW>m@&aM!2XbWehEYQ$LEQuyeS{|}PB+{D6ZZn8HPcUWCMIo;w@>w}Sd*eFDMZzH+ zeHnvc+#TF?nPNr6rgt7y@-`6}ndnkeb<#v#jn?x?yuez`9cci`j7Yz#)lz37EBMr) zW-!Z#*+*?6^mbSqYvizDZs$!w6|-|~v6VR%``^fu`w%pyj1V1lGz+bJu-@hg`-}&x ztahW&Fpee}bvgMLB* z;QJX}87AkPQ#tYj4YSBX#VDf?N0{Bo&)l-ygrOQU(HG3_`7|X)k>B=_w^B)1SS|RF zR^9nyo3(|@8RSb(gv8P@u_IN*a?)<^Aj%^$b${4ULZHKMMqlb(lF}Xa`MDTfiZg4w zY|vq*ibe>QSye`|iY3<%3l$NS6-`!y<p+VUUz*Y#WEd4CRoJc;>|Tdt5$7WGymks(HC=!U`C$)Yo$y_3aA*@&rB4>$eav z@XDA(9_<}TD3TB~AI6_`{SQq94)`pir=Ev zo=Jo3W|rg(YR@oKPs<95)u*Ra5Vf;8A9>BzvHi+vxgf|Rs}{Lux*UOl$s8QQfx{9Z zA%dt~hN(dogkEQ1%E3Di=ZOwe1e|=%8l7HFl&OIm8RnB`_PJKe({+(Z0m2et*0e3O z!PZDcAEG0%E^V}f6#jzpd<4=<>a_%epLV2N%+5z_TvBSVmKzyndyR=d6J}`kQ;0#- zwFM(?b5h=Qr3$w^UMo>mdhhP@DkKZV!Tqv)v-4)Ny>s5G3 zM=j|hn@ixvG&C%3wlkFhwvTbhmA9eY1seS}>}{n#hijlrbvxI`*DXW3Vg%4p%ooUW z{Nt`bwh_0^fDE$?e6pM>S%z)_$Hl2G-+Gchx$^;tqJ4pmelb4NDbEyY(N{FAG^Db; zZ_6-=X(*&#kK2ZM?%zY&iPo*Bjg^+M4f+C+eg|BsicJ)pihio3Btx_Qa)60}kwU}n z81n=k@q`w*y6g!j$?ahRL9B$7BGtwbNewRtPVgSa`o*$36VMVFiF{=0SEC$xG_nR9hO_jbtntDG<&zdy&T;@xg?n z+opYd?A~D&D@YXr_DweDzkuxo_Q21$Y&9gD$Lmt z*a@j`7pYa#;B$ee>Q6ZwV3fZ5pol2O*9?2*4S%qAx)#qhSeA@Emaafu1*+oIhzSan zmHh&dnjHJ=IHYNLGw2@uBP>yEqOyA3N#cQ&G#fs>_-2uZ@1cquyb+2HdV=*My+J#VM}9YuR9F;ssfYdQ8&`?Zzcrxt;Fc77dtr=z)*hHu~{`6&!%V>|WK z5@QDI0Rp=N;7yE;R*~5(_hi+Xk%VmN*o|~M^GJ7xVd}R{CDcz0q+V5}AH-Sq*1c~I5;BnSAh)VLuFfO)z@T``n>|8N$`+~rlHEG{AJoy67*H$`FBa#gH zDS|yybxs%Vr5NYgJ~$!Y8aeGB7|qBQ&&>BGzdI&R-aJr&gWelrd;KHLYim046dW~@ zd((qZ7i;DQ;!vV8F{Z2McyZ+LVfM|C?D6xr95I~N6GAyGr&Bg?dE8B~xjb&j%*buK zi>;a&g4rBd`<{p&1w{~$%JHfau#&=rf<{y#@_V;?J3Cm$(atqyyCJQp+OSkteVA@Q zr7#RyNkmY}cO?IYDSj(seqMk#OlD_0AtZICe zXanf(9DO(vDxDm6z*{o>3nX~6eTryVkU0e(hB+?H(EqhHVQ*qlQuf8$1g7^7_yKK4 zcHhxP75_jJ@3?lf(W!GU`U0~fxK*j%${bLpkWf2k{CJlqbW=E;2B+k9rz&jij$M~a z{K;4+Ek5iIFyg1R;~*WYwc>1N)M1Z|u?TeHmBnm0u%9|M+ln*yv`uNeyA{s)njN;0MP=n2Xl4xf0Y|5`eQ% zWCXDp1z|r`ZmLgpJfc8d>Z#-LVh{0R#d5-C63LFA>l2MsVZ3#_IeG_~K1E07xWi5U zmgljjXpZLx5$)}k%nwqSN{3ggJq3b6^^iaC^?tQz4JVlt2nI=*zqNppLwlN1mI)yX z6|L*_b!QcqMeTl$-Vt~|Kl_ZBHvgW9sMF$yt{O2ae-2_;s0pc(W2r$1|BI$*B5kOi z8Nsuh^_{*{jtYLqhU(gt_m&(ACG9HqxToWQ7PWf}zZ73;H~xs1G^y_#Bk&!eD+Ni8Pr z^W*j6jLC9_#x>OwRMSN}3ogBpNRj$F2n`dt)rL+7A1n=N+2b=TaD^cY6G4p$QGajg zte0Nkd@T{9%D982e~9IRQOr%4k#BPPSrmkVvD@1?vBDK?U8QT}Cz)ZU|5T?X?1;et zY=}%2qSH-I-lA8)vQI@mGf_{#BGLSeP5}9l;PFbiDqmSyj+s&anSE9JFkJf}RK}ko zy;L806&<m zYSn(DN=mU!aob}#p~E7Y<0c~{e8R$B46_4EZQO;MZ}$1;L0tk7gUECGDiPem%~m3E zjJ_3p6K>B)brkVJWV^B@4%j!m8plxBDcVx` zZmi{~Yl7yfCfs;=ify!)qT$*{1&I^)PIdSwrm-QD`+Xy{rRfEHl6XrEhW1iSOz09? z29)`*`KrZ7L#!1#2P?x^q#FZRC1|*?gtfbfVH}}bTHu$h_vsmM^dCms^UCRMXvK#= zi%ZyJfA$N+@TM`_^Y&r?OBn{b`S-`HiCbB_4Y`z<#4$Bm9z_s}7P( z6O6EJ)$$|T*crlm$Ior}3N&(8J5#{AC;XV>90vAc&+EN!ZR8hlEICK(&p^iLtrZC+ z#SjO^?9XncgZk}0s8eRj$4n0q2>o=BYp+s=w91JQbFWe&V~!r5&ygkc-Df_&Z7zNn z$y4FlrX@J;Pdd)PtD7iv!)j>1T}pTw`8N9Gbwfqh-6I>A&pFVy@K#|N`WPeCQ=uVm zPZVc0+Ljbz4HPY&mh`7&aZD((g|-@*WzUd|jMb#u5Gk??!hrR&k<$=uLn(!e@9ra| zimMqotF@El{3$9R&jobqb_A}2edc3DU>GR~UP0yjsaxtlnHnp$K-0Jh$atZMhcx+z z+iR_js8Rl}hP6f_3l2lga)q*cG~A(YhwiHCZRNk__KKhi+Zh@$L^qKYf$WOm{=N#yxdN(RK^Y z0e1M~0i7c1pgP)DSgF?0eRq}NJeu(Cx>x#}n|%}tL?{O&f{P?3-vq1C^!9PQ7UJOU zi4Xe%d2(unn;P+OA3rvAR-}lAXmQoW7)ZOKZ*^yueuiE5je}brAF`HIjd#i`^KT$w zY&8t2t|f0jxP^=$x5fQIirw|9@u-1U@_UaC`4e~(nh_EO4WVlBA;nfNn)quW6J^S5 z8%YCr^v@=#IP4~-Bzo_nk#%JcRhE8^agl9j)?T_B{Brcf?7{2@?z@>?NFshT&XRHC z<%k8t5u-YMvGe8J7>+>-cH?{CEDD@?Pej#}eI$+b8z89#9LzZ&pc<@*lY7KTbI?DB zMDT>$1!Hzn$mq@ zrk0KAWKKG5+m%}V8lA#52?q0oAF*?%3y!mZQP3~t?4HoFZ{43*4x!OYaoKi?V_sm$ zwlllgT&wP`A>-4J$~hcr`=ue+x4N|k)!VVujMs>S;roSQKDRIR1GB}U7+Jn2@FC0y zrrC<0o8fK5k^PW>haH7d*@~+A!n&CggSo1ad%0Vx9GSHIui2VsG#V+!!#$Zly5Pni z1=wX`#El7L*Lw}zQVVh@r+!PhKcUG5tr`H+X)LRi-}SMebSh$`;pqjscx%&Mv>ykx zO7h1GFqLt9Q&4ZDXcnePNP0`~VVR9|ck41u+O|E3VpaAT8w@K#p4p)lx zpS`?EergLe;ZPn$c%pigiEwk5f}W$WjR209eZ;OA@da{>^%4H#vrH~jm61El{N8ZY zJrP=43Eyh1$&E+v`d=m#it+VJ&97D$CdjRzsokxQN!v(fN?zcYs#o{bQWB?L!yY3KOb&8U2kgXW+4ax2WjAr zV$~~rFU72>!sCb8N##=>h%r7Q?)9U4s=-ArSKTdArFE<8ka(rper@$Aj(wSxMyVYw zrKIJW<0GwkwgE_0?6zvMavDsvl#DO+h}4FUm1&t8z?aMs#`XgvL?Oqc#ZJ-WObObu zOLdbSzQkI^`D%+;w1D%uafvN5WQ_NstYuqEMmUJ#q zjNuCH#l&^I`YiGxcbQ|78F_si>d%-TY+~DfzZzYKCnR`gKO)X>I3DTlqi$+e_QY>H zG@PD;hMkgGmG4Z6=FIM4d0!!MzoHbHQm$BIH+tbn4uz-eg14kNDll)UxLr7_I262( zM4h}Se8k+sNtw9+4D(S^tfGwi-Swm}0tmroWo9}C$x68dIo`IJ-Rc)&w!;bbi-tx= znGqsdtQ0iY@fM0cpL)m~lZ3P$+Y|mtD1($zN#Z@%;b5lP2+y*@YGCRW;g%SF-x=l+ zYinydaVnWSG)wS6oJ=o4gs=Iil1KCvqy71*j^|3O=x7L{Wg(!Hzo(vZV^@$1~XrqH14J3-nHgzK(E_L6X+URv1K% ziS3H%Y7Hkp;zVZ6C#9eXTL+tj5i&B1^s-5w+YoSybjJ&5)zQ6H@Ma=ID@GPFjEoqu z(Yb5Eo)<{ppDH^`uaHq4LzfC9oDpQdctZS1cHGSS6&h`yI>@%T7%?B`Gjda zqi(8)OC9f>Y`xiE4=yZJUh$oH%9~H9!!PCOc~bs$a0cU)EVJH$JKiR;+xL=5KH9Wz zZw|A$r}*Gb*_Z6CRsyEZB2Vp17&p17S<41h^v4|`P<=F7AK`V?3wksJV=sTpw`v%? z?4XB1^`JUiWjZh4^SS3;?H7?utlPAizDdWTEE&>l@V=_Wi(HtEKe%oaZL~HyF&$^6 z;kzWLG;u34Hqe4AhOT3)0tLs%WA5%og=Y&rXi6k~$>cV}vg&;jX=&+wt%j58YvDD7 zhHNHXx?8Z5#oK=$EuB8~O@6MrdWxa>_CRN5xcRzcdYH_-^o|@z1qIPNx zFDy{oC=J(}*FhP!KF+C$=)UZ3y183qyk#Onn8v*@ehX6{FGHL{?#Jly*OeikMPfND ztI3e`S^+$~TOjZX*cpOrOp*oNrMcRAjT@iJK}&kZ#U3SiT@M5AH2LU}4B0j@Ri^rp z(K@AaPeyq~9TiTi&8rpT-@=btHa| zcYWL>mdqeAb4YmZ5Un2FYeoKJooDbyv}EUlX4_%L`vmNXW?s#gG=s(VUGi;WDIw zMAdDj=sF!MWd6*G=<}{}DfM2`8p0$p=j$&BVYDy>S=va}!1GjBE(L74$B@AisdX*q z>L~p%ONIm_TH}ocWu@-6+Ws0kns7PR!v4J`dG1Z;-7gFe9qi8Q^K)T_lEoRxq|2HR zvALQQoDMKn!n_c+Fy$`P4qac!2Y-y94rkY8wr70q66wM#r4h*ekzSj1M9*CvlS*|i zK#q_93|4F1ZrPpDW|0U+3AC#1C!%U0s1prEFMANOLTE~bjze5x2PBaCX@g7$MrdF6 z%;6p9vtS)G{_6<$8x?;j85A0v5z{`kSw_HBu6=7ZB9FT}b0PMWR3UHhU6p{G(ePV?U2S9C4>zu_K*T{FJ14+Ir4D%`cbXoS z7v2yo*JMl6&!E~l%%pGhQi&)cRq=8#<53D-dD&xj4=x_vfaa&fo2jUCMxN?yxM}0L5xEguOs&mhBq47^EJ}z$Vw+@`O0GoC5Bqj-06J9 zGDjHnZmFUa!u&Q19zQtv@&P!J>6D!b^`;5G_J%xU(@f~Jr5V!iGFPh95|WTWfF$%DLcjn4La$l`dU6h^V1TRl16(fTG)ub>rUZKJne}_nqH$uJijl*UDOJ zX4b4(_uMm2T05isvG0;g`M3CB=z2nEe;LRTuwHX|-N(YvCxxov1)7!-%sO|EXE!FN zmRbd6&iR>mB*ntOCPH|K0xLG|ZUSsThiH2|@uQeeOg?`r%5xaAI#j&W1O`otD!Y^z zzf=_#zwDT&YZo-M$^S5l#^U7ff;20dQ*#laPm>D&yffqKYC2{}e8iAlFjZ1Di7(EF zDNqnGO4-H@?wlw@T;a=J2*7|Zh!9$P@gGUzxQJg-oqID3hyjgK``PRr-{KZT9VD(JkpN^p-l zvnQp1FB{^BZM0j@5j&BqO7AF7)btZ-$_8zWSD zPQ*{xaCLUXw*4XLnNIiqi)c9g>1iI*XZysC3|C=n{lttL*?M&v7Ey9ittO!yPd~2e zzI!D((2Som?bX^<(-b@2$k zJ`5=i^Tu8G#J=F&^KJ@=JrI1OO8C2LWB&c&|h8ZVaOF4Rn zb-V&$sa-UA@@CR*Sqr2s5W>8ZePM4qSi)faUb)w@ZTjb34xJZ=(x-5%a}u6jl`9n- zl9Z5jc)eG9y`a?!vkc%KvRlc~h_JH42%BXIrv9&^(weyk2b`zE7cQe;@CidWL^Cfu z%dVlnzBSHaqT{rOGT3t&>y%KW6AKmR=Sm=2G>)u*NshZ2pH79|=m~hTTvl9y={=j? z>c1XtyZqHmx>Krl9zc20r2eZO_s_4%Uo2<*o}}5Un<}-w_GXlB@PPuRyKjLB<4}~& zU7qwftJxoEOEFbB(_lJR>TViknAf9!FFN1@AHOzzyVoF1r9l2QbStbbZ1F}GdU6U| zI4$}mzU71HM==;@VS(&`y&|C~^_%HYl1OcIdXDbXyK9p#To=@3j)9&?2}K4l$#Oy* z1;r6-$y*AW3fKYcNt=`hE={4FIIlXj7b^4J>G6Ik_9hvY6&JeS424brKO?z4JZP2O zGE*vra#I34zL#=w$U1ASL;m+Wv#z_p)bLixdg?*5f5p_rxRn=YQ<4$y#`LDF;!{M< z*YPUMUNbv$J<(rmbk9u2Q+M5`kO*^@kpk7+6_*svR%=02Pfz|UemTdBsK{acMYK=T z(P=Ko1A64H2)Z4yH~v=P(PKvk#%%Omxkm~GnC~11dnS*ewfnm=Q7iu=Sm+z`xVsb2 z$dzeP^PD^<@F=0nX%TU?7WQUhu^$aCYy=g9p`8D(Am<`58F89|WNmk%=YyUzy5izT z1djG_t&{dLU3d4_d2h*jd)x2Ji4-K~qeY)W%KrGGMnoh{@-Nr=abp^uu{^fV_QwTz zP7GS(+mG6t;FJsl*fzcw^1!3fv7kiQrwpG5Qc8c&7I3!t>?Nx??<~R1v5*&S z95e;keGrcS)91;1k-IrVE@XSvbww741PAckI3Ihie!Ao>MNj5<--^#?8~rns^;UDfnwbcY93JhV%%9Zo$n6sq1#zhUw%0~&WbkrpjlB?A<@L6!wQqG z?aZJ44e^!f%xxG_-%b(C@YKCtpq?aGs3py%8M;!Uf}OQS)rD-k3NWuI@5RU?1?vj& z#nvi$e)9KHIa4QoNHku} z`fZ8UmV!lxaZr--HQVyu)h1$}TrwNr6ET+OmVC$oJ?2^HDb9XwJOws1L1elNPQ-#o z=dz~$&YcMO^^fQN7Og#bgiFu>VB{VBYu00!Pn;b&JtFNr($<7gXH8V#ZJ*+%{+J7- z?0`!j!YLdlXSJ?&&K7%X%NP{M-U49|> zC+!<1hDx3$A5qTo36*?NDBX7`r1ex~DSU{Q-#M9Hz8s)SjsTBOKX7>Vm6ct!i|^=r z4k!@0CG+8m{za$n#SF?)sbw#x;Cnm%%TR*1cHZ@_)$Cj1Y#>Ep`=|Qb)K6aI;6Y=a z0$U#Om~2@CiH5V7AX}Z*E2m{o&b7n#y^=)?rGBTeh=CYR$^A@3!Bxi6(Xb~o+#>0? z5(PK6*Qvjcp_Z%+wX$KHa-9Q66V^%~}SD zOK0*F58_IsWHgS};46o&?_)R_rsjb?f0d}oS&{dGs4ULKf)X0^IOg=;^9MEIe3 z+vTF^;#X3OL>-(aBAuyR*Tzuq z)j2abAGK$o<5!E}IddwH@4jKP2AlK`1^8lB2o!up!%dutyZMo=w_Q(DkJk3KzRSH* z;Mp56UG#`5oXD~)0>#!nbT*YcV%m8MB^XZ!fgqGZ3|dl*O^5)%EFs|6dmT2Ux#372 z>BomVTe!;?DV*}XkN&L42lum{6>7AG1knHzC~!PN`_+(Ixc684f^{6>a^6V_Yln#y z0IW;dxVYK`nVem}8A;!r0N+RsL<5e^G;Q{dtF?6Qhl7+%a>v9h`4-QzGw%kNN!iiP`jg7{ zlWe{O2)ofUrVdiVMdBcW4Vsu42n0oj09YdWV9CWY8W-;QhBSW19=cyq6plLrA=x<>Q>nFJj`7g1t;VtM)RlJp1J zgqQ*fECQdRDTO1NLt3y}I*PIWLdYz#+%hO++xd39Ocxk6?E0$zdClbGXUe#maySV` z$ZR2tnijl-LPLna?l}B6hl68JtcA2_Ku<{|E5gmhHLvM5nA+N;h;rP~Jf%xswuvil zuTUQMux*@qO(q{0OwKH|yQoW5R|v9H_oG(UoOAo^?XyGo(`_^<0F&2Kb0hW1@F^`@VO_ z&S3O6UYDG}BRana^Lrz^r)HYGnspUB7m^qT0vpewxT)p6F-Y1{qLzLo^9MS0Tn7=< zJQ}uJSLy;!W%!77|M~XBC$--b>n{C@Es7~1J33bpW#r(K(~Ms}?KcR_=|{i+d+gfA z<;xS~w@i_=At7x8Zb`#a%&v1hdTqAp`js_y#z(I$&NcYpfyppM$vw_N?bKcses_Yrqw5795ok8%=F4p>EI#g?b7!DHlaV<8Llif}sz+H4M1 zXtDmaTyEhn8O6oC9}zKzE6SLYi|Hl5S1EgE?_~_i$;roR7x@R$i?wfd7bASlU!b^E zqjiMSWvAp8-pu2AUTxa{IeFu3htfF})@j%4ugX?Np(2Hs(GWVDvum5*Ecwb;uFgFB zv3xgsiB4P1KS!F)Pb!=axie6JLafa^CnopzN{#t={EvEm%dy7JqR`#_(+S#UTl|`8 zV*;0&tb|Yc<@h%6`StG`NFZE-O*!Nzju(RC2}hz zKAV2`#T1|DsA=e}+{!b*_W$oS6WL^mGR?sBADmOpRVSHdWkE(%;rvnabJ!5lEuIK z8z8st;k8XU3eHcHSzf@*#c5c_ja(b!%OY@OJ9h5zgkbW8y1a~@Tcr?@)2w7^k{22E z_j9IjdWZGFK3KKs0a6Z0EmQ{tNZ>af-wiJq7g`p@hR0nbVJ7f<-&Y9 z1Ab+hjl(etvI-4(7tbj0h8J1aUC#WC>imn*O3#)hs`bLK-4Uq!KWwgvlMD+5>KX9+YRY_ihU&LC zQ@N;&fUCuQIK+v>ao%5p8gxyJ!O)tE5*C>em&9r^L!&8{l-Vm=KW<#A5vu-iPRA>W zcEocmVv2yG0d_O5|V7j}IAc^sDUJIA}D_6Z0#D7+AInX;qeceMSgc zWjjE|Mi5dJ5!tD$b1jCuKqY7}vCSN&39`JGk{fn7|Is7y_c)Oq^&R7Fo72?-A{zb9 zPr@aIrfCmlldOJtV~?uvz!a=@r?maug)?sPd^3J%>sN}{%aiPvwdu3A+db6twzCI3 zi8j+>T4t;Ylx-1a>agY|h9nx@^&s8##=;k}2ulNtx(v9kVBaOWjoyOYgSWoQ5NHia zTowS4{Z#_i10cByiFAWo`~q`jtfj%B5J#FXVy}_X=DhVP(70A9`&&w4@r{;d1=4^M zomjm*gskQC`|vBn(r)K4bmjNH*|F_-Llck&r1$~AZppy<4wODM=G5rwgD8Z|sSzF0 z1OYcP*v%8rs^d#b%1hNwN0~`1-BrdBnarA3Zucy=e8L~!P622TGWofM-06O2$;Pwg z*Ij?+2ZC=oCa@WSt5ZE+%0Th-UFr1yk({jgW$j8rBiSs4*U4Gl1S|vBwJ<^{JjMi1 z=x6yhrtVsBw>rQiE;}87X^udWuwC%lY*`HdC-&A+zF@`L_|!Z8DbK0U zbjt^(Z)DUGOyx*kHbZmou%L)p;@l7Wnz6YfBEQzyS(u%nRi>`K$hx%`MW$A;pX+e} zRkpd+IQ?^4+IHg!hev6j(r;VSJd=YRois846Cp~U=Fb4u6`G0bs(uzvCYZovXFeHO zr}i9@BAv|lvLA9hvf$Ad>To{?*!~!q6K`wcB&&M4Pt5`z(H36LxlQ#JoSFG39b`Y? z_Z_a6WnOX2JDpV*O7%a;YfW9M3t_F|9;C2LoP!Rz{v5SZd^pMC?}(n!%A5#!ygu#- zbp-_7S+D`7(`!TtGos*Zd!A-4UQ@~4vH!p^xY9vD#Bxq$@E^b+enMU*=fR=&y%>FK z{m&u>44;-o5AIj3{t^1hAKA!mvZ-CgN4@E&=O!Nr>b;oF2^#3N!bO-t&DB<6Lhl)l zUmI-UJnPM6#ho?uvwX-a_mUA5I0p`daS9Fl!M%j6Pj{6JkGny0_Xk>lqs<(n&M2`w%Z(5D>GGkkM|@{? zAwsV`H&#vzzhx?#k>gdY7NW(_nq9Iy9|FDqVB|(`J{-pei)@wx@6f%_tN4#w#SbX^et!SL8tD%qM{gQUm4}|Lr$PkD#o{VshP8 z*m~9L&S^KBi=bwI&~`zUb?WdFAbo?zVL3(1-!E2PMw zL0h#Q9y9w4mJ<_po6{qp^g;)MTAq&k!%v?(==lb)Mp$l6Px~Bf;^bv))MJfV?Cq-w zlapb+B2;zYmS50iLSFHe7s+7cflKhCIpEkrJ4B6=Rx#!?ByZXw@VsYdZb#O^se9*s zB{idMxsF(_!4&w#2)D>`SGd{u@`UDm_NFvJF5LLO(;k;3$=zy32%>qHIHiV+T6Nd7RxTn3(y z)9~hJ2m86un;Rdu|-F5yGK2PxIU(eAnT{3|Bt0<`W7n zWF1}C4p3)54Y1@4tlwBUK_=}YuJss3np=<7ypy8RB$b&g5)Y_3qGG~(`?a_0wT6Vp zYbE0p4(MJ(e%MdM=k48c2)7%&8u108ypktx-7XQ8O(X$zU`H0H!#@0!q=<=G!C!|r z1z4|g8}BjqLD7$V^2=N`5u1mc8dgnSIq96QWPe!x36e0CKzFEru;mv(0fyMtax0S( znKiM3M`>KaTh^}XRTcea_FAJ;oj}A2czOh%A&M|%42Ys^R&qNdPuYT(R$^`wMs&lAza6EJfTi0;8deUzH&6*&A{}via8nG>$1!;M(h=^pFE^|*5;$2@prY44=y5kOAlZi zxyU8*tj^vqn=P$Fmq`Yo3GTmjlJ&?i$N|GglChe*I-grOTCMzIC{la2)TGSJSNQ1_ z`%}WM!_=H_#NMTt`jV8xa?82hPJRE9t*#lrl9tzywL2H+PKnGD1r7)%)zfT>KpD1UyTsGRQ#k686l|SGqC7^+e@ykG5?bqZ>J6wcke{+WN=9~IT+9n_Z3#Y!L8!%MJj>^2 zhIa0o&lYHxI*=?mBFR2yz6Y-bk5&?K;Ci?^&P42^oB1zaX*bZ5R9&oUg!VJeJJF9v z(w#~n8Qcznis#`w;%4~zuCVw9xU$I?>Zz>8aEMicI!uFNuW0Pr>uPE1SQW`>!w@&o z(wdR;!uI2zm{@=fkAGUag|5dk&+`PGDQISVO_>JTtqR6W!Uw-UCuaiSiStRPDCLo> zo{mmR$LaY*ikjB1$Lz~&IWp0&gnn{>C}NrVj%JCv&@erf26i_VxgF&&B0cq3(@O-QBFJ!L+n;-gw*R-IAr;1}Pk7+ws&o+b3xR_4vi$AXOT zX#F5@eL+dmBN;;((8x}5iHlwd52IS_CxS#vdI%M_)~2oq_?d7cdPbCaPf3U-u>d~t5y8ezZ=~3%oCKZ@ zptwavU|GNf%;n`gI(kd=PpnpeHEhb}c+8v0uQ`(g&W2p9iOm~n81@tYzgR1eCU5cq zyfdOCCgj(g)BK4oZhTM7Zx@u22L&uz__2|bW4Ku#a}knHOaVBSjK$I|8_<%Hp-Lal zrS!X1XdEGq=UF^wr#!2SD%5^{E5(lU(6a*pWZyC47sgjCv@)#GGJ8;@{IdJ@@db3Pt+s@dd`+-5~_|Kb~S{+-MUhVlLkXRMAY zQAuV<$?ng^>td5pX94=L-^Vaw{J2Yl0oSJOo2jz`LGa23)6Q2`ZlmpAoqy!{{jen3)#QuTHcRxw$T;`SWo zmIMffG@bU4U<7wE_0N@AZo#6RNDRtH9v}^lRR{0sU~0QRdC@bmjACczZlZ2l8|f|B zh|O~mz{s%iw&=`duQMf*Oi7PYZT0g5dlJz2j?sZGS^> zJNIQ=PMmTxd;f8^fYlCmSFUQx4wg_o54u}1^3;v)n(XFiQOzbDRBS6{>L&_4G4fma zsK;$Io)F6TWG-nV4~2b*v3fXb0s64O!9GrI5qf8WE2<1Aw*CC$Z&0ZUWbSM{^qp4n z3q2g#Sa!FQ(L}gp{sDKqfx@A`0k38gQbuk&rBHl|(9lq_oK*Fmo<03 zaDh!mdi$2B^ z#h2V~b1RS##CFhXI_|z_VM-}&P6P8byUcD9A9>Tb3C6SPnhff7DS526&a%XA75mNP z6fXkCj&COP-w1QnnW>8k=iEFd!A$egp2wukE5QWmKL-Ua4g6-vXeg9JC^ z)s47R#l%>{`D8T`_;V|NTHASZq**=v+l3wamg)2#)qSnJZmBuqBr)|Q#H^&_V3nMQ zaZ+Cbrum+;<0C^|_5+cj@#)MH=DYN+P~;n0?t9spfG+ht5G+kj@z9LfsL`0hy;{;X z7Gmx$mH{=pB}vcQ$+sLN54#`xkIgB3G_WhNq%D;|g*G7C#w1N@=9@R5ST<=b2jD}h zJj9uC_=$HDT5O}o?DySDp}T&GKf7Ylbes9UZRG9VPVW zZwGcQgp6PXxqLg+wg%z=>sY~)@%$`;G>V;I$U!|9(!U|lrOjz5`mGWC&@`zP0lE_P z4{)bF^%FIgspF!oG%ou^8js6s3)6&X@yD+|@Ivh(gBYI{)#T(%%2lSGL-vwJ%)y5V z7Sd_Tbg`3jyIz1oBpQByy0D{`q9AlqITKQk&3;82=gU%fWRq%pYHBc zMYuVV1bUxms~k{loVOJ8rBF`ETr~oxkfJv)vsQn~%B9kSZf;VUtRrpvSAt9qDwLlFG)!m+- zf;PW`#lWokgwc}HaB59{-f8Xyq$Raa-xZ^IoXAt6b!_nWWk}lcXtls41JFpD;~L|o z=I|Wrv1{ObUROVyxt)p1%d7_IL!ll;d91FF=f$m(9!5!%<->44dvx)L)<>Ox0HB?3 zZg+-HOLF5m+}eq0x@*ZMEv8+w8$0-9Y$I~$-8LcKp9N-GI?fUR00meIQAVmyMQeHj zLZYY0>B_3Dm&G=UEqh9i(%~&f%0JYEL0-)U33CVQK5R0TP}o{k&z)ZXuuN~aA&ck~ zuj|(@47NlONT4W{D>)B>?z=lx0(<^hUlP7@8uWBGGQGMRoE|6ZB+Lpq;0?|SD^j)x zG#}B&qRbB2{10tPp#)>qdPTO{%^Wh3eq-OmuJm&_4fQlva{Seihri5Z}!S3LnrNOFvZ=7w)n)_pTGOh zsDt#R)mpV<@~3{;p!)D)Z(8#vjL-FfPCe!ukh%LmUK)W9Gb8 z;0p42TofHq6TI!7XvS)`9R^waE2(dZO@4o4E@>VPo+pZ; zwT`+~0NdxjQzguR4D&x0?aG7y^$xU&bU=G)jIq{lejhOGkcux>sXPjnE2^I26-KH() zoK4&_&xs-&FR47m8$kQ)Bh!;qb{@MoSj(9LP{ z@FYC^^)A?5%`CfeK6Tb0;P$(->`NvcT>d0ub`g6-)R`IhNhw+sDmVTt*LzOrse6MS zFQ(aE!L3S{&y&;IZN3#@Z453uvH1>fG9x6)(^-_HQ2c&_Qtk$TCS0$&MqMSDq=}F_ zf1oALEedNpj`TcJbTZ)z;?U&UDbYE!-zMBB&n**ufIg73E>U!Cb52WqN%DMX{o+m5 zo*y!t*6OEjeNaNk{6o!L&mT5#i{8r$O{FM!4sE=1Le^WcT-TFgG{u@gKQXtrsZ;-86dE-N2P zF@|u-!P}dcasYq~^3yboyogmiqknuAZWwI6zJ98WF(KR-kV=pIFxz%CX1$a@t<5vC zi5%m5WWAZ)yr5&_#-5=qD9=$439~whX-55o5$+JN53T5i#(Rm}JguGTwBxk+WTNe0%a>`Ao;w{`QHIuv18}r{f1H=STJ$dP1G(L{cP7OcHa341}NrV_%{{f4&F4$-O2q@F5gUplA)Uf%W-v% zl+jUG!p`~$?89A@y75Y=VyIJR(cL;NE^D!Z)5Q2zNzOZ0?Q8V?*d#t|3d#!Ar-vEd zqx{4-P>RAThn)kW!~{Y_%w<_);_0-y*M1xIO+MXFP79UHpH*yw&YYQqEqS2zB9&gy zN0!M=Xn%!TQl}W42s?J4aI#pffdoXkDk*OX;$<`Uw?g2jvWf35*g=T$Je61)<2neQ z8gnu&n;QfgK*GQ!Bx}?5;qz{NkKd z3S@<#O`*p}gJOiO`rx~UrcEGh5Gn@0E`Yv)TQX4#kb5O=rPJL;7Q zLh)yTy#m7IDS}6>s;kP#?L>7)WD2C~^voP{GiBJKuN|~s$V`dg8Unw5E6@yUldS7~ zT&R8=zg$nW=NDDJ{Xt+V^*at*@r&)Zxp0KstRP!i%30m)QR`?Ptv_g2y($E?Bs#h% zm(=B8e@wcA-+>w{GodMSg>lhj_0;kf5I7}abmh`XWv-?1;*2jos>wO1nai)rkL%wH zf^Xz@b1I6hp5w@gU{GupKxp%bkH+d-T3Wt2wwA}3u$Z<=?LQu81v`iq$@AKZe{>)@ zE1}gdJ-qt+`J(R3x`(K_roBsagen8uS|sU3vg8ka8gdBs$`A8QcBs5jD)q~96 zH1D4zau{=hTHriTFTl7#HBO+7_s*!ENKi|h;U|o`9SX?O0g4FYL1RSA+iuf5;2&UY z4a4`GK|l3d=vw@3QhHCoq9ZbAZO9fmqNP}`13ee&7Na3|2gf5{wzp>mhSUeL2&HO| z#*T=Y;{29N)XVq4hy(b&qZfDX0HhQ%3piHHQa{Mu-g0ly^_IR&*pTr2(DK*qxv$>t zb+J-SSz#&Z=^M+B#w`$8S4o(q*plLj0Uu{I#v?_uu)v z`PQBIw}<}Ej+%=bcW;Nk^c_6HeD51wdif4>QkV|J;k*n@C|MZ!{qG|#$4qgd$xbN( zQFy|x^8a@v*>&PI1Lk%)Be#(x2=i3>-~VGzR2ThCMe^#Dp<)1~2w(E=H2>H6|M!O` zs3pRc_Sj`lL#1x<@F=-^HQpcfqHo>v#|^O|gfXGVPKpD(aS9wp@=f0}o=1+0NXQGv zZq?L*{0rd`W!7S^m169h#55`XXmxFeQW3QIo=HCDzq|Z*7RNt-SP>Q-CVrwCz{_#D zvsEfNp(j_<;x04N<`}|)s!3WIo2QX3JpFPScP=n;21K0#%CRpSXr*%nDmEUID-=uL z8qg!nptQ&H^4^sHG*hV(COq3E=q8nt4v*?5u*uB!S$ISmZAP4qnt=;kohi)A3(cc= zKdGP4p!Z+Y|1PJU6Dg!M?``Wp2u>eDL${=wt?8DaCX7{~iu^_6wT{-$WntVSs?O!h z{d0BYLw>f@{2Kj)w?Bo;E~Up7>2Z_4^Rbk9B*pkLcxpfZMgyZjpUGrzvUD5O4301VJrp++3kXG)@(g`h;PNJf=`lsobaDb3nAL6@Si3YKY6 zzbm2;z|&Dz_mvA&vr~&IxQ~sF(X7Qx1Q-ViT9@XU`A!ny21J#m=cF%+dm^IBOO^*` zFG_$mggBp%_t#;8I5}qS=z|`ygcv`7nw0Qr1&%j^wPMYgsXP2Zw1iyGamnE0Y1C12 zh~tSf75plbcQ@BWCffKloDrJgUy~Y>mO%iBeXt}r%C95Yknj?br_|N-g_wMn7g@-r zi8-`K4sNpp8gQ!-5epo~tDL^LN%%tNCBNUrI}8z&qk`KhPaVv&xGw_c5ufaX3c`q6 zp(hJNtv7VXaoJioqIxM?Ben_7=XFPiY4(*zJ`FbXB&6ssj&>&CgVS;4Umk}9dB88N>Wp0caFN_NO1yRHGQ zBXn&Iy3lF})gC=Ma^$b?zbQNdYJ26evrKrYc>_f2E$>~#trzBZDoEgDAT(^}wLV(FA8?vxV zKgi{i@^h7Ae}#fQ3KW7*wK$BtVonhZr9~bZYaO^mvN>DDSh0G zlCLek?_WGlZ9l4L5`9d*9sc%JPHOArveX_~e?h^sk;Rz@dx6L*d5I&p!E)tU_!WzH z_3>Z7*8o6r%9n){^|x6eWp5n?ZY*rd!+tz;l_rmsv~rQV^50q6w{PWh!Ypkn4%;r_ z1jelfb(XnXHr)|k*r7|;etUZs5*v$hEX<8DXp!)}ZD~R)!ktiV;CX4yaX}-T8*q`q z`#VSYf_IkSv;1&d#NZh%$@9S;RpPtSqSreR=bi_wlh=f(Q^dG8qkvEPA^zh$!usU9 z+}x5~z5XW&M6*XHd=7)1=xRG4@Y2MO%2uPxl*0E~YNpAz?}}Ubt6MB&<&y4>yBUD+ zKvtVH=`J( z;)`V4T+GlV)J`dk`lk4!iccpb=5d@zkg<_5DWF=VmBa0Oy{okS$0wnbT${XRd#+EN zC!FKLuVwIIxBXY^6qrc+nBzSGJl8dcIJk9zUK^&Ya`%&gYmDrL%T~f>%}@GLJKDCX z?ge-Lq?tUKo*60b4T3UkY*tQ2f>$X4=^V&Xe)x8Gbl_$e&8U@VIlFTR|8@Jf0U_1& zjx4&GD)u+&fO+_xnN#=aQqT~6JiL$)W|}8&s6FewmR`@%$mIH;_ET>TK#ovv!1@M= z>}fY0hL00_I502WZf<>b00X-0zy=rq#$g@~FEx`6LVChqfdY%sw zxVW%Ztourn+qKKJp~TJ2L-Ce;AHA$sAgKC%GpCPyj0he|txF=|qh+hY2dYyY{LSa_ z=JyucQ(p;eXEV)Rxo!2SE_Ev*_WoC`ETIh%Hn8wQu9z>rdn$cFG%zHHU3a}?td~)?f(G(^?B97h9=@cYUXeIO6@*!2HQyZ78~-0 z@iLZihypQ(zR;8`tOzk9aK{>dREVW|)<5!Q6qFY1eot+14EdIac0Rqk2D(&yH+5pz zG65;TXY&>k(HrFNhrI$_)i;-j$PhRpryyu@y@%|?T~}~h&=s9CK56||=cj8@Pt4P= z%a{bMO@{u7wA_ zCT0cZ#w9ZX(=}wJQ;%8~OWmBU^-?zdxy`VCaAIDw4R)YY#`89vUnIyyt34D^H#1DV z%~%JMKGGvO5N3;A8}6_By4iGR>M8!klyE4r=Q85XQ@53GV3;fIdx_%((Nkfp8Fm@K z&4+_OK)wU_&y6yOSV0AD&C~mWkFjWr-yri3%c-4DMF!%*sE5sSG$*h2!8)_X359c= zBR>ONa}<3DyfPV}lt0Q09YW3L>&}KBGZnWdVh@6CSiexMQpPOd)2L$EH4_fVjyGYM^+!9k=Fg##sH+(jyuF_UT zQ-u${Y45I0&;S~cM$8Hd2X~ziM(t`<)~C1sqO$phRzDlrY9<7n=ekQr@racLPSnY!F3R6M69^IO|R?w=3WoB}CC_EXmtbuZwPs zE0{bE#MpH3vdGR1Mvb;2tXA@Zn7@J$&l7K_x`5*r5kux;$vrPW)^7d%LFos)d=j^P&`q0NO&qg-B3PFws;L}S zm2BOt_NCJCk>lsJU78s{OerLQnZ{>Im3fn~<#+!!79VrD>GSzBY21l^UZcKZc(~(&4Yq$R z{TnPC-FkgkUwOhgb*jv4^?bxbo}%IG1?u%S?iAMwFpjF)a5Npd3l^P&C&S984+lC` z#!WeP*F9B5Rm8!VahtvN)M%aAXQaih8{6P$n~1fe&^{kA;T(K^bC?8S#pl4FZU`tT z$n~dQrR{Gnz@x8|GUpMwYHp?t^%Bi`lka?Xzjep_?V-yq+A-R=D;@rlZ!kV{t56RM zH;|p?n{~R**JaUGO{sM)VA<@Fmdb7KrfM|foYNl5UBtIy>G(CZwoy^gu5k$(Nw7@F zX{l~PQXDeOo6CQn7Ob9BBBS>cSLxxq7`Xhd9vRH8a;^tCzOXFxv?2wgUN%?z7+Z-A zcnj^CDwxJ*T3GyjgnfP-r(Sg#6N1uNEK{yUK8BBSX{CL{Nieh}nK%n|O~-_a9xvH{ za|Z6;ZWYu(HM0}|auC4OgBMg8t@ECLjS5s15QxLYsE3e==pEG`htWsR`f>HKP8c9d zg(x=3W{x2UPfyVY=fuCdwdH7U%BJ3lBAQvb4{@ujD)xi%eHO9!h^LcUIRVFY3<#hI zhhlz_fKpIlg}V*cs(+Rd&%ZR}0gA@Oyhi3*?`#w{gEe`#OiJJ zBNRNF?BY@0d~1Rp60)*;WKV!;8Q`GLm+$2a;ch@$u&H zplAn=>IT&_wcxUiabFGw$?q25>ZF6YQ|fJkJn~1%?T>0Z^?6BT75Y@6+q|-cN8>2(_@7L1e5B$1!+TuR9UZ@ zJxS+M*GuoTNY8P%U;%d#>Dsf6b~oGJ4|)ad=5kKC!MKS7dFi5z2dj#Ec8{n*2bYMs zBqr(M+tmlR5KKQIaer$=v|x8KXpH`efOZ7q2m)=i((wptAHbl{s)gR&tIkzZHzzXr zaTqyy7cEB{MYqIc)qDa3dKQIH7)3I zBF<@?dEb%v{xHz*9^m~YII(nm*X!V}CCsOIbienbo3YKTPOPfk(kT><29tx*L~EB% zKx+49g)Amy8q0Juqk571U$Sa3D4MSMJ&ua;9GGz3md(|><|36-e-VFLWe>iIN1qS3;aPR zHmht;OUc=1QljctvkIgk!GVRrUukX2O*YLFHX;)wAN&{&^xoPcA;aVBv?2B5v-#1J z&!f@q{!L;_{{WvK9-QQHwfhjXYKjjiwUc|ijeb~ooz0bFOM!}O`Ul{g@h3GY;(Y}5OEP5O#VJQ$$xTWEC5$Fr~x9FN`bQYDwEZZ z33w}mt&Rr?T_i^3_1A*81eZP64_e@3L8djqipx%8I+UKfR(-ei+xeP0FVwHrbCcfh zghzR|1ZH!;M%AYp%=msK3SmYSmRbVXjEKLcZn=CW{Ev|O5nvq~(cWEwesjBR^ z@OeBpyv4cAna}M4V7n%$ci+#C6$$-iLYixcI-@U^Isg|ultq#zk)(w$)bOsK3AFuW zE(w*?4*v4jorgYqgSGd_qKZN{TWA$>g+0p4KTL*2dWR$@KP^gO9=}z}$hdz)IMUI! z4QM3NWTcJS`L3Glsy5vej*;LolMS#pVgt?v1#=ybx8Lr=HMgkl7Sm0_f4KWVro}|Q zWk5%RC8h3s{lJz?Vb(f9VC3`#()=IJUH51&w`Gp!4H*(vG1DRU~ zK{q|G6|U)d=wTf{qsi?pJKg zv4R4LS^5*@;}dAntEtmA()(UNQ#vbs|M~~`PXzY-<@J153t;$5SJ|G%gwEVX)NnEp z<1USkfJZD^AMl+0)xE*Y1W}kz+ZIHeJ<$_J)~HvSWdr;&5A#&Y3n$JN@WT$n|FdBY z*XpSH+>vxHOt?E5Kp?1Apk&PBo=zSVr>kSC#l=h1!Cy-?9-7f04uRBrFJ+P0gJ-FL z*-KZgk7kxn@+uZQ>lcA*6Z3a(DLe=ragT^hJto7`15j=HeaH`o)#{6;{{hAoQ(yf9 z-0-0(sF*JWLP|UNZvh$J+9y#hJ_LvjNPSZLAHertq@>1~j>&i4S+C17iMZw4qG0@1 zkxGfDNIex)?YFL_o$LdrbY9z>yF|BLNE(#zcL4MygybSvJN5fbGpo5M7 z9Om>Q?jynX8~iLwIyyuJ48U!-!8(T6;r1)E`!SD0r>hpUW_=Ubrx-Wc%g-IKSRX)k z{%BR|{WJyMoOV#6q0amp_2Lmpb7m>Tbt9)=gl}BQH+}v&!WHO%hQ7$BQ?q*JHg?Zr zsrpua++EV%EmxK?CYIf%KX9!^1NEb`JfC=Tgbqg3o`b^u?evR$->@j^6^&BJJE3e$BmF9UhnsP$sdzs=3e*A84j!pm5kKS(b*K))Dd(0uHzew88X zUvWYU``evMTR#UDA^T->1WSH)1(Up;${ZsTSem!lndC;c(?)lPJ~dC-BHw9pvDiEV zv0n!BZ0u2>Lxq(hnLqbDa!v499t6RgPy@)~w=gby&2ug-h_ktAeW(=QURU~}*4C6q zVGPL4Gm4=FOC1A72MdIl=c^*!nHSO=-J=ludoUnbUn!y%BR3!vAR~pZvf;^@0IE=! z2Cu+_NA~-P&Csu02hM7mm5LBGLD(r!W*P<21o40KL5}vllg>+mGu)p(pBUo308mAq zu^A)1I-lW4DNvH#=SnJ<$AxyuZm?cCjd(=Tm`=IF+g7A3m{DQ%AF7cqi_-OeoAj2` zQZFib6=n!mvBRcB`PS+ZEwba>t>Vf@-kZT!o~Kg{(b#;Y;&FESAW5_0(~e3+;92-u z^OqwqbK;~}mHr2z)pusEF-PdpUDmk)oB15Ig?6NDZQDQ-OZ&#fk@r=|wC{Gx$e*&w z2}lb0Vac~w0|~eIcB4`eDP|upxQ8C!Ogxt2=!~4&7j2}65Q7~HA(bdw(}`qpqZ>=6 z(C3Jo+HI%Pj9VmIrfK%>z5#X_^G1ClMqxX>L^>weD9Os>vB_4B@;KNq0X0howr&`1 zK-}-p!A+(m*)hInMB$-k$wQithz*6|s3n?3A7^QQ3`$&`&)04kL# z;5zTre^iTt1Xf6p{Zp!kEYJo7h9)50FoC(!U9!HwGd03I!I<}DC0fpU5z?;AwUq}o z?jPfjQMv_|B&;|DAkWzyM61pZT?kijV=gH2sKJMr|wOcByamX*- ztcK$(fKc`gxx}kEp@)F$k~WJNQLy~W2Z@<#%H4sP#|sKk0ly|`}Q-4>^_NDfuc^BP-5EN|3I--X2R`J|RKFOkoS zt1EP}xCz}%!&HlWztu)_4g-M2*D zRt;8f1TRfM7_7Z=uqIvkcHl9g4di z^=~$!g+Xf0mB|^NRxC5Me`%liem~dGfizZ^A&!dVR30_HHun^cw~e!KYzxugYuV3Nz>IQDqKxtGV3vG&EaB9TXk#au3I(zfv89}il7+qVZYqk{5@Q}qs( zYwC+Hk}D*eb&X)^1!Z@p(u3kaE_#Av(g&{1#wu(xfDe{1wi<+-T;oJj;X$KCo@jK` z6AutQHYd$p`l7LQx1|J6ftB#=0)ywW_%j~mIY9P`7dFxACop` zG=!W2&a6&Jm|l- z9%MPVuj9mAXBk#&v9+b$JjNFu(l&56mc8^s7S=Z7cGe)r77F=Jqp5DI4i6M;*k5lA zIqg!7qZI+y`C9fifm1Oz#}DN14U-A^LJyL$iu7)O@1EMd(pY2Sgiv|j^VLxMwiO^X zccia4Q+{OAI@c z(IbyDCo%wJNR&8yL&sw;y zloC`*h$ug$3%FxNfu7yCVG#Fu%Uj~MapHN6;f-vmAb#oUtFn59=y7$CjxG4X4TB4h z-mD!EdCcEQS1PSkfra5eG56rw$d8uD8^Vm+7{q;SHCVjJpSKJ_#}WUt_fSUf#htMo z-}p^oB=2up=UWRz%ksdPQhdyz8drpkM$}K_Y5<&d<669YYEK0=k3CE&UX$(jm**F_ z5z&|baYiqey}%_%Z8<_YFQbz9IFB>7II5^l?Jek*wpQ1mS_ekQ`3Djw!hFw4-^^b2 zTH@zRhzqOqJd6elM}>!v`oJt9NkgI24rOIi)11pys5>3;X+)R)J`l{vSC{Zc&cU&P zy~6LTk8B>BKC=X#fq(b*U6QN+FOoB&d`(bkZHrr?qr`+(uwKuz|#Uciu?T06}|SK(5_vkL|349QFQIFN^^s zNT}dDqX?F1MEj{ULEO9Lw-V17yykF~N0`cy>?g<5(xy{w0*8-n#l*JaPcMSqGySeW z^kRziEfX?{20YX8xd6`OB+yL_iDO9S#R*FvvG_Z`m+L{RjtsSjS|P6~oT{JZnu>Hb zX0z<`eW9*%8WM8%g1MW*!v`$T6BZ6Hjzg_XLV0$sV|Bpa%PnoH07S#zUHB%Q*4xT= zjt=e#&=k*=$n>E%YHctAc7N}lTNfmXN>UdhTg|68Ex^cpCW&VyfBo*t_2MH7HV#s6up!+%ZZ z@qe2+@&AC@H;Z=v4@wt>2eJY+VRE+ye(cqq*yuTUF?vP(w{GBnC`SLe;zH?@5;zzb zgn^z?w&48W*pR?DhW$3sjT=qAd~kgjmapUybKL<#E-w3)i#WJcnD5O9jdliL1%2rk zm@k!|sXO_4;d}J|pC4T7lv-P?+{vq^DaLzRZhpzUd1-xq@3!rkv?M_7_ynEnQ8vmP zh94NPhTi}VKt}+xV++vk)tfz7p})?+Yum4;j8r=zQ^0HSQ#2TifH6bsIb0%NPY?4+ zQfVg2CI-|L=d_k;|7>SSAIEn@F_mfufx3J*)=w26{pyzw`cNaNMzBh5_^FfNeFY*S}Ae|kxE4;_iFDvIe=8mR0I_?T@ z#oYQ4*vYPE#_mF`_&5rMvGCAJEoVg?9K0vZz54V-v)vKi$?Q_{d1z-VX(Ij;y8#HL zqsA#+k?L%$xrSNWv)6lAf_<+MaoO$ieEkPLqZ>x`nNN@8e=`}5RE1Ku!eC9D?282B z91>RtH%ZC65TAcH5%s#4q{ypFL^?|uL0W8Rd#uN~u9~*m%CT5qYIyRgcHPxml6O>$ z>uiuU_1;6zDi>4~yFJ0)VqyxH#*&pZz(o;`x9}sDjrrZ1>kWPLrB3zk?fC}zS|97~ zQWgPx2}YF{t!9_(025ZZW_s0zti%4rl|G^1x*)K~!F)1o;(l}}uI(nlkM@AXjHEc^ zf!;Co@!zAA)6kEjE!V2Ygda;zF5neR*i`AeQc@bH1JI=*&Gp;gOha51j5U&X$Aq9-SzKDJhKG1Jyq{h(y6jT(p{vIW316M^Qh@k;__WkPDUJ+C2OlY$GsSp8 z-Z)iXwu`mS94LxPw-%i&=?6!$mJ8b_BhCt5_AGkLQ!v97&m<*8M%|oR@h1(<HlqtpTB_>crZGHY3~2S}hHKE_g?5Ir{=BtN_F5>yrCyt9vyJbXkNCz}~C zOG|)HhFwF;y?E3rrEg&F^gP&9?f{CZkVv;4-}xH3nRMY?>tka1Fi;RP~kmU)~5?BZ~D~) z_F~zCI8{M;6E?L!4Ilj8Gw8qZ6darZO1I`?-dzKMJrg@(xN-bETqzM`O2ujDCoBw~Yd|=}&>lQLGY8HZP0t}hbPE=5 zguB|Q9DSQ*H2qY!_j0Kz5oo+doeSKX+HsAK_dGqCc3y;IIb%}xr_QoN_Vm{WO3zO{{$ou22ag!h)ALY1L*NXZwH)_ zJ>&;#aSUQC&dr_dj>g7njLF+Pdd~fs%xg}yHN5wmHR~B0JYVGS^`5Y+v-O1}#qfFfvoDgTv2RD;Tj!HMuFH1DrhjLD^! za~O@c86E48>u;O@t8ITi@>JqvBEc#m95`Ji9P5b&^Mr5nztpni48ftuuXs=6)t`W+i`+6N zvrZ(U1#LYoFgXP1UE|$ODC-LK2KK++)+4OTS&ULNeEMN#cp6V31J+jG$$8DgnmEvK z)f<+PN3Xj1Y35HrEMxc)F!pymT>CGy;s$T`#&2T_9t$`BJX{^*8cU}uL|k3#9enS; z@s(jed!qBln=*sXk0dU<;_i#Q{C`>T8mG4I|4!1%z4z>-2RV$=aUcIp<#2xP3He~! z?ZcvctBNO|Rqrih?_aX~Wd2)r|1aPEA0xrCxSN*e)@UXrngV7{dS=cwCbrz*0BY$d zi(Okz+uEW$=Jh#?i>Tzf^Vo!n)V27(nT?%>r8%_Yvz<^buIciq)9(&*hzwjbVkvcw zQirU7N<{%eB7Zz!oJ?{P$shSjOi~ptxnC#OA`*H86Zi*BAx{NL7Epz<)FUv;xQQ+E!rf$)|01z_;z~nVpdN&=4N0|%z&pmwFyzu1Z zD@fHOomC^*F)EP((!PC~J#+xIVKm@bi^OGWnUa)cJ2hUqgkFvD`>QjQxsN`6(mA<| z#R0fJq`N-NsVkFYR@bYaGY5z>8(MleJ)3M%RuLhM2cy`uCEl$uAQf6#w)gN=)%AHO zk&H0~EIUU$U8a>QR(+6URO>JS=0$Tz9nTNmw{(Y6oZ_s${W#9gvpxomsB3kvje;SP zesnX|OmIyNQ7A8y=(I>JFmy4>itdX)?gxv+cwo;;+WR`N0I5bLJs>-J(p-wB3@a7P{%Yya3G}^3W`*b_hby z)#mQs{7c?H3LX8>ChF>LV;7da}P@#uMug>BKC_gTVeY}za>gxAmdGD=Pt(6>;9T19i6h z9vHboK}o$M&zVwT0{u13V71jpx8bbL3CB7@DugFo9Va!9$f^hC@2j{D+h*7t<=iJf zBe|yc6{p@2AehwE5`QLuEr6?F?5qKw?jNuUfS1lmB5kuaQqR5tbj*-`^_WDsv-xhm z>;*0+7P||+>#sKi_vqsg=>E`la<64xcWENex6U`YsINqmP2_-Yv8o*#FLmitkPOu@ zS>>BAq0KHb%;jXvDKUo!tBjqiH04Fc-Muu*!yD?+Z4AQ<$jvsNgyuTOA_SLI$^8lD z)s28CvF#vYaP7Vu_Od*&wTk_TwJPp{1MYRfK}dk4jCA4y3XggMRt2=Xg8*AzlOEpM zJuwuy5j<8LT-c_jjg2~%#Y2vtwfVViCJXeYuz#MHR2E$s()UzQOSF00VsJ{(18M%` z$5jTGz=r_CLPR)ny$v<7!oGO(FkK7}?x_m`xr9-Us8#Q}96g$vR(_@YX?N(eyD@M7 zTQRe2{uJP~8zcL*#W*qSjbPt;vciKUJUmSb+j#iu?8idc`{NiMo_*pp%sBftzFIye zGi4k&khb*g-;(?NV_u6Eg7@<=hqT(OmnI$>Wck8%iZ9#aZ$>qobL)5B+X9pX@q!pqcZjO5UZjl`!{sneC58kOldnlW;W zO`7|i0b@xEO$BQjJ77i(HzwvDR8aZFx?Rt{JI$!@7}J+tNVN2oITBrO-N+54kD^D; z{I2;~krs$~Ekvuwhr3q%@xid?_iFi&ifO<#fVTKMn+igYUi_BZC!879zz2WT_N#{c z(NzEH^(iw$(ys3JleW`ycd{=P&PRT_Rdu5#TJ#qdkf-Bu{Kot7^DOUwcWd9$C>RAc z0pifuT$0)Q?)CUT8GihKd%qlQEyg4}8p$<3|3~{^d?aI??voq-lYrG{ErZXZvUnrX z`!r`r@rgS6Z#b|j(-GCUhWH8^7Gn57>OcDTY^hEp5A!j<^10Qt&|m7Tg0VL(>RSkG zch-y!`t(KOY%`L8x0W{5H~y{cqHRxT>KO*Fv5T~?<+V%$-Byss1DWn=)d7| zwHVMTkN%T>zbc7!n$f)kTOqJqAU_%hHCs63{mYemXUXi-7up+IKjo;aN00$rKk}p~ z`!)JoRZ-B&Fz?5Q|5lSEdcLn{ z?WVoJ!_ZFxU1uyw$1gEmRdVl**jAqmwfKV>MI8L~?e7;JaZ(wBI^y8_kMGcQnJxg8 z!b||YK>#j&KLY#>scn0k7j8;0B@#m8Fa6_2Uf0eBzW$*1N!XYPOK`b&l1>iFOP)c>|=u2;}7z_|~4 zp&t{c!Tjl(>^#jaLGK=bOT7pz=CP;p_DHwC#?VlKfR|9S8M<|a~+tkL+Kp=m| zpPOOAWqSwns;CTdVez(aA{^SVrUDZauzJcwEwk^^_V?|}fJsHd>e z?1wcUL8g%g6yeenK@wJrfD)fe4yoR>grEVkQkNWLU`9hcpP#1sfpx8y>Aicx*IT$B zPmq7S$uammCUIelyD#Feic`v+Mjhl8JwQGCvg%Qujsz9P!^ypyT5OX z#wD<&inH^6)WcP?{NZ^ZmH(0n>sC!iKyU=}Y7p&@3prN>8mn(%90cAeWE}UzJwLDZ zBnpAP^5wT9#WsxhiH*K?l*~{flP})@PJzYXbZn1tg$lB|8z9RkNCoH7TY@EEr+1Tl zQOW%(Ng8);D(;q#h`;@Xrwi_a9( z%S&G_WRo6|IUdT9^by=Y;uxE%JA$KLY>~}L0LO?Yd=?N#KaoI*D6k4ZJ>O(F;|Ut& ziWew7t2UT{0_)qAKV6od!DD*Wf3O=bz&tI)a^l<}J#4$ZLTXQ5PH$Y8#3Q`a6$c)=%0Z4Wb$ff_l;s<#QauM6Mu)ynM|=OBxeV6PtrKmuv({F zP5mssoaKRF5s$Fr53piBXj$>YN0u&oAjgC^H8QaMX#5_^@aes~@x^-L?jqhR2to3F z@=3p*QDLXOB?v_Ar&sL|F8Guu2Zzg1E~amv=b7?ZMFW*g!ZOG9hm6#L76#bvf>5|% zG0~KTk#77fW4;0A)~iryPoAddmvpvj6PIA1;E1A94&%3}?6=_)7V^N8M^@8UUrbAbQ2_U|PA zr7&>$Hx1Biao$9>9dT3M=w{NP=v%TpNl$tr* z`)B$+K4(bL!O&*ZV^t)XcXF!RZkYG{fTR=@TW+r3($%=?mYR(e8_${g6d6;|R`^q;AxkY$BV1X$u z>Qg_j3VQ}rU_JmUNIw8w#R_Je9?U8r?)}tsiJeZM@*=HR`l=y=E>8HZ1Gkxi6a9Uu zJ{-eGe*%7Q;e7rVXM%Jzg3~p-`|*+kkDBaRljTK|Lq0k4nouPCU+SyqpV>YG?u<=( z=j$vAtAW4Ue2#kNFMFU?VVML;1KFv8Z%nHVW$oU{(_LSVv$KSnOLjnZ8A)?W{p4i5 za*!f!utP};6EEV*37dj5!4AIoD^irq=R79Y@B%DTP?&QCcxVvUHV}<|zW>{4uU(&a zA=)TM4Oo9LjO!T~a=2g3N9!8YTcHS3?@9=&?vtCqU0O<=nst4~7eS7fVF4q0*DYIO z{kSiu(q-F^8%8EXF=-4rtk#AC7TT^Tzp80YV$;topX>wP{mPVQhNf2`@56#0IaN?8 zEOWZ3qz#w}lZ>v-B{ghOR6jsX_JzV}Z5(Z*t=5KiJ}3 zK!$vD;3F(xB0ln|H`v~JyhDqk-_IMvO0}SgO+Q9?DEim4@7vj0$wkjq-b?LYVtzOG zt^P#63Y-tfqpm@g;@!(+YMhsIzh}>Y6Wg#rJyB%`q0pJU2;FQy-L*w8>ah5Uv?8At zXz1a#KzOU^O-1Tdz@Yx83hXlm7Ky=`oMDpq$xV#HeHq$|(aIq++ln82Wz{b)cn0CE z#bU-UIC8KbZ{+lILRW9)sHGr1ZnsT{2vSiPDyVI<PyIfs=cHb{7_A+Gd5s;q(l>zw^PTNtd#CUY^c9sDE z6cDaWYUrD!*t_N;EKWsgNK?*k;;AVLlzjC&?}UeIJeTD)zE$E5r;o*AebD8fjtst| zIsfEJ&6|OOMA?&j=n3}lvuJY%dK{tF9qnOYd@B4jCZi$s3P;U7=z3VP5H`LNoPt(4 z_o7JZr78EToS}68$z|4`4!VpUjS7ZYN{8ZOETn5n&&fXeMC)>w#%rqLiy{D%(Rb`F zzc?}Fw0RO%-5-%n6n6&O z3r7dCexh!S7nWKTju6k1gf5%Aln7<%bU(q=@7V@eme@%g2r%q6JT~c)XqD_u`=~Y% zA8e3RrhH9bkZ`;7K!M*;FAx8adng%YL9#XB~HChX+Ux z&@rfU11!`wW_GGnGiUG88}^Jl7IVgLa9>7`ON+TKjN9p(dovIUsz+CLCQ3lKiNg3= zJ&!DsH;qOtf?rP)@+6Z>mWe?8_LJ8(0MrctY#u&AIVoYOR-QWl(go^NS?o2|Ip;bqyLe{jku_8hOOzFEqMwDSz$>$ z=Zk0IWWL|Q>Mz!VPNil!Lrlu<0s~^6omzR7-W_kZov-aUA1BH0iyCy%C|NSxiAJ=_b`^V@1!j~qwXFd%_Fb*z*4EB5&^#7sZb$j}`v0OfY6QhLB zWu(|dC9;Ak z&tUrYsRd`)mgaqP0#tv%9(Uy|^6mlHtXlZK_yanOlGj4Wq*i1tvcR)R|P*U6lB&Z$<+IX35qybT}T;%gHiZ?Z99 zcbON0fv)4vT9Xj&`BIZMk~NAjEI&XxvRP!@pil)Ue_Zu*M7ti!+0uNhXj_2k?>Ps&%?3QE-z(FbJhoI;DwxC4 zhCb1rIe@j@6MW@|A6K%iSgI}M=t6l6= z7=Eb5bIs-Np#E)=__8O*^gg`1S=YZ%BxsT@3^ zE4tTz1CPnQW@Y__dEXcSEbp#=h>Yd$O7q;@$HCO-)_jf}%~mQ_p8BQZe5Z3*3&omF zn#*?BTdjA~EuYp2g&1vk;e;k2H#yB+O_{jnOKCfH_MA5Padh{V`?tUX|jI;zJ5)NS;OL$ zah3DQ%;pO0mB8rq1U|u9>sL3S%?4{A&kW#msXoD(+ZUy6!Kn6&VP%E)#x*&S2+!h0 zt@Tx~V{Nt|^N1)vQckjRZjM~}JpgIV1U;Xz=y8P|KP1o6oEY#1qrwMr(32Xa!|ggn zdIollV(X^N?Y4@$93sq(0c_QQ0hIO{s4UF(xn$*zyM5A|jJ@INz=&&7(r43j)5$^@ zD_I!$tjF@6%`c*#879hG=#@x#M87 z<{JpkEdUqwYamfjzE#ci{jPl_L7TMK&ysBEih_#L`=(tw2v-X+(DS7?n@?ox-8cA# z=RaZBCRBH8zQNtJo;=k^WKK5CcEc$(C%#3gYl9T!-K$(9ny@Gi4bYe6Dq4wdeH|NU zv+S=0QRohESQwk=zrvlDYDb;S`pR#!Kajt9tC4pdNv0 z1U&*gM(+jnloVYPDDG2|wdAgzj7apd(2v;$hiEUVe#r`BCtVEOqN6RaQsc@Nwh00N z)f(U?-AX4C=MdafCOL@{5Ih?xk1qHoQ?O(HDbL-%8&=5K1VqYOcPN{ohe=3PORy=o z?3CiDRte2>^-gAm`as03oLN=t2&ZnB5aw`29W~cbGv}aqC!hBkHB_V^>RCz4ZEyYM? z$Ziw&(0sL~BpkG^9M(q5Vn;;Hs7(IYKArG-57vNZVz|8CKq|(@l`Dj$iWcddstBvD zOJMc1SGoUum=`BM679sqNlA>_{O*uJcPeZfjp@)wt3?tB57?k zo;LNf4*_Pbc62djNmBOD0NtqsNJvRGU0(V8L0JAf^?fMnuhwx2OGH(`*4CG6ZdjR~MdT~8@%ghlyI zrW-BrDR6!9o`bMlmR6D;xk}3LC{XWZqIlj^PPZz7nIiG*%&jQ-2*GS_R_V2_9x%wU|In{ktKj)#7+hcc+Hd!qqlgjf?wU&%c`IIB?N zBHnT^tCo1ji7bjxnZH@FNKlGI7Mum{I^Q5Q?f+||yHmjVYp-aH~dnmlVn_^k7;A%@`;I6I`n z!rNA(*2COMaPm<=s=)qMUm8cd3jSX%mFON`j`bFj$LMvEV>QX>eS;1hwC*c4=rf|OK41VR*jO7*<~$+}s^mf6CJ z(TYsFSORQToq2E8qh?II(y;!sn6E~gYugu}`7GlIU@i?%VUpv)TLa7yn+vkT7hY7s zm_STZ-o^eS~rzH1(ZZ18>-z19;qdH%){tpOJ;>^!9o7OOOLYCpPZI@?$YMEE;y3In=91` zp@3RaSD5WG3&SjK8|lluM6lSLgEsGGjI`qAL0XlQ&hLy4tI;;W^JdT9axq!k*da`x z1HcA9kM}4the~T(n+$2gi<@HM7SaZ5gM2qq#e?WBhpCNy+m34N8k-gGZLWt2<=+8h zKYeX9DI|7{r@@V~zwk7e>O5#tKabfCqj2f>$FucQZfZHquDRIcsZDJuzf|RuPw0b} zQ3&Vn@V-Mkrj1I>R4;Vd=VF9tR(?0Ks*#*h2pikr@MS>HspO0C z*foYH{Z;>B^SDp`K^pBZ#7geyaWdP;9%2EraV~u8!#B)*c-e6T=4?JYYqzailupio zgpef|7nT@V;Lw!?5Y1d)#{hhQNuIge2^rUNT~xhSXl{yX8XU4EWl1Nw2GR!a)Gi3y zeurhB3H_sfZczS34)8K4c*rO^fd)(#c6=`Ny3|SU$=-=Gg9-4Go&&T8+u^}L-LT@7 zf#ISRJ3k|51?!SBpCSX=#SGhB$3U&~J@x@2;W!&ZOL$<(tQjeXpL?y=v~_}>NU_kK zYxu0TO~z*#%N2;931kLjc>D4mK43`j9`sdl$rxuL7MvZocWC*ld|m{vtytug*v+%c z93vF9t5u2fDFErMGpwplPvGp)t{Lc+v{LO|4u1AVLZ##SQ#CQE^+R5LM%J;0?3umL zq4^ZCWJi0pIX%^WIl{e*0%|;z#JT}4i&gp0Y=jX40N2Z2%;sG)yL&NBH9u}8Qzoj2 zB+9>xpz=2QfCbZ41b4BMaymF}h0206iLutp4CByoPW%{LStTX#3QhyP6Y@aep3(Tl zluH%F;xP(D02K+eEVy(0M7Xrt*=w7>j2pgf-1jF88 zGSbPc;o!Ift`xcinOKfw{itWrtYiCZib)_)O1Z-_i?RS%mu)wTmO~MSCaL?>4}%dF z3@LXUZV}TS8+RSxa;9WE!l?vhBPaAjB{uJvpp9&=*;}iv(Pp=ltap7YqhgJRjQl+H zvU?j!jS}1hBA^~v=nTqVmpEmTz?)a^t0^e~7rI^WI4vn5@=w52TJ?Pb^rQ#gIa8(M8r-!utU(=n z+QDoy)Z`+bLaLCuRud^ZI{D?kBwm+JdD+Ae*kf%NWP zNcrr}7_pZw$wZvka8El~=o)&aTy)}#t`7A&@7r`wfg#nm=AT>c_9Tn$%;#DH93y3o z1u|{jj6~Q(Ww&l?E(UOvw^{G>RLb2Kye13vUvyA%DhSZB6s{P1Yp3}r2Sjj49hN-- zxi@p+MK9%gsP+m#1P5SlloEF5{_HH2709Ndc2Zat=d6||%M3|Gdz%ef64NjXa8;LD z_sSdB&)rW^oONu&)QaoQf_~@p8E5;-vKXEPsmHIdC1$M4sJS zunR`+Lh!xdT5S{35ZTCaI>Yw1O(mB^nM|;4Wbh z(TjP+`Yo>{ZNcS@@DV(Ax&G&q)h}%(QfZ!~l+I~#^#`xiNK^Ckd41`ztv>9P@Fm}Y zy0{-Z8_nwlopa;Mb81H%x7tLhYM)w_I&-K$ zRgKF9Gk8qL76>M7llAu(329FOU7Pb8g`ub6xLoNE0%ZCMdacbVk5x>!5KR zxcP4G1~L;K&{70FC$8kbrmFG1bjIRgeu%D-)1QEARb(fDS3GXEs-~uWJUajo<4HG` zf*OBgJ2A{A>rmE3;_nsti-*`AZn$1GlBdCHDZ3Fjg#|eCj2g3XThVNpz)Lw*t)RI; zrXJU!;Q}HSm%@S8D?6XP!c{f0PGg2M0B2#rU{=sYm4wJn)5(j&lf#r$bwt8a;K1l5 z=#X$i())SxL3i}cV&WRM1}kRL)3}*FfdM(4h&h4QpttJ)T|M`HjpVkZelr96`q)dU zpR(DR#Q~lq#A?CMm0cdxmkG{Dd3BPU%B01nZdBd>$1yFUWWWyphOpIs3e?-lSjtQ$w~foA(}1JNLZe0^Hcb|vYMzX5NCr{5 zDQS+my1M^~0G=b{hZol&+~D#kG`ofzH?W3+TT&bnZ_4R;|LiUsm>h9YDa~ILP)f`T z)oR2s@n!3eE6ybn@kmilN>ZYUAb}SRAt@Dd0vi0V(We2ABKp5x$jg#;(;d>jB+!M> z5F8dY9qFp1l3~jh>H;$Gp^@|aCY!^o8#0q}+kkV}9PF#x<25nq(#a|E#WmdYfy6^+ zb+engw=fk5b}1S&%k#@0XnnAd41FdMmA5SX7<-lvvU-qHI4J`_9?#HiH&azJbL>E{ z4l68Ml-A!1=@e0JarJL&yXDrj`m2Xkg#=n-+bda!Q;pN#b7^fv4=G zY=|zbEQ!ad6UK!V*0k#(dF?ZW+Uh8HBn$3lty|~B*RZ<0dk$zwLb3(5bk6vi#V}p4 z*jiB`m1J~Y!#!}kt=+0#EB3NTH^>O!FeGJe1DS*S2J@1Xo8hjj0V~Y3zH{~>oso7k zY<{b8)h8j+<9sK4AHbE(doynxJCsceZ2}LiCS(;)OKZkbo-c_n_Tp=aRD`hMWc zKx&d;6?JKG-j)L-BJ1n9wdq_ujUMaq?D8xUjSu7P#P7IZ$!;nx;kiIUyaP`9IP`PrM8)#@h^C?oLVfr$0sp zsvt?z6CBlwMFp){=6Au1E!Z?3<%m2vgj(>Mbs-!S!y`zN~p5lI*H&{%a^(=0m3?3hQb7bYNJ69FSvxU5;c4 z${u(Gw=~afgeUxXkNVz*byr6nmwKs?;`Y{B(Mf}?sQDn{+BYgu>LGAAaGp&+1-2Jq=2 zw=_1}WYYqUTptSs7eTIR$jKw!&{|V^6Tsh^$sHjEu1b33FPQ~0EDdy;=;yZ2% zOxlDn1K8le=qNT0m2uq$Uh}~vRf0i*c-wgR3K-P__c6W$d0S*249D(AnCaP2Lc3~@ zeVIz0EQ<`0z4?rp*$c;`quXu5X=_M=+*J!d4!iV5y_tlUdh~~sRN#J@P^qR*av~Y( z&s;e3nEa?~V$N^)9MsHRLQl#RZ7XlqX*R^E1eek%ZA?w1-2bb$(J7CF`QlJXs!jrDlU+-ts%*?QAvt6DG9Ji2=H}1F3v7Ohs zfXa&s+G9OS8DJ@UZWC!O{7h6pV>z6!7#O3N>~4!WVYd~gq1Z#`;ucCCQ(5J<%NfnQ zNva&sg|?u^Rh}Jus(3m9Om^UM8ZcNB_VoLd{xW>Ru_3JHl>TAbOY@ZTd@Fgxgit86 z$B=-5zSF=RUt9dH`NGfR#>2E^DIP2zn`q;md9(MI67uwPjf%3``Rjec8S09c7kli- zH$EuZ-_GO9KJkWtiZ5CB(c) zO`{F%u$3CuV1AEJ@bEC<$OqyApF~t3VNPmycwtaXq4#Pa-<4RuhQ>;Sx1oJc&18P-tuL`^h@d8#z<J;P%$=p|{b@E#57yYnkXC8>?9&LW z*2@F;io(4k!hw`iZ-5CkmzMqg8QX=^mm^-Awqf|HnbNS>WFh7uheF-G;;%4sQ<|@b ziP5E?NH;|`YRkoIXWYk(a4G3ov%C4CLIA;q`I6bbmIhekW*!hh4n3v1rElh}utB|L)N1Bp)x3KEi~APpO`= zaH$b^9YQr9lonO1s=-~+Hg6|`5_oBthY1tEgeZN}Pe;U}&Oq%l5#G%-gz!m|*K8aq zerXqu-4t3n|+nm}ijMy#;t~86u@_|-kK}NL&c_sPMs&k2KMqR?2FA6#m!)o4Gzxtez z%_N1*D_NGK^V;0ffs*KNkx=Hz;4@jOQn;$Orgj$Kn%whteyRYVXY5e&>3o*Tw|(a1 z7Av83{CUlpx1Suc6%UMTi$pPg;09ARHK!RiPWj4DDJ=N*p+2!ijy>gexNSSaO=A?G z?!3~3Q)QV2G4ig$aD2bzw*0{@S88)TQrw1Ry_7fjr@EGEMsYPUDWy?L!nSSsdR%{F zaYQ$ZAC@=b%(4X=EbRpKZtxYyLSy2~Tr+QTNMU8>ThN=H!8P^BtO1QZ1XMQqr+-;?j}%*@T4 z`OlpB%*9-seX}pt+Iz3P_gd>+?|R?odD3b?_qZ!32Jrqt;}F*r-zrD{d#V~#oeZ^7 zCshaS!XLz7kmwV}|! z^WUE@&~Ce!I$i#pIEiP~sWQw&-JG6F9A+aL%XTHGI0Uh9qhpEA(Q^tOC{3(AIzQa2>f@{?b zP0E?!!ltGvgz1Gq0B$(PjVI)0u3%jVSQhdRO0l@D&MC!g&IenEEf; z(1Cbp%@q}FgDJbqihzj%oi5(7(SZW|VT8y#={QrT!Fg2gH;jMawZPluOj>%ka-1DNdZo<@ngG{triE_0VIJ5q0j^Rv?q1`lF z`j&G2jk>4&B_fLy{=C1eWT-~R*bNXb{)EvBdO8Zxy4i3N^%$aan1<`fO_PB?$2395g>YUVQoS9=j#{;jpU3WM7o8@&c!-? z{22hlswjY`%ExLrGxVTAO#gPJbLHo;U6fgeJs1&6q-X*G{__H5JYVilYcPEs;w|5D!EwpL`{n6ZR$2p8=Qvuj|!W7FRtr z@eXAi^Mtrhs=a>w58%HNf;w*Plq@9m|dM??lS%oF)7#`xS!wj#f&bN zmvXIc%f3Dt(Fg-*ljzebiL#;_N}vqe4<;r!bv4bZQ<_hgI7Y9ZF||v|m`W%XHSbq% zoW>_$COW`EF)Cfs&ks40s;m$(yq-`cd*7GLTd;D)D|;hbOe@rVdfg41U)(DYCwRi< zYF3xKC(U^dp0=#h_tUN>Ot0X-SAPiM$A^SZ(~6572b_KI$)v8aea82mH-N8HC^z$^ zB8HX3NZnMYNg>BE^k{b8^E$GZieG|}ngh^DnICU!7EpJ4E7wRA=>B>%qlfQ=l^mgv z*t~?=mPlol^t?q$yY2u4e7<9#Oldxh1xHP)6!$~& z`8R6G_J<>DK)`vqr1p27b4NdJy$JjN?7bXN_YY|0hReEHSZQ3@ zFM!^BvtDS7iLwudQlN9YOpnbfc__*}F~t_+sD$`oe1LM%sesU}XEE7T>VfLBIy>ll zylhoh=KjgITt)~A2tkSF57aBYw=;G8pvyF2z8l|McZqZbl3^oiv+jM2wkSNaj-t#{q9 zI?vK&=6Z5?z}giV0Q_Oz_PRix0ZLB!uyWgj`4n-eA96>_6Ymx*dB#!_)EUF|Mi{Vv zA1)TT93R4blWy&k>mUuRy2TuOig!c7O}e$G#VUnm*`l(Z4qZ3`#RGBAL+RM5KLcW(c}A|knNl*3wY6JlLCzHXcT$5k^`cBL5bTU$ZD^3DsVTPE0Ry%L4Dp*U!L zR0jzz+^YBx^Zd`tf1f&NZT$QZ)}s2<=4@d{^N)@~MZ)+fIkVW|?4^3F_K)6g#pZNl zfMwLFZ@g5z7i5)3JLe937vRDE$}?X?WCTrA2plWo_b5fUG=p+*)(?MHz~rAXz+Bs)qI>iB#(jD{DW(@5x*Y`m$cScYw-)tGE?9Pd2wa z`_98ZeM&gZFIWbu1cK%dA@xC3NGC_|OHZ5H0hs*%H2-XL@dn zPr_ad-FJfH{om_mQ#%261^gz>Iz{mvUDt_e18Kdp4#{_9*Dd>Hb~*K>sU>n@wkPsj z8H(!E!1pn-{PH`Ns!9UG3#3#r7+AYv{nqAq?%NZfadBI1;jOuuLd&2Diy2l$|6E=; zopscEpNpSL>UdvCn@U;ITV>AAoJwJt1W2xNz~9I2`ibhW2*bvcmut)JX`*p{qk$(Ue9Wz~QFg7psR`O=^n=1cIYCsPPW|q!J{yyEVuXwew@k$g< zAo9(sv6b!p$oFHAt}70UwXsEt=w)BH7MEd|&pkmBv`tGsKrtQcRsdNXJuv%~WQEe^ zZx<}Ocg^yw&fMZRzHPdc%*$E|)tE*sL_f-x5{k8Y5OrC=ODhZb^8n#&pSm1&hOp?b zBvBjyl=A2P?D|0h3aPd?oxHw04%SWg8849*ET`mfW1THGzq~j|b;(%vu_M?ZMa0P( zDuQXZA6@L1>_`0G%*;?xugl=KRjw2X2}zY^oU@?{%_4tQ9y$HCMM$`;Vo;<&=|mvI zY&PO7e`^QKhoAqzlxF+!G735|(F!ENu+E@#)-JQoFzwa6?7rJ;VL9y}v&9Qu2^|Nl zXujQ|mg8|*2W6GeV5CUl`6!PZ4j&f=9a=gVlXY7|_gDtORXq?0f)<2^s<)q6fJ6QP zZ2aYcdA6tJm$Pp%hEOl8;6B|is=-f&Txsk=87uuB5uCHYyLjxA&|+dUS-?8+_qhZ^@sB{%hNzJYzSimq>44vt=#Tw+ zu#=34dcJCTGax8drz|VA&?P8v5Fu0aE$R8x8g;yp)@IiDhTvBPK&h?^UjJlD-TwM6 zjTt357}aoNHb8Okfs#+f^gjS`CFc~-phVO!)GK)ueM^+EEwbH^JL}UKZ!}&<<(TV= zW5>Dbm|4}X8Gw9jYKVOjJ+Ou)oi03PJANdKxoQlk_thT~`DL0hDrKx`I-=2!j?!?U z=zhhLNX5l!o{=A?zf_S=K2Wg>=G4$K6kpx@Jy4t{RLG@>OBL^zjJv-R5cCR#q0nWq z!bLS)NC$jCV{q1OqLN@%u^8ml@L=fW&C`mnhl<`C~lWlIUINiIn?--$Yq_$`gMd z4V8}37JBaEv7VHw`S64n^fM0La4=6y(I=|ju&e88+XPPCUH6scz5vfHZ({ZkxxVp6 zllsu^TtBSkelGEcH7m~`HMCaV#@*AbJ$6j(YbgxF4az109$)XcGbo|(752jq9U>b=Rrdn})C4`8tIC3uEl%t&Kc z1N8~`Qm$k5e7&Akt4oD1RNGZatY*0Nw>i(0_xB|!9vW1(%z?+-39%s;??1uk6_q9j z?>v+A_ciWrwUcLiylc20H16;>A;7Jfqf+Lb5_u)~m>*ML?Td z{jgfTvASMW|C=cxc0YRK8E<&l_4s)5p)-bzD}z0gzqADym?7WhS)JfQhJs$GJdsfg zAgq9#@<{<`%E0fTw&(QMeOaqC!6!#w`vQ93QM zA&4oF`yAma3w^tb%Xk1{(~ZwUjn&FR<${nC{Jgy}7JbJVA26MkVPBDEHDbRO9emQr z?eJ$VAhO@!KJxgHQZ^Z1L{LOumI#V_z#`oXk5@etUvp?rj0(TAZXvxWwRvf2{D&JfI~%d#xLiP(ngmCv-TQ4Xd5pJU z{P;rj?;Ri5gkmA-OL7k2$JNMt{5%0sfd|Vkqr?PNJVLE1O-8IMQq2i^X4?It&>vFPgY&Y`(~yUH^;LvtC} zZ8>8!JeZkpa8S+r<&B9Yr+UP!lS8g&8Y-yS!#?JOv(ackrm_SbvEwSryho=B!g7@b zqw`wfBPR4y8u4oW(qTsgt@|9MCGnr|=*7jeFDfu@y0UnyQ$9Zxe(3#09+Dg%D}MAU)@%6{t1IMXnhq7kbK7 z*R&zm8~yH9kZ#shQoioIbG3;8?q$s>M&XhD6{Qtt+B)2HYLcP5II8HYu%52L3w?Hf zg`=e7jjMG>DmoOq6-N~S1*M)uz^vFTDd8#6ukAS1(BZyXH&2k)U(VW2Qvy@v^!n1EHm62baYW_V0Te9Xkx2qJ`9TBk(Vfclqr!$yWa%9!Lwfd zzyr@re;>FgWTNh$-5Z0AbeXQ;s#zt9DSxs=#-TgU<@um>bqC)=DR#$ z{Om@O^h|zHAl}f=&eRYA3u5d)Q<0zo*9jIc+5ds$Wp?{g=~U4n>iT`hHY2tRt|?*} za2*MrPEMj~3o5z^Gc3srnxG3{@)krfNpPnxij4#YpHbZm?xC_?lPRKZ9V2|~PN9dE zg8lAomEg`}Bb5O`Knvv65>P&dPs5ovt=!>bJB@rCxQfaU;F-wp8;w%4>wj#&;T1v* zI{3GWp4o_AK=wx7y=JX0RqigJRL0-A-dzxT;*iQ{lyFxD61VG@uu%r2n3y0`u!I2X z)PTNF@O@7vz{?ACjr#Iwm9^Dd_mdQhGUp*9$x{F-+t=cl^>Cj&;t9{$CPc@qN~P^e zv`&~!oxCo2!|YJNf8t5ugN)WQGHkG?J$nDO(klWZL$UhhR7dH9Bqed<`oO0@K2jHj zX|Ac*m=nCIVc09{4CrHv-~_3dBkj!HR~#K}r!n(hZ)ANgTZo|7DF4*Kxro)asdKg5 z)ZznJQaLuWZk9y}~II0amT|biUSy651 zfa(pB5$Z09Hk317Y1suJ0PHlMM)0=J*jvfYsN>m_GzcFV3kL(**g11174yk>^Wa1C z;C$zb??NZvwrmVCd4LKou)tl-E-dqf6=vvGUqqb->5)Zu)Hy&8jV<~6SGh_7H-B&u z_z(}6YylrNt6xXdin^tO2>?ySfLJ?G9^Q9=hUcauFF#FkMgi0T^)-KC;~9{h4nTME zVjbc_i9x#a#fl(k8p%AFWuPe>O@{iUSBVBsPq=|SxcwM0p-Uz)b|Nx$DM*U3H_8;{ z4TA+)J#4PgEVQP1xnOy$@uQdp=!YA=cLsX6oI7AYaB?7^W<1x%t2K4|!Rbe~cP`9- zWM}pvi+oh;%v1G=gT6;#JcHX04w-IO3C_q4NW$&Z-A5d$Q_|?5IwidjyJcc>;Pzq- z7vSm)1vL46NxU39_YYv?C^mIHsEz)bPOEXC4ZXh|>vLTa>d*eZ1Sv-x^8j|MkDO1u zvqW)~k$C_3)>C3!fe^I7aZJ zpA~sdGH|*k$2PM6@FTn%3>5NFR%nBq^5)v=NmfR51DT*FB%F-s#8w-ippJ7@%jQl2 z<0n!kg5iaTA;`a<*d8!0D0k@eMcMdru>Z7{uHov7O(!8o8AaoxqEHQft%`tk#HL=W zXi3qGk5bM4N;c~aTrCWIN6~q!?IClo?o6Nb*g)}{bfld`WsdAE2nk2aSsu_605_Yy%rite9;xKTgMj zJ!>CMPa;L=g>>YtVL|I{>FxKg?T;yeCu`hdF)CwK*B zFQ+1&MUP7rP~y{#GF&U)JDw(=3u%Q}0FHl4jB?&&5DpzmF)rQ#RRrrEs{y0P_6R1s zXX73TL<2@WjHu1~SP3O$TojfFgz$&jhc|P#qW0aiV&v{>e$`$)QrHyAgS7vLM8hU2 zC6|kq-v>fal|-OmNK5EFz?_J;R_&|r`ORGAAP?1W zaJuq)DT7BLMl~FcwM~6B7_d^et!Fo4Q9UT@OMb^h>@Lh9u6IUxx55L6-DogKOAZbp zndm8DONSj4@llhR%u{j)J3TAm!H+pAG2@cJXaj0w1(FlsOqOv;PtV4R&a9*D4bSSn z(L&L{{|EbX(pbs+Lzr{7@%(Aqp@i)-wtcAcP!M6XqZgZP!t z>TwNDWnFb{xcu6+UB@PBX1w`Z+0E@G4fm}F9{LtUG9|Ac{naFHF<|G4OeDzr4OhH+ zNJP$2X)wQNK6Ef)5vReQg4h&dHpL+iw1`D26EI#|f(Co!;`2V^b3PK4GPhSQTjNzo z4qZ6T5JoviTZwS3=y9~-k56AfxrA-18Q`%zXJ8=8Ahiidcd#! zmEj6^oAm?{M5?_4zmz>P&y+BSNrttlEsHC3wbe`CRHn~r*(*ssQxai~+?)fQpKFNwa)Nv7wA4uFveE6=^Nx)KzC0B*@cLc)8100|3Hs5KR*!^= z^3ha^9?U;=Wdfxe6OjIjGLbCG;?$td`rCexy30t^bCX<* zP3{7g)&69hk1^=16gak(9X=uXdb@K&E?1mgpZHrQU9<8NfUa*D9V)(E$GgPqS2 zZa#xQ!xW8FN{pY;uupaV>m5{g+FW?DPIop*Y}Hyo-@}T&gv~B4H=#!XGpE$8tuvdDmvaB(!Y555XK4z7{A`5WWqPa0jll) zaQXjQocaG9X85}RF;y%DD&nBevG1W@HL#&WL;$zu>PI;F0rYF-5Fd$H?fD3`6O$M_ z7zwVy^Y0;wX3?x`X0i{4htB)5n8@0$(%j??cYNi(GOKH4GzosLuOK$#$O7eU7|TWS zyW3ojb{>;oOj`uUTgf6Q428@T<&wUaf_fN#Sy9yrJ&lH6W+W zuziQY-ErrXbH?B7wK3oyd(XY#EB2lG4pe3MTWp?aauc5anlko$@THD#Z_nRc8B&FB zGyc(~oVcg_Lx5;eTWRZdb;WlP1eJHW#B~d-D3de#__f6`u%cw(Nj-f$=VNtgsP&}V zE&n}04M!EI!&KNG{k67gGVNBA`nx*W=w}^*aTgOrPaCIklEmlPkZ2$sjVL*m>`yz( z%Q5&suX+`Ly}ex_C6pv|Qz|JsExzle=ffvv27@>eD*POJjI^Ek8viL*nZKHPT`2y} zLDBWfWsdZ;l|#4=G4==l$kx{|8yj!+ujdj)ldat!Orh_HEjLp}8MdI>PpQRlXrCeb z%9v|>8#Z&vD}=v8W9$V(nNqvY%X%gJ6~$jUcT<@T^9yd1z6M6p)|J7t4^@#p=-MXt zPK9hx{?oV7bqh-;e*H@tTeEXwN1B$>D^4Gmr_WI*Y>O=kR#5FkL$eG<+5WKO-1FFY zqG5Q`b8kSYtSLw>1f93RmoR2pyY!J(c7#%~a1V9ziOU@y-GHD@`KiZ%@54EnaJ_LV zBJ1@>5jn-H;x%3?gSC>Y;9?)Yigps8vhWCI`{W9Qo|5Bv8*}m`IEygB`^_v`rCJ#B08xX-;PEq=v@-vZHC2$4)ccFdYIx*aUFCH z%7?6IrWd6WU2$~ld&37SqHUoo+~O=1cLD&y0ft04?_3h5&d;66!?hd(L48bM z>3@c>3SM{btL8|xW2m-#IYXiD*#@Q*4@;N`9wMngtC;o?jbUVWOW^L1Z>ECGNpmsp z<4o^ysF--^@?C1j)p=SL)=t5*pk6D`reHEnql2%{Zfjh{0h+28j18)mE3YsKMz+st zM!ZosAvkcCu8ZcR+$mdZ6@`TZN|${GP)1)Rz|iM@G%muY((QHFF`B&<%RN=Uirk z5(uTJS+}i3jE?z0lgbtv4euq^wA0hk)`od0Rh)Z`m+sB~4zvT9vk+qz;p z#me|J6Ru$!?%fR`zcGDx(fW}tz(8Myn0`xJPS2pW{)B11)S$P${)h+uip(NYCih)*l7cq72<<_OqoWJ1(#U}T0Vb3mt|PpDsQ4%1%h-hzwVJKWK#jq%PWKH57s zF&qXH-}65!zrgg(`k1_;)nWn8fU3+I^b{1i%#|k+0&l17T?>;}r!v+ACeN7|ac4c7 zrO-bPXfBUNo9@63htlEPFlP;oMi(IDed1?<(_kG$8dSOMuhV6G_8`@J{-&JE{#JfY z1vi!?tqIl*Kvl3`;>N5t7t+5&ZVZljY*nNA^Ikmke~#%b#~|%rq76{*mk(=Xg}mu+ z`h2!J%UpygQPmfmM^sU##j3g@j;Q-y)vk#W@|W$paj>}kl%NYS{KgeY=^&J;P+SFv zU8qA#P0)kpGY3@oL#!F%8gO4{qR;$b9A%r_uiuL48%e^)4St&B2>Mff z8Ui(R7#?a@X(HX~>ihg-iy)bhN?nNqAq2_&y$siphARbxW(F1~+Ca2{&E4RtMcxe4 zZB2jms}NXfz<&5qO6cqUzkA_)VaaJP9#8FpIy3B1Lp#B<1$6heHT|!gs&*Ljsz|5( z#O>4Xu*%A-sRhlA@v!~$P$LLCn;|skkiHcbpN%!J9BmP@}$oVDxI}l4Buz z-)0YqZhoC*wj!YIg3sc*1t-^3h3(IHS}VxHO<_AvD;Xft^^~RfkZp^i$DsLt|2ViP zD|b+=d~2dBVO|xw5{H56F&+;E-A4D>0_rnB{H>!sH##k%q*mhM4Rs4Po&FxaaqnTW zHF+Q*J^e?aEbCd?FVzBLL6v_1LE(k=)v?D_x@4fr&$+2MU?4&@)L>k{#n)|R`hv=&==k)B+b5xWpmxbO*Y_%P z=s1+H8BQ1m9tC~L9pG$af6_K}ciIKDf;$1Tg;t^kF0Rq8p>Wq_X-kfZv{{-~w0@TZQeLHI%ud ztEZ$@5cFBesXKet2OmNG1=dgS#DA2QNqKFUj`}Sv+qWad+G@TmFC**|s;@VaM#~i& zbk;M@bC}};O&KZ;DGIGjuXgi4FgYCrw+P;ge-r+9)26r*50vY)D1UVv#i=+yF}57Y z)k8o^Hb+yw8LMD62LQuiL``t7#g9-eXVi|(&0BBfOcRGjKoZ%tqfPkFQzwU{|HNMt z$g|>julWtAoEjk$CZpu{g0+Yh&e;HKLGrNDsdMFyqG>|DzEb=9USf#Oy(?e8Pf-yT z^}ci8Z^`kcn$^=EI|sXBUk{ZDB{en{1NcP9sMAXXTPHEl;LRKMnC?`AY-|B^``#J9 zFyj{KvMhime-Huk)=|^6QTBtTs~Q9_AoZlG>*5a@P32IKv+yH7fDrcGat2bv?IfU4 z;PeW>@C=;dk&=CoykM;%`v7`5Q0h&jo(U1^)b5tq4i13dc~$J@r@XvFri(1jWN138 z;ixvP>~piWWfeqaX%&?ZV>|Jqz!5tKm0usB=7JWuFT}d=bn=2&eq-b0nn&aI37`W6 z5GK_MZ(tgbiP z<-f$TK31TMe(%?T%mPq*kUH*1k;5~?RgFBylJCc-;LtbqO}A!u0@IS;`rAlMFSETQ zgs+us0^#;j=Ls*y4?ZWuun|m$a-W(ZjnUbnXD|TD#1y_@!cff3Wa%vq9!)nZ$~RTB z@`3I6WEfmlT7M+gz|3huw7P3=B)tOA_QV@Lw;%T$We7Q7jLUi-E|{Ae)zcZku1+~0 zDfi>W4d`cy%;5?zH%&XQ?TsVo4sd4ia$aoOAno1xVZm|NaL$C5DAo(4*@nvBE&F<> z&sigGK&LWT(NF|3XXp(U_0GwkC=FuHT4vvGvvSqy4rrZ8m8VR5E#|qKfkG5zD_Q9> z5~z|KxQaRe-#(b2`%~1fvM+TR>)C|Va7lehYTiva*js#PHMrp>N0moQmhN=>3}2c? zAA&tyW8%rw81xgc@kvdzRjoRvyU)Y(y!fhUa2XE82UPM=b{Rag_`$G-Va!qCuDNBw z*WK@%?xW$nSq)bUfYTzW1ZXnJex-gj4P{_xaS<8$&SqRZdPA!NcI7h3jq}nPGTR)c zjY6G5WrsrN=3jmdgoWSDa?JJ-O_?fzTJ4E`e#IVEt|_rTtih892vGQ-weC(+{IV&= zB`&)ifV`_ki3M7`l5%&#*v)E?HI=Mt!)^9-=IXeo0Xy+a={u6DxkGUx-V{C`dQ#>2=TW#ot!>EGQK#qg16;3i8F}pm-r3z3k zQ!#ea<9>z7PsW~vW-o@M?kxVr4;=UhK=isIUUWf59R_0sA_4}i$h6wqV`hBeEV z6hZ!k2Q@CSY*qaKIPInK<(6A)xf#q|Pt}}W+-;EXMifSZUL{ZZyiuzeg@eblR73p^ ze!N}i)cAhPEG|Z;w)dWKH}MQfbK<7B$?8)$J%vf_#%U9>QK4|zL(FxPSD>{`I39U|V{hBl^rpKGPm@&3;PwWNO?TZ3}D%42sPt=^~=wi3ZVemgP? zPwTyI$}tZDppGYYpmXm}7dm^P1vpy9Wn<%rO#3jp;ZYNmneH5L>Al}IN6BhMib;DK zXYp(OeQBqoW|$yh`f0U8#{4~T%bFFSn5sj%Z4%-)X%xK&$=z=|m(;$ZbPzcn5` zd!rhXDTHHL^CIWnj45#20Q+fyeDP;MY1_~WaYoT87Spl?RP=*bXVxn3H*!;OvaR)x zHg~}A-PbZ&M^4vyYcmoDKnHX&oG-;o9mgLGHrMSx$2SnTr^Y#G-LB#2ZgA+t><(X% ziWtAm`elEJ{0AhPKc7A!krd@SK;G_ylk7uoAwKNC86|v-ne1-VXm_Qwg=2$R3@y(} zKP%%5*|x<~{DOEJ+aILginz87zG#u}4bECHvIqSM;oEYJEfAfma2N4(62?gveyJVt zw94~C1=zu3Cntqcp2Xq9gN~)0$&cLm*>#v**kOn2Q16yHR39qwSst1SRuQNo2@xOKnuXx_% zKJWKK^q_Qc-dEQv#?OJ23_*~feZJPh{J8{BlW3A;|PSnl&MUAqqSwh=|NsEl=x6jq*!vJubtu8e#NvCegco6w@MxP;_Yo1AmVpc^=0j-#vtiB z+&+-@y@^zuuQf>B9k>E|;u@#iq@17{LRONjro}c}xeGaJ0CM=ZMe7`4g+Qx5Ntq88 zZ#GTRh#7wJPf$_s>^p+zE}VNGpT2Hkvx^P7+~K+yHvVvvlr(XJnEc z;gE*PXV*>a(&l77cFbCXxfXn`7()XT!NB!&Y6b0*T!R+&BB2u1#UBY1{80c?`Cj9u z*(7|ECf0m((T&SqpA`a;8-Jj2VGI{=wbReQ)8NxTCwS+M5kRsfa zd^16O6}tyiUe9q|o`4@$6;E{Pcps;QlFn7A_fx6HC-#+nl(rm!PWPjOvN}&4u{i4Z zGoW7C#$AC%);n^{S2g88J*NtzlbNHZD)Q=xG=wjJ#!_D#{DIp`D*tAB1cFDyyf;+MV{Rv|{JVsuCr$irjte6CAs$m+CIdoGb^H z@7jzgZ=F8nsAE5!9ALAa4`YwSm|+wO*4?r-njwogA3l*xDgjKg;C1gk{csyIk=3j% z$_G2i#&hCCTmD+Bq>knrwcehSr&e5yb}+mh6GnNF}Yqfko^F|`C>zb|iD5XzSRNYV3( z4FnW`C|*%r=)!n*-6Y;?Ot}!6F+*L9$<=(DoR61KbKGOWH0$}8xEH8(B6USrOd>e# zdHHoduXyCd@Oy(ZYJEWg-+f>3=3RkOwI1V>C2GF_7Q87R6N3(vUl!I0DObn3wt@68 z9vx4+{{eJ=^k=(*C=KSyj3ckc|N}H$duh*FO^wlQep#S$byclX`VIj+-ZRT11|cz80j;D- z7)zNSJ}R1eENTNngRKs!4NHChjl=4>B0V)=cS{-zA&vW9e``DWMJz(gbt0ljH#5e> z2DW}TLvrV7H(=hdz6$o4nC5T5hRVE(+8STzfkugTnYny%Gs^Xb-4DQ@p`%=B<=Rz?r61(vz=AXL?t?RI{GKg7N%K;2_zmOr26mmq zwlnH@Y9td7lpPJ;-I0F$zU z9kTdU)IN3?QR>|92n64*o4Iu&;po8K=WY}SLd>e@?|yQND< z$T>)-+xGF!PbzgDU5D3e+`5LJ*0W2V&M!!ot&#@YE;--UHI+BojBe3TI>*e`oxaL7 zxT4cPV{pDInuAGSbBXN2ZZ6FE8as);nZpH&r_!RcCx1Bb#8Vra8@G?A36@}s5Pi}R zII`O3{0aE7^^2i9X;BOBK9o9L-BiGT&MDr`BYIR{ATz`KIvsY{a=tacL;|_apA>~H za*O7!%2hq?kyqBT^S+-MFTQ5rFx!KN`+)V<>Lay#loNKe9tAcWjku@%IwE0w5|;bx zSUgi7QLQ_kk|;2ir^z3Z%&#cVzXxAT^N_n6yk7zp#Wqlp(aT)9IrK2+(Sohah|sH! z?zI07GPC9sn05rkj}&%tqnuYY(QU3FFC-wlt~=M6M5^(u1-;9Aay*dLh&|ncI+T z_iup%uz;kT4n-C-I3M-QyC&AKdsP3d*3+g|Q3r*Ls{loi2=r%|Z^POm*R|rkm;rH^ zJ7nY#ZI#1M8Tlxk35KW}8^kD74dzRe94c-0J%L0omWOU0wDGODS{0OYytHHwaf4wx zUmMx@ZteW{^B11);T(*7M2w!+ykyHs7T@qcWwnJ}Dd5H;-qr<%h5}vCLEH)v?!3Ah z(~AiRhS1wwZvqvA{wP~kK$D#$Q{S8V5KHO3(FoM3d8b4GCy)?-^-~>Ktyee&_9n-G zEH|YiekH*!>N%;VAFS%5Y5+qjBPl91-7OP|RP4{eq|Mi}#KnIHApk(|0kolnkr8Xv zCOcIklQTMX%U>Tf3kjHq-QuB;;_mWAzLmab0Sj^oVH@4+x!^-HmGxSL@>{p;U?Mwa zp2V6)1JWSSWTa>4mSP0Rj_5>xs&ciBN-oj{JtD7E3D^jdN0!pnsvPV4JZ$oO^25Ut zoo0Alo&A3FfcVo`F2qP8uJYe^6Q~dplXLiR_@xcN(f7Ffzwbs%1XOHL@RNvB(YX&X zypdY1Kf7Fk2TYy5d70Q9n2Con_?%yWjq<4X$ph;FHB*!2Nl8hxb*B%@iYKa)qK+FI35bRBrbcG zTXyf#@6$Z?YqCdecG;$UfNu_r)Lf|Jm&vQ(9wVaAn`bbhKBR^;6{(u_6tkPGwE&pl z2MxbVva507@+*Dj=wfEv!tE69AAZ1oogenSwgD7AO`-5tXR#V?Hs~2w*I6ffYVWFl zZgAI|5ov9=+l@8gy@vsKHTuec!8JxuD3?Qg(J?Iy0HI9&{jty^7UP(wL6wCJ0)P3d zwwYO&E8hO1)3QoV?lBu{aBeOwPfeFfF90CwC7y;|(I5T?Aos5vOP(k|6mXco@9ujt z*F$pWPB<^<8DOo{J8J~qxs>?gAHV?Nv2Nho19@6tH*=?<$?7*KtI_j_u2m$V&n^V9_`)xS5^7PfAn(x$EUxN|ElHukIVl1b(e(yi_8C0y zXBx(T%@aO&ip>#|)K-Fpek&}-qKD6I*!4LGDl2Er>wRKlhxcWBWsc-SD?>l>-(pQnPQH2U>Ql!Un?iXk<+$r4W>?byU{KeEZee_(=juGgN=Kx z(6~+PwGp|zvwwq{5CKnig02dizYjoy(RK9H0aV-$`;VM(s_HU3bs%i?($JQC?grh)IIhpJMkwIugKw zX(kY9IyNT*Bkn>7<%!foCH2tANXU8(q%{vbNs7=`;pH72Z3!4NHc8PuFSkhWWHDHk z<8fBP&S8F1cjT^f28WR6U$@p2mrY5dt>ZU-3qBIRV-Yzkhf)_&1Jy{EsIp2;ZXOq0XO+A3>)KTJ4ZB$%k003R145s1WeASoNinZt~#nW|i=jA{zAQK9&zei$4x;(@Z~5ul}-H}r04f99|Bk7mU1|8$_# z9E-num;Uz7h4#V1i9B8BJl9%9p-b;Tew8tW^Y7rnQ2^EQo#R72u&11A&B7AY9CuKp zsiTq=^s(;ND|6eYg)k<3RS)U6{gQAbyV{bZER#W; zv_P;B-q8Zo=CvgXaz@-Pp&o= z{?4O$)EoFt^aa-*dCLcQ_H?|YgkWVuun=G2boyc)P6YWcCRu&lVmJYOitVd+4;F29 zZ^2ex?G-)XSK&P-1DgmJDe4hQpLH%o(YB8SGf1*nT@WPaIcKQC>tbUr1aTRt;Yw^y z5xIXtXGIT+vj9SEoLnD7T4uEa4kPlKa-KwfUK{zq&DL1PY2(vN9gh7CuAk}r<#G6e z+40VcWl|3yk-GMc=7`p%^j`RoqE~>G^7eOAc0lRLxYJ>a8?N?w%C5hv?z&&TlC73I zh<4ko0~5L_`Dz~b{7hJ{KJ^*#KP1ca9~2EJCR=S$5yU_o&^1^O9;(6*B4FEVjy+e_ zv0aJikacSAzyxR6vr$f|0o2PVyYrW_@zP|v&@dr8-CjorA*h^*xg@Q|jGT(dUabw} zAv9w$a2++)7^nD-)6ai10h34nGi3%h$+N&xc*|%(g-+_v;xBaFp)10O?5VKYI-z+h z1a|>mxV><|Ng!J#pfbMZjh*h?<-?6;vkI(uvBxhTBSG2H?g?CNi*QXpxO!R-{x%dC zIy{&#TLM=CC&Y)sR~j=cYuI| zB7`PIFm#Y2U7ARjsvt#BK#C~Ef}L&I=f=IyIsZHE`;I%_4=;Sk7_7Czv*vuBS$}iR z8AsQ~i`rjVv?+K~&|BFlhl94JB?tS^rscPL0TM~EZD3ZI@>X%MB02gAcLfq7C_j{- z=&Xf>Zbog32IgbU*;E=1*N>;C+1F;8yD6m^&uYrq{c^2CMsSkoH;Xk*2F~0AJ0wYei2%X0bWfb!ICtr zrS7y|(q!YD`>Pz-5jls*fAgXiiZgPnsCD$7AsftkbD4i>HeUpry^J8~97OJ|b83`q z38q&^ScIc@&5Eoyodk+7L&?A}5-HZFy!}2GzEpLmS-s%- z!1Dyu@B0z|-|lxPuK2~wTmH6zavH-*Em6wBjbSXqa&}&Z$sbL!Y`y?M^A*53FhwkY zJ*5q63d&?^oox^6pbWc311PB36?e&iIlJEMc;fbQ|nk{B*6WL6@Z)XpI zhnkGSdQ))+8p?gnybu#OEc`8>@4I7`N@xPx88=I$q!_)R> zqLCR>o_Q;H*{@*>n<_%ivS+0{Lr2k`_~6cnc?aZmadDh?VW5Q5GQvz*zRrlTHG8xW zm*CTZh8)%?7PYd`6# zW3_eagHhsdWhPsN*8*R}c9_#q*HrP`Yr@5KtI@@0Rp58+q}f-L9Z$pUJ?M6K7DFPo z8Z)sdv$L?V7k1BXt-fUz}qy*Q-XjGmkuO8x*SJmt)6rj-{zy z_ylB*ZtejOaXS8380EJ{BeXjqzEE09o2o`ZcsF*)mHw@n{9{gja9*lw3NtA?E1)cr z!lO8QG)YVtl?Dj1IMwHQWhbMcj$Sh=p8cBP&nRncx0N2lv56sC#tOYgVuH6if!*wZMPj~4uqRTQ<uyWE z_go%~GX0vLLt;3N-jPdk{E9I!BsS3}lm4-qme08B&SDLx2CfTQ5N>)DX|uf{NG#b$ zIUMxZ|9*01?f)MK>3`gPXtH6%Hg3JQtLjoWf@0fT zGT7%veYHgZ@{cmG(~%4tVuhB%DA(F8Ju@)-A~vYipGIV`Q9<$vLJJLfC(yA*q8_RF zSU%H&BLqh6q{Ha`-1lDVH;_k~v=-CX@>Z!0(8+>7S9&^}sV2JcT}*7Em>tDQ*14*U zg;aMFA_4Zggf>Ug;Ss zM?ziteaxXv2Dw7%Pm#^u*3bZ0c8QWz-b&waqTxhd+`TZzjoTYAI%j3la>`LTtIgX$ zxgg==bf{uZ#8c+n94oQx{5e2C(!T(DOm@zyD#_P_!TESlBBR@+?gM!&hBVUI0Ev_OLw1;GTqb^=$*1CUB+tHfzsS zZPYhcQwa?tNN5YRd67Ypo#4tl@%kXq=U=}r%AnJ~GsHX6ux-iV0uTh?Xi>4t| zL2K@roB_vQc3`7ZDQa$S<+EGQdJJmVxy%-QP|-h?9@Fnw@P*9!R~*xm*PO^|y{cWo zY+6CBs#iv4`Lr~B@;x!`Qo%VPxni#1_j>4&R$kb#MWl?6@yft$0PgsQuoV&?knQF| z>89kuCLt#xG-u}nvQ=Q#&6(J0lviCy>N)D~+v1hV$5qIwc&ZDxx-Q+&_e>-x@njPY zYp@a0E|XkjK29~!{&905;Y8GEZq)1(r0@lSL@PoD$-3p9#kx!u9T&(Io@K*9?t@`CSU#mA~l>kiAYaiQXLuetv7k=0sxpqE8 z#aKgL?IvJiQKFLPSasBxUA}AGte$Lq8oB-tGZ04>M(2v}L^4*jt@yYiL*(#1-;h|1) z`*)@Sgg6}A)vuv$g-O3SD&DjC&5YB(m!+#R?29jR);!U`qB98HjqKgmA|PwxQi*r zDn5^$lfKVUHufvm>Km_$xF!J5%6IPZN%>r zfPcKPF3+vz6NV`IgewyH#ezVvVHLQK1vhLh_^13%tkJ&!)Tg8ZgRANLN1zi~ty?V% zud6>hV_Ud-Zv&*g9pG_;qQ(^FUJ&I%#a^B&9(`>&w3yTOeM}aG6Ucnm<~-(YgVg+r|V2|0cJ^@<2Zn&W|tq1UQQt;LK2Qoj(^Pj7XaRzET8&=e_<1R=7jf%h`v$q zV@5IRjB=AMu00y`MeOMJ--ou96jz6+O+kO57Bjo;V&@aBj@Jo3^A!{UZn0C%cM)Ru z|9KZHWzSM$Nk_Hd3yzy7A}$5b>ym&IOo2UyHdbK?cg3*RAr^xsO4tXjewOMw+L-W3 zl5_ux*I+Uw*WsY%ACiiYDC6$|rogVvq4CH#aa#Z2RvvOl`qFWbQlmDy{ zXxa;~e^QRU`e5z__&+Rq1WPlTRr9-84GR79oQ><^QCUci=Pk!>NdfhE|5U&_pRt*f z>=%%FTY8}1{imQimy*29{VO(}GJs&|Lym_7GJoN>A*40^a)A@yB_o=dhavbkF$W(M zW-GKZ5)@Kw5*%f}N*WolnCBk7GmSLbgS@RZI9o+{Mm?j+I7iKG-})n|f;6^sAYQjM z>07~9KhS#gzlk1ER*qnHwy7hKeT})?`D+QzT{8GOD#{`$Wgg4^S)>U9lw zpKFhd2CBTsY*RIwwl*Gg>%l00<`WzPhvB5vTRV0mXYwPz@hKb|UTJ2n9Wi0=xYQ#d zQrv5R2TnI@ncI<<77<$0bO z@VTnygn02r0X=b-%T5`C942%Mz;obfoSMnY(P<-V%{A*tAPpU}T6)MgVG|_t?0J1WII`jOo7qX2KVGjq#jpQaW0bI z8-;T+3sSke&*SQ6yNWXlqhqV5CSW_TI}E@pg0p|BEn;`9N3ZZ$EHS|2kkda;&S&u< zM)9!?-fOS$oQz;lN0Z%``)_wGz-Ec!`cV7Z7{8;suV6vA7sGp8 ziB5o|7!_avSd}An86R#!xQK}u8`!`g004_olQh3aSUg^H0NFIwB6Fi3<0>w)&1B{z zVjDFvPWN9&$9h+Lk_GqQ?>4{aSEI;YDItPppvUMM(e!$gpvg&;*8ui!{VewJ zZ5cR6F$!Z@;c8Bc=&|-L>9sjsVea8BtoIZR>{kD1FpmXO3^Ws=DdphWiaT*7Z8G_d zsjnBi1+W%dwbd`$l9CwDO@;k}fbZG&^4H%7u79@T%!6Gu9|sY&S(v5vjCW4CD6ei& z{s%w5Fa?0``!?)6mjj3-zs@W_`xoHXpQ4d;*1FS1G9>xFAC8y%_BDfK7!|RatOk(o1C$};28v)=}QUBas`mVAi*YZM!^)$ zu`IT!0sxs>BnH|PJ@FZC3#Y>zB_yJbCSwfm9VcHe|85u6VgUVgXeT`9>6$cP!sXDL zYFJiPsWV%@VhnSy=xwflI5UvI)p_sG>@VK%&}oyf=oBWnLg)XMd6;SSse9-Z_{gt> zJY}s23_Fct4vxN>em9nK_3)G3)NpC3iB@xmMpg^R!$Qr|h>Y<}UBXH2yak~So5_qczz z0Olhv%XefFzxO4;CvSOEYsa!wH6h~_wN1zw+=9X%Kf56W=Op+z$%KD^Ge=nGY3`Ow zep2;DHOJX5B0}cCXRYkl1~dgoEOyY(=8Z&Ic^XWUAnx;_s-e@72ZMn>rjqGm4vhWM zC9K|EGq*tLxWc#w- z6s?vHsP}`mSD!@a#aZhuBoT2}S8fa~=GiRwb2!$u^Y?>}ap!Du z&Bou>cbXdbOUBK(@*7qre{cQNVs7PocaXV$=A`dT9k~_0I~`!x@`fdN+=mAar!T|P z5S>SGw4{f>@)sjyE}l9d4trZN>g$HSWDdERz^(UCf4mYrQF3Daw~URw{62}tTORw+ z$#vdl+g4P@glbOhm%t#@sqQLqf??VDFxE{Ur!t)%OF~^`$m|k;$=sNYtbM;I7 z8J*QlDlD5nFvJE9!76;%N#~1ax$1zo$n;@0+h=tP;Xn>M4Zjdtj|W8|hm}ina$}Lh zo>Z))m$5ns`KoS(IM<`F2guPjKf^P$MooO=xSrcNbf0GgcGBiTiY$@>rXO8tmO2+! zKSs0gh1^dNNO*JVY5LjKVT0{uem-xfp6z?ymD299x7s;kDuHzu;To{okc`!1hoHA# zPO}IhDdv-Y-?7d&^u3(;%x_iA!`fnEji$bFJ^gV%nkhlc-1>(21cb>sSCTLBKf9hI zV*T}K-60`_UAQILRF!U#3_Z3a_R_E^yj=&w-AHk~7+hxW;fs$6-F zf=&GRr%8GTI9bTafnIJ$UCiaH=eZtzjlrQ*pI+Gy4DSsX(|5~)^2{NF!$WJr`I7R; z9&(`yep48&6DQZpu8)6nXPJ5tWN@=!-|18L*}IgH;cK_?ZJK794TN=%>oF&_0FFR> z#Ey#eG;`uq)ueGr(5%St)p)1_+F+u1?i?jil?+VdQ)Xpa^#^aiXt$OvYjNZfENA%K zibZiKO*37VIs6vz(&yD#&A|&d7XrS=kPGp>Ek<_$p>wHbnLFc7=UjAyv8f|5fw+YP zzjy~UqllhG>Pdg=I`*~M>&H2jt9K5)mrlj=Yx+H&ixNF2>Us1rGymO*yWis8F%1sg zzUV}`*Y9j0=dv+GIaXHijlp1jKK4xJl(g5SWK02QNj9NMumvbj94$a^&a0l(95m@Bm3gR@Ac$z6f8rNC)7a@ajlbcFQ0f*)CcDL zPfuvFN~oJ)#j0K~KC@)4-y%JUl)g#9C|}Kq%m@jxs9xV*Z|XPAn~qG7p6gCOmzQJ>fMgI{9RCX#B_-bLp=YR<=1iv(egP}f4`Q+uZU>sCh`z$#-aklI$TCYJ!kF{4dK377yfV(aLql|2fs z?PO2yw(cG_wyyU%A_iv@bAieyg@SHyz}SSvOeEL9oa%)p8aLVYQtW-aSPmbqN1W=r zYAJ6cIOJr7@21e}NdT-GU$7@ikcBo&NuVXTlBoSAeOtIJKC8&FEGKWCUlP30F8%NY zx0bUCZIw}=w~AFP6=%J(h}$i`ljQ8eMo9rKXy_4l@G@d7)nke6sfv&J(Toi!;1G0zd9Qz6 za+-BZd<>uy8bB#~shn?R0s7!_GI_qdt&cx*l^T^M{l#aq4GDYZoqXx|UKE|Uk-T8iR@Qee!-$KOrIB`7peQS+MWWR6 zx%mmN312aRYOIlUFvPwCDO{PL!-uHx=8qLwLDYfi-R~m)4}vD~<|c(_7vvZgKI)g|{KO%~e&6uw$rAdRwn z3c&0(6k(1n4%-XH9+5SXr~S+qI96{|occhN{72@N zmqSwNbTv8K1I_lt+ByO*nOBJa%Mddmr|$v;r}3fGH)LAxlje?@(2O6=G#1|lnwoK zgnIid)0v<1q((jWR9kbyUG|mfnUf3l9f~lkj1Aa8{JsZok#K*5>cyY)?2%21H-A zI>bYqR@12h=FaVFo+cbSh`%|1mR(28QMG{O&R|qE#zlniWnz}1EDUs1oL}vq8ICkV z7kC|6-r(>hu-)s)!_jZ9md!70 zN5}V?js+)7?`kFc+ndDo8=}AH0mKE&zkI-0kO$oix5zlT3@aS>*)!65niUErNLF!d zCfG86DZCn!{nY7H;|E1+;2jW8BcMrFV*y+D1O~(wKsNvR^5L->3Ga(qZ&bOt9kp-W zZ<5Z!`B$DxOSv)M->J#dITzuP9it2mSUpW9UV8cFjE4gCD$&ta{T1M>qY}Z6rkbkF z9EKid(s}|_Y37Cwklh)y&bh(j5uAg?**Xd@hW|gdd%?zazi>S<$+GzHwDZztW78=H z4D6e;CN9?Qs0>$FM*HmQ`IPM#0donyyJf%d zGdyR}Ca;fznPJK@f%S;7$%-VcBBvfFZqsjJLpOVVxqlb`SU(vOPja2oWY>S3eFJ%2ADkL=x{}^00 zwGZgu7bJ}=Zf|X`Gu#ii3L)cF7el90xo-`B-lrlALhu&3IlQbX|0d}80^+-~(H6fD zWVWWl#Kwj1dCeMox#;MWvEOT%D=KjTvOu=YfYf3Mq5JTz_&ZNta*}C>v1@>}oj~rP zE~lDtiOHl*M;rW1Msz}R(2sK(R~w24mS)cfWnS|IMNIjR`O+_?0aDo^H$>KWpU>iV z_ij4g3f^LxxXS)F`yh^Mye-wv-3?O96{HdT&8R*FKrs8kzW~wA%=oX`^u2iL#^$D; zi9R7x6Y(LEOWFVNW0O%y$;sS#thXdX*NHxX0^$wuc^Sa#JnxS(A&5NtrI_W$ZqObp z%${tc%B`V=%=c)qOz2t@KzW%<m9JYqv0^lVc`X!PLVW`Uj*g=lHT8fME zbj{SdmW>`&SzQFgau2eJ*OeGr)UU5{eC+EoKFtCh6pUww7y%L>X@fF8WBuyVRt)Jy zZdD?usUrmXKJ8I-dxk>8sH*vuTqnuEyDS#MdNbTn3pW&yH$&?JR6A?B>Q5@qJ{5{v zoM-%a(D#(-!4~a4A3!)5&zRcjU{_TGQpSkiKL__VYtW=W^wMVYnnu!mdn7guUfH^O z7}SoKV-Qy#S82BO|3lt{hxC`V;3Z_}oCk}VyBYd{iVXK3R9{c-O+zZ1w z-{|YD*KV^G{zq}1C)M6GQDcjE6)kL@!GIomRBC&wrscQK@#-3ZD8o6iUnXw{K^*VW zIS64p^?Y*=#&mYb*^hUT{>A^lj?$)~4D~U*TV$ zTYpmH4hZelMB0k`>xzO;@*)lTrL3&wPiJ#_I8R0!yW`4)QinrTTsyxuJO4PRaJ8Xe zU3)E%|K3xD>vC^Ks|Ifnn(U1%Cqytjj@^h9B@O^ zv)5erFJ0g08F}xz^^HN_reSFpGZpUs<0k3Kn@_RY+wp+K15Z(`GXO}|a3@K3SxzjH z>oTtIW1^NOg!@WTRBh9e{iz3l;YhSlrpol|GH`)ApM9vMl8u*PA%X&I)sMWrM>GwI z8r;$q{YS|bmZ&C+cCB&C59X`zMnW;UT(*_DwU8@nUC( z>gnR57&@r%k%=BFeRD(#ykXie5>8db=AT;RBUaKO5sLB}#$9IF5=mmKzK%8zU~Bh; zXj(#rVgJ>cn`t~=Z`k*FL|i~OTiE7|jevhX&%0ob zw)tHho#E7}qpI(41qS$Y;!{O`#;m3j6k{Mo1czFwVsbzvh0O?I4FJ@BFe(5bu98wG zJ&gl8o`(%z>5uM8=dv=LKHv?DDiV%pjN0bNLSID#KMX%(@X_M`!=BkG{A6zZ;*&~O zDJ?|tf!K#UIcCPv+u4FSJ&-I3y0ZH^=?>a~q1aOVh(qqRi?q`DsTa`U7WOu!^79?n zS6By*DW;lbzBv6&=YNC%8pHSLdhTT_&jNk{_pu2 z;*IR=-6;32hS7B>3kqf>Z1yH{n?|H0s`9uO9@oIXt4hAb?aFm9&BHMBXn6OSjtE`@ za5nS}YkW*Oy!jUW74sXk#W3f80f2?tH>1MZQ_pe$W3_k+xAB|Dd`#2FQfU+< z5zKqU-lE8c0-?Xx5=+)!WW2Fl!Gu|r>bflO?e!Y_z7GO!yzf3ggZs3VVQp@k2=0x@ z6oP_I^Yrr0^S*L3;|Nt%`-Y+pYoR+4w{yJ&~m($TcI7v0?0idmLJhxh==wxv6RX;e z0l;k{pt4eoEGfwQL^#Cla#c1?Doa`J#11x{rk!p0pqN=q#7|04Emtq1u--#{kd6_-^om`rl zEpjuDwc#m`mZAG#JFq*c97>7#nxv*qXTdtb9-v`Up*A`~IL}e(D@a)9}pk@0n2x^U<6quOE5tpks2V}?}|rSiKQMB z007`V6IFk}78*#mouZ)02Qit?Z~eh>&QRe5j496bz*B|Mj=a2AjGCV0eSq#rrF*2E z?erI@IQ; z)X4h-@`uOWH@qR=-uM(|zbj8XE=QjQjpc&TmLhHDj{pFc%Qwz;gq;E= zXCZreo2~MfiJGh#0MtO6ijSN$NkVD+>`er_hhV`R$HB*K!Hh}WxX-lurng={xSdst zPF)WWt#_e#D~?3@A!s}9LKSO@v9wZ1>HxtQiK0;H?|HK=)K48W z$<&dHpYQY3*^+Cz!~^Bc%yOs(Ey2VNIwDmproDjBp?MppdVw!O=wMaM{DN5Je3Ifo znS@tC_&rL3tQhEJ8`Ii6{NLY)xenLPZ~rXw_k~NX2cAZ+x# z9CT&D9Vp&TDrHh7rpv~V-+)hJ7bykIn9r03pggF6762p*P$`j<_;FM#Brxk-y~WJz zl%K&8;Egx

;+Yw>6)E$AqpJ0RVL>e+~fgb48lgWwX*n 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 aFSDGi+O`do{m;UG_T&E<4q*qs7XAzW9T^`0 literal 0 HcmV?d00001 diff --git a/SUMMARY.md b/SUMMARY.md index 8c3c302..366243a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -205,6 +205,7 @@ * [User Guides](examples/README.md) * [Using Danfojs in React](examples/using-danfojs-in-react.md) * [Titanic Survival Prediction using Danfo.js and Tensorflow.js](examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md) +* [Building Data Driven Applications with Danfo.js - Book](building-data-driven-applications-with-danfo.js-book.md) * [Contributing Guide](contributing-guide.md) * [Release Notes](release-notes.md) diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md new file mode 100644 index 0000000..a4ec027 --- /dev/null +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -0,0 +1,43 @@ +# Building Data Driven Applications with Danfo.js - Book + +## Purchase on [Amazon](https://www.amazon.in/Building-Data-Driven-Applications-Danfo-js-ebook/dp/B096T13R7P) using _**25Danfo**_ discount code before 31st December 2020 and get 25% discount. + +## What this book is about + +The book then shows you how to load different datasets, combine and analyze them by performing operations such as handling missing values and string manipulations. You'll also get to grips with data plotting, visualization, aggregation, and group operations by combining Danfo.js with Plotly. As you advance, you'll create a no-code data analysis and handling system and create-react-app, react-table, react-chart, Draggable.js, and tailwind, and understand how to use TensorFlow.js and Danfo.js to build a recommendation system. Finally, you'll build a Twitter analytics dashboard powered by Danfo.js, Next.js, node-nlp, and Twit.js. + +By the end of this app development book, you'll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser. + +![Danfo.js book cover](.gitbook/assets/b17076_cover.jpg) + +## **What you will learn** + +* Perform data experimentation and analysis with Danfo.js and Dnotebook +* Build machine learning applications using Danfo.js integrated with TensorFlow.js +* Connect Danfo.js with popular database applications to aid data analysis +* Create a no-code data analysis and handling system using internal libraries +* Develop a recommendation system with Danfo.js and TensorFlow.js +* Build a Twitter analytics dashboard for sentiment analysis and other types of data insights + +## **Who this book is for** + +This book is for data analysts, data scientists, and JavaScript developers who want to create data-driven applications in the JavaScript/Node.js environment. Intermediate-level knowledge of JavaScript programming and data science using pandas is expected + +## Table of content + +1. An Overview of Modern JavaScript +2. Dnotebook - An Interactive Computing Environment for JavaScript +3. Getting Started with Danfo.js +4. Data Analysis, Wrangling, and Transformation +5. Data Visualization with Plotly.js +6. Data Visualization with Danfo.js +7. Data Aggregation and Group Operations +8. Creating a No-Code Data Analysis/Handling System +9. Basics of Machine Learning +10. Introduction to TensorFlow.js +11. Building a Recommendation System with Danfo.js and TensorFlow.js +12. Building a Twitter Analysis Dashboard +13. Appendix: Essential JavaScript Concepts + + + From d2ed51f1b41140304625f1d0ad5a19f44bd699f0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Mon, 13 Sep 2021 09:25:10 +0000 Subject: [PATCH 003/202] GitBook: [master] one page modified --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index a0875e2..92e7da5 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,23 @@ The reference guide contains a detailed description of the **danfo** API. The re {% page-ref page="api-reference/" %} +## User Guides/Tutorials + +{% page-ref page="examples/" %} + +## Building Data Driven Applications with Danfo.js - Book + +{% page-ref page="building-data-driven-applications-with-danfo.js-book.md" %} + ## Contributing Guide Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. {% page-ref page="contributing-guide.md" %} +## Release Notes + +{% page-ref page="release-notes.md" %} + + + From 0a6398a478e8b8ff1e4f4779cec6cfafde74cd7d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 26 Sep 2021 12:18:50 +0100 Subject: [PATCH 004/202] Updated release version --- .../dataframe/danfo.dataframe.addcolumn.md | 4 +- .../dataframe/dataframe.set_index.md | 4 +- api-reference/plotting/timeseries-plots.md | 2 +- ...iction-using-danfo.js-and-tensorflow.js.md | 12 ++--- getting-started.md | 46 +++++++++---------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3bf3252..3e20f6a 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -50,7 +50,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "value": new_col }); +df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() @@ -109,7 +109,7 @@ let data = {"A": [30, 1, 2, 3], let df = new dfd.DataFrame(data) let s = new dfd.Series([1, 2, 3, 4]) -df.addColumn({ "column": "D", "value": s }); +df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index a601c0b..3e1318e 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -57,7 +57,7 @@ let data = { "A": [-20, 30, 47.3], let df = new dfd.DataFrame(data, {index: ["a", "b", "a"]}) df.print() -df.set_index({key: "A", inplace: true}) +df.set_index({column: "A", inplace: true}) df.print() ``` @@ -116,7 +116,7 @@ let df = new dfd.DataFrame(data) df.print() let new_index = ["a", "b", "a"] -df.set_index({key: new_index, inplace: true}) +df.set_index({column: new_index, inplace: true}) df.print() ``` diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index f6845ca..44e6176 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -38,7 +38,7 @@ In the example below, we plot the yearly trend of a financial dataset. First, we } } - new_df = df.set_index({ key: "Date" }) + new_df = df.set_index({ column: "Date" }) new_df.plot("plot_div").line({ columns: ["AAPL.Open", "AAPL.High"], layout: layout }) }).catch(err => { diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 2281d63..759b61d 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -117,7 +117,7 @@ From the data types table above, you'll notice that there are two strong columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df -df.addColumn({ column: "Name", value: title }) +df.addColumn({ column: "Name", values: title, inplace: true }) ``` In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. @@ -150,7 +150,7 @@ let cols = ["Sex", "Name"] cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, value: enc_val }) + df.addColumn({ column: col, values: enc_val, inplace: true }) }) df.head().print() @@ -223,7 +223,7 @@ async function load_process_data() { //A feature engineering: Extract all titles from names columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df - df.addColumn({ column: "Name", value: title }) + df.addColumn({ column: "Name", values: title, inplace: true }) //label Encode Name feature let encoder = new dfd.LabelEncoder() @@ -231,7 +231,7 @@ async function load_process_data() { cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, value: enc_val }) + df.addColumn({ column: col, values: enc_val, inplace: true }) }) @@ -318,7 +318,7 @@ async function load_process_data() { //A feature engineering: Extract all titles from names columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df - df.addColumn({ column: "Name", value: title }) + df.addColumn({ column: "Name", values: title, inplace: true }) //label Encode Name feature let encoder = new dfd.LabelEncoder() @@ -326,7 +326,7 @@ async function load_process_data() { cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, value: enc_val }) + df.addColumn({ column: col, values: enc_val, inplace: true }) }) diff --git a/getting-started.md b/getting-started.md index 1a5edd2..f4cb826 100644 --- a/getting-started.md +++ b/getting-started.md @@ -17,7 +17,7 @@ npm install danfojs-node You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} @@ -45,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -84,7 +84,7 @@ s.print() - Document + Document @@ -146,7 +146,7 @@ s.print() - + Document @@ -210,7 +210,7 @@ df.print() - Document + Document @@ -260,7 +260,7 @@ df.ctypes.print() - Document + Document @@ -341,7 +341,7 @@ df.print() - Document + Document @@ -436,7 +436,7 @@ df.print() - Document + Document @@ -541,7 +541,7 @@ console.log(df.columns); - Document + Document @@ -610,7 +610,7 @@ df.tensor.print() - Document + Document @@ -692,7 +692,7 @@ df.describe().print() - Document + Document @@ -762,7 +762,7 @@ df.print() - Document + Document @@ -833,7 +833,7 @@ df['A'].print() - Document + Document @@ -1169,7 +1169,7 @@ query_df.print() //after query - Document + Document @@ -1276,7 +1276,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "value": new_col }); //happens inplace +df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() ``` @@ -1291,7 +1291,7 @@ df.print() - Document + Document @@ -1307,7 +1307,7 @@ df.print() df.print() let new_col = [1, 2, 3, 4] - df.addColumn({ "column": "D", "value": new_col }); //happens inplace + df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() @@ -1381,7 +1381,7 @@ df_drop.print() - Document + Document @@ -1602,7 +1602,7 @@ df.mean().print() //defaults to column axis - Document + Document @@ -2240,7 +2240,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. - + Document @@ -2262,7 +2262,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. } } - new_df = df.set_index({ key: "Date" }) + new_df = df.set_index({ column: "Date" }) new_df.plot("plot_div").line({ columns: ["AAPL.Open", "AAPL.High"], layout: layout }) }).catch(err => { @@ -2288,7 +2288,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2375,7 +2375,7 @@ dfd.read_csv("file:///home/Desktop/titanic.csv") - + Document From 4b84708ddcbb46e8ab47f8521fc2befecec7b250 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 26 Sep 2021 11:28:17 +0000 Subject: [PATCH 005/202] GitBook: [master] 208 pages and 5 assets modified --- ...(1).png => newplot-2- (1) (1) (2) (1).png} | Bin .../assets/newplot-2- (1) (1) (2) (2).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot-29- (2) (2) (1).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (2) (2).png | Bin 0 -> 50358 bytes SUMMARY.md | 1 - .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/input-output/danfo.read_csv.md | 143 +----------------- .../input-output/danfo.read_excel.md | 12 +- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- api-reference/untitled.md | 2 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 ++++--- getting-started.md | 2 +- 14 files changed, 55 insertions(+), 200 deletions(-) rename .gitbook/assets/{newplot-2- (1) (1) (1).png => newplot-2- (1) (1) (2) (1).png} (100%) create mode 100644 .gitbook/assets/newplot-2- (1) (1) (2) (2).png create mode 100644 .gitbook/assets/newplot-29- (2) (2) (1).png create mode 100644 .gitbook/assets/newplot-29- (2) (2) (2).png diff --git a/.gitbook/assets/newplot-2- (1) (1) (1).png b/.gitbook/assets/newplot-2- (1) (1) (2) (1).png similarity index 100% rename from .gitbook/assets/newplot-2- (1) (1) (1).png rename to .gitbook/assets/newplot-2- (1) (1) (2) (1).png diff --git a/.gitbook/assets/newplot-2- (1) (1) (2) (2).png b/.gitbook/assets/newplot-2- (1) (1) (2) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (2) (1).png b/.gitbook/assets/newplot-29- (2) (2) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (2) (2).png b/.gitbook/assets/newplot-29- (2) (2) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/SUMMARY.md b/SUMMARY.md index 366243a..747861a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -14,7 +14,6 @@ * [danfo.concat](api-reference/general-functions/danfo.concat.md) * [danfo.merge](api-reference/general-functions/danfo.merge.md) * [Input/Output](api-reference/input-output/README.md) - * [read](api-reference/input-output/read.md) * [danfo.read\_excel](api-reference/input-output/danfo.read_excel.md) * [danfo.read\_json](api-reference/input-output/danfo.read_json.md) * [danfo.read\_csv](api-reference/input-output/danfo.read_csv.md) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3e20f6a..0792905 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,7 +21,7 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

value: Series, Array. New values to add }

+

value: Series, Array. New values to add }

@@ -30,13 +30,15 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** - ****return **Null** +```text + ****return **Null** +``` ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,12 +55,11 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -112,12 +113,11 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -126,7 +126,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3e1318e..8445c35 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,7 +37,9 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** - ****return **DataFrame** +```text + ****return **DataFrame** +``` ## **Examples** @@ -46,7 +48,6 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -59,12 +60,11 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -73,7 +73,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,12 +117,11 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -132,7 +130,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,5 +156,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d1ab8f8..0bab005 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -22,9 +22,8 @@ description: >- source: str, path or URL - Any valid string path is acceptable. The string could be a URL. Valid - URL schemes include https, http, ftp, s3, gs, and file. Local file paths - are only accepted in Nodejs environment. + Any valid string path is acceptable. The string could be a URL or a valid + local file path. @@ -32,12 +31,12 @@ description: >- object, optional

-

A CSV Config object that contains configurations for reading and decoding - from CSV file(s). Supported params are:

-

start: The index position to start from when reading the CSV file.

-

end: The end position to stop at when reading the CSV file.

-

... csvConfigs: other supported Tensorflow csvConfig parameters. - See https://js.tensorflow.org/api/latest/#data.csv +

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

+

+

We set the following params by default:

+

dynamicTyping: true +

+

header: true

@@ -163,131 +162,5 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -**Reading Large Files** - -For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: - -**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_process_data() { - let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) - let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) - - df_chunk1.head().print() - df_chunk2.head().print() -} - -load_process_data() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - -
- - - - - - - -``` -{% endtab %} -{% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..9dbe248 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -27,13 +27,6 @@ description: Reads an excel file into DataFrame. >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. > Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

>

}

> > @@ -46,14 +39,15 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read\_excel** method can read excel files saved in local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index e412af9..9fd06ff 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 397b480..b9d73a8 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,12 +44,11 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + - ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/api-reference/untitled.md b/api-reference/untitled.md index 9737fec..41e79ca 100644 --- a/api-reference/untitled.md +++ b/api-reference/untitled.md @@ -67,7 +67,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 66dd124..48b3b1c 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,9 +9,7 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) - - -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -19,9 +17,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -### Setting up your environment +## Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -31,9 +29,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -46,7 +44,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -### Loading and processing your data +## Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -54,11 +52,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -80,7 +78,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -110,7 +108,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -120,7 +118,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -138,7 +136,6 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -159,7 +156,6 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -183,7 +179,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -193,7 +189,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -250,11 +246,11 @@ async function load_process_data() { load_process_data() ``` -### Model Building With Tensorflow.js +## Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -268,12 +264,11 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript - async function train() { const model = get_model() const data = await load_process_data() @@ -285,7 +280,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -298,15 +293,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -393,7 +388,6 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text - Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -419,13 +413,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index a88f855..56c4fe3 100644 --- a/getting-started.md +++ b/getting-started.md @@ -1281,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() From 99f16afd6383fdf9cf0c1b8b0aef32123537378f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 26 Sep 2021 11:29:25 +0000 Subject: [PATCH 006/202] GitBook: [master] one page modified --- api-reference/dataframe/danfo.dataframe.addcolumn.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 0792905..f74da8c 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,7 +21,9 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

value: Series, Array. New values to add }

+

values: Series, Array of new values to add +
inplace: Default to false.

+

}

@@ -30,10 +32,6 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** -```text - ****return **Null** -``` - ## **Examples** ## **Add Array as a new column to DataFrame** From facf2ba42ff620bfda8f63d326337bb746f9e6fc Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 26 Sep 2021 11:30:02 +0000 Subject: [PATCH 007/202] GitBook: [master] 2 pages modified --- SUMMARY.md | 1 - api-reference/untitled.md | 109 -------------------------------------- 2 files changed, 110 deletions(-) delete mode 100644 api-reference/untitled.md diff --git a/SUMMARY.md b/SUMMARY.md index 747861a..961418d 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -185,7 +185,6 @@ * [Bar Charts](api-reference/plotting/bar-charts.md) * [Line Charts](api-reference/plotting/line-charts.md) * [Configuring your plots](api-reference/plotting/configuring-your-plots.md) - * [Untitled](api-reference/untitled.md) * [Groupby](api-reference/groupby/README.md) * [Groupby.get\_groups](api-reference/groupby/groupby.get_groups.md) * [Groupby.col](api-reference/groupby/groupby.col.md) diff --git a/api-reference/untitled.md b/api-reference/untitled.md deleted file mode 100644 index 41e79ca..0000000 --- a/api-reference/untitled.md +++ /dev/null @@ -1,109 +0,0 @@ -# Untitled - -## Examples - -### Basic Line plot on Series - -The **line** plot is exposed by the .**plot\(\)** function called on a Series or DataFrame. The **.plot\(\)** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../.gitbook/assets/newplot-4-.png) - -### Line plots on DataFrame - -The example below shows the plot of column values against a common x-axis \(index\) - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) - -The example below shows how to plot two columns in a DataFrame against each other. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../.gitbook/assets/newplot-3-.png) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page]() -{% endhint %} - - - From fab2beb8e2884c57b05015a690df44d198a29c70 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 29 Sep 2021 14:56:21 +0000 Subject: [PATCH 008/202] GitBook: [master] 9 pages modified --- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/input-output/danfo.read_csv.md | 143 +++++++++++++++++- .../input-output/danfo.read_excel.md | 12 +- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- ...-driven-applications-with-danfo.js-book.md | 2 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +++---- getting-started.md | 2 +- 9 files changed, 200 insertions(+), 54 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index f74da8c..3e20f6a 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,9 +21,7 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

values: Series, Array of new values to add -
inplace: Default to false.

-

}

+

value: Series, Array. New values to add }

@@ -32,11 +30,13 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** + ****return **Null** + ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,11 +53,12 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -111,11 +112,12 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -124,6 +126,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 8445c35..3e1318e 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,9 +37,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** -```text - ****return **DataFrame** -``` + ****return **DataFrame** ## **Examples** @@ -48,6 +46,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript + const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -60,11 +59,12 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -73,6 +73,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -117,11 +118,12 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -130,6 +132,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -156,5 +159,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 0bab005..d1ab8f8 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -22,8 +22,9 @@ description: >- source: str, path or URL - Any valid string path is acceptable. The string could be a URL or a valid - local file path. + Any valid string path is acceptable. The string could be a URL. Valid + URL schemes include https, http, ftp, s3, gs, and file. Local file paths + are only accepted in Nodejs environment. @@ -31,12 +32,12 @@ description: >- object, optional

-

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

-

-

We set the following params by default:

-

dynamicTyping: true -

-

header: true +

A CSV Config object that contains configurations for reading and decoding + from CSV file(s). Supported params are:

+

start: The index position to start from when reading the CSV file.

+

end: The end position to stop at when reading the CSV file.

+

... csvConfigs: other supported Tensorflow csvConfig parameters. + See https://js.tensorflow.org/api/latest/#data.csv

@@ -162,5 +163,131 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} +**Reading Large Files** + +For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: + +**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_process_data() { + let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) + let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) + + df_chunk1.head().print() + df_chunk2.head().print() +} + +load_process_data() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + +
+ + + + + + + +``` +{% endtab %} +{% endtabs %} + +```bash +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 9dbe248..d8e3d9e 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -27,6 +27,13 @@ description: Reads an excel file into DataFrame. >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. > Default will be the first sheet.

+>

header_index : int, (Optional) Only used in browser environment. +> The Index of the row which represents the header(columns) of the data. +> Default will be the first non empty row.

+>

data_index : int, (Optional) Only used in browser environment. The +> index of the row from which actual data(content) starts. Default will be +> the next row of header_index +>

>

}

> > @@ -39,15 +46,14 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved in local disk, or over the internet. +The **read\_excel** method can read excel files saved from local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -const path = require("path") -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") +local_xcel = 'testexcel.xls' async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 9fd06ff..e412af9 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index b9d73a8..397b480 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,11 +44,12 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + + ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index a4ec027..ea67970 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -1,6 +1,6 @@ # Building Data Driven Applications with Danfo.js - Book -## Purchase on [Amazon](https://www.amazon.in/Building-Data-Driven-Applications-Danfo-js-ebook/dp/B096T13R7P) using _**25Danfo**_ discount code before 31st December 2020 and get 25% discount. +## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo_ code before 31st December 2020 and get 25% discount. ## What this book is about diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 48b3b1c..66dd124 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,7 +9,9 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. + + +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -17,9 +19,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -## Setting up your environment +### Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -29,9 +31,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -44,7 +46,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -## Loading and processing your data +### Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -52,11 +54,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -78,7 +80,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -108,7 +110,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -118,7 +120,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -136,6 +138,7 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -156,6 +159,7 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -179,7 +183,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -189,7 +193,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -246,11 +250,11 @@ async function load_process_data() { load_process_data() ``` -## Model Building With Tensorflow.js +### Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -264,11 +268,12 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript + async function train() { const model = get_model() const data = await load_process_data() @@ -280,7 +285,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -293,15 +298,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -388,6 +393,7 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text + Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -413,13 +419,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index 56c4fe3..a88f855 100644 --- a/getting-started.md +++ b/getting-started.md @@ -1281,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() From 09f5231fd121b0f3187012c8364c70da82fa9c26 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Fri, 1 Oct 2021 22:38:46 +0000 Subject: [PATCH 009/202] GitBook: [master] one page modified --- release-notes.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/release-notes.md b/release-notes.md index c3f3c78..1f8ab6b 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,5 +1,38 @@ # Release Notes +### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.1\), Browser \(0.3.1\) + +**Date:** 1st Oct 2021 + +**New Features** + +* Ability to create empty frames +* Flag for toggling between low/high memory mode +* Inplace support for all mutating operations +* Ability to set Configuration values on frame creation +* Support boolean mask for subsetting with `iloc` and `loc`. E.g `df.iloc({rows: df["count"].gt(5), columns: [0, 1]})` +* Update an existing column value via subsetting. E.g `df["count"] = [1,3,4,5]` +* Add loc indexing support for Series +* Add configuration support for formating DataFrame display in the console +* New DataFrame `applyMap` function for element-wise apply function +* `and` and `or` logical comparison support. E.g `df.loc({` `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) })` +* `read_csv` now uses [Papaparse](https://www.papaparse.com/) and supports config values for headers, separator, etc. +* `to_csv` , `to_json` and `to_excel` functions now support saving to local disk in Node and downloadable in the browser. Also, supports config parameters for output. +* `read_json` now supports config values for headers, authentication, separator, etc. +* `read_excel` now uses [XLSX](https://www.npmjs.com/package/xlsx) parser, hence supports all XLSX config options. +* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g `df.query({` `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) })` + +**Bug Fixes** + +* Column data not being updated when mutating internal data array +* Str class error for non-string type +* Better error message +* Fix support for all JS Date format +* Fix loc slicing bug for row index with string labels +* DataFrame apply function now works only across a specified axis + +Contributors [@risenW](https://github.com/risenW) + ### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.2.7\), Browser \(0.2.6\) **Date:** 30th May 2021 From 14c83b564e71d717aef4fc4e1e72bcda0426b75f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Oct 2021 14:04:32 +0000 Subject: [PATCH 010/202] GitBook: [master] 206 pages modified --- getting-started.md | 496 +++++++++++++++++++++++++-------------------- 1 file changed, 276 insertions(+), 220 deletions(-) diff --git a/getting-started.md b/getting-started.md index a88f855..4af06a5 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,16 +8,32 @@ description: >- ## Installation -There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: +There are three ways to install and use Danfo.js in your application + +For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: ```text npm install danfojs-node + +or + +yarn add danfojs-node ``` -You can also install and use it in the browsers by using the CDN below: +For client side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: + +```text +npm install danfojs + +or + +yarn add danfojs +``` + +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): ```markup - + ``` {% hint style="info" %} @@ -26,9 +42,9 @@ To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https:// ## 10 minutes to danfo.js -This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. +We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -45,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -114,7 +130,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ NaN ║ +║ 3 │ undefined ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -168,17 +184,15 @@ s.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 1 │ 34 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╚═══╧════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -386,19 +400,17 @@ df.ctypes.print() ```text //output -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ string ║ -╟───┼──────────────────────╢ -║ B │ string ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ float32 ║ -╟───┼──────────────────────╢ -║ E │ string ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ string ║ +╟───┼─────────╢ +║ B │ string ║ +╟───┼─────────╢ +║ C │ int32 ║ +╟───┼─────────╢ +║ D │ float32 ║ +╟───┼─────────╢ +║ E │ string ║ +╚═══╧═════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -705,19 +717,23 @@ df.describe().print() ```text //output in console -╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ -╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -772,15 +788,17 @@ df.print() {% endtabs %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -939,7 +957,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing, both endpoints are _included_: +Showing label slicing: ```javascript const dfd = require("danfojs-node") @@ -970,17 +988,15 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - Shape: (3,2) + -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1026,15 +1042,13 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1078,13 +1092,11 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1103,17 +1115,62 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ Count ║ +╟────────────┼───────────────────╢ +║ 0 │ 21 ║ +╟────────────┼───────────────────╢ +║ 1 │ 5 ║ +╟────────────┼───────────────────╢ +║ 2 │ 30 ║ +╟────────────┼───────────────────╢ +║ 3 │ 10 ║ +╚════════════╧═══════════════════╝ +``` + +#### Selection with Boolean Mask + +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. + +```javascript +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) + +let sub_df = df.iloc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` + +```text +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. + +```javascript +let sub_df = df.iloc({ + rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), + columns: [0] +}) +sub_df.print() + +//output +╔════════════╤═══════════════════╗ +║ │ Name ║ +╟────────────┼───────────────────╢ +║ 0 │ Apples ║ +╚════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1194,7 +1251,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Selecting values from a DataFrame works on string columns: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1202,34 +1259,36 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +let query_df = df.query({ condition: df["B"].gt(5) }) query_df.print() //after query ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` -//after query +Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let query_df = df.query({ + condition: + df["B"].gt(5).and(df["A"].lt(30)) +}) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1249,7 +1308,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace +df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace df.print() ``` @@ -1281,7 +1340,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1309,22 +1368,22 @@ df.print() //after adding column Shape: (4,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 │ 25 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 │ 35 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 │ 45 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 │ 55 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data -danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. + **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1333,13 +1392,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} @@ -1380,27 +1439,27 @@ df_drop.print() ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping - Shape: (1,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1408,44 +1467,45 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 1}) +let df_drop = df.dropna(1) df_drop.print() ``` ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 34 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ + ``` Filling missing data: @@ -1455,13 +1515,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() ``` @@ -1485,14 +1545,16 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -1554,7 +1616,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.print() df.mean().print() //defaults to column axis ``` @@ -1608,11 +1670,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ 0 │ 4 ║ +║ A │ 4 ║ ╟───┼──────────────────────╢ -║ 1 │ 38.5 ║ +║ B │ 38.5 ║ ╟───┼──────────────────────╢ -║ 2 │ 31.75 ║ +║ C │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1666,7 +1728,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -1687,7 +1749,7 @@ df_new.print() #### Apply -Applying JavaScript functions to the data: +Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1696,11 +1758,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` @@ -1721,22 +1783,18 @@ df_new.print() //after applying -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` -Applying Tensorflow functions to the data: +Applying Element wise operations to the data: -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1745,13 +1803,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -function log_sig(x) { - return x.logSigmoid() +function sum_vals(x) { + return x + 10 } -let df_new = df.apply({axis: 0, callable: log_sig }) +let df_new = df.apply_map(sum_vals) df_new.print() ``` @@ -1770,19 +1826,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after applying + //after apply_map -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 12 │ 13 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 14 │ 15 │ 16 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 │ 50 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 49 │ 99 │ 88 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods From 7968a0dd298e78fe226999d2831655e31c8423a6 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Oct 2021 14:17:44 +0000 Subject: [PATCH 011/202] GitBook: [master] one page modified --- getting-started.md | 57 ++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/getting-started.md b/getting-started.md index 4af06a5..480b689 100644 --- a/getting-started.md +++ b/getting-started.md @@ -2325,29 +2325,36 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") - let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] - } + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] +} let df = new dfd.DataFrame(data) -df.to_csv().then((csv) => { - console.log(csv); +const csv = df.to_csv() +console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH + + +df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs + + +df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version -}).catch((err) => { - console.log(err); -}) ``` ```text @@ -2428,18 +2435,24 @@ let data = { let df = new dfd.DataFrame(data) -df.to_json().then((json) => { - console.log(json); +const json = df.to_json() +console.log(json); +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] -}).catch((err) => { - console.log(err); -}) -``` +const json = df.to_json({format: "row"}) +console.log(json); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From 87756ef5b0ac83764d1f9caedfec56153eef217f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Oct 2021 14:27:01 +0000 Subject: [PATCH 012/202] GitBook: [master] 2 pages modified --- getting-started.md | 553 ++++++++++++++++++++------------------------- release-notes.md | 8 +- 2 files changed, 249 insertions(+), 312 deletions(-) diff --git a/getting-started.md b/getting-started.md index 480b689..a88f855 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,32 +8,16 @@ description: >- ## Installation -There are three ways to install and use Danfo.js in your application - -For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: +There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: ```text npm install danfojs-node - -or - -yarn add danfojs-node -``` - -For client side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: - -```text -npm install danfojs - -or - -yarn add danfojs ``` -For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): +You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} @@ -42,9 +26,9 @@ To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https:// ## 10 minutes to danfo.js -This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. +We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -61,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -130,7 +114,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ undefined ║ +║ 3 │ NaN ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -184,15 +168,17 @@ s.print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 12 ║ -╟───┼────╢ -║ 1 │ 34 ║ -╟───┼────╢ -║ 2 │ 56 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -400,17 +386,19 @@ df.ctypes.print() ```text //output -╔═══╤═════════╗ -║ A │ string ║ -╟───┼─────────╢ -║ B │ string ║ -╟───┼─────────╢ -║ C │ int32 ║ -╟───┼─────────╢ -║ D │ float32 ║ -╟───┼─────────╢ -║ E │ string ║ -╚═══╧═════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ string ║ +╟───┼──────────────────────╢ +║ B │ string ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ float32 ║ +╟───┼──────────────────────╢ +║ E │ string ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -717,23 +705,19 @@ df.describe().print() ```text //output in console -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ +╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -788,17 +772,15 @@ df.print() {% endtabs %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ -4 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47.3 │ 5 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -20 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -957,7 +939,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing: +Showing label slicing, both endpoints are _included_: ```javascript const dfd = require("danfojs-node") @@ -988,15 +970,17 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - + Shape: (3,2) -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1042,13 +1026,15 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1092,11 +1078,13 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1115,62 +1103,17 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╗ -║ │ Count ║ -╟────────────┼───────────────────╢ -║ 0 │ 21 ║ -╟────────────┼───────────────────╢ -║ 1 │ 5 ║ -╟────────────┼───────────────────╢ -║ 2 │ 30 ║ -╟────────────┼───────────────────╢ -║ 3 │ 10 ║ -╚════════════╧═══════════════════╝ -``` - -#### Selection with Boolean Mask - -You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. - -```javascript -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) - -let sub_df = df.iloc({ rows: df["Count"].gt(10) }) -sub_df.print() -``` - -```text -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. - -```javascript -let sub_df = df.iloc({ - rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), - columns: [0] -}) -sub_df.print() - -//output -╔════════════╤═══════════════════╗ -║ │ Name ║ -╟────────────┼───────────────────╢ -║ 0 │ Apples ║ -╚════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1251,7 +1194,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: +Selecting values from a DataFrame works on string columns: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1259,36 +1202,34 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -let query_df = df.query({ condition: df["B"].gt(5) }) +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) query_df.print() //after query ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let query_df = df.query({ - condition: - df["B"].gt(5).and(df["A"].lt(30)) -}) -query_df.print() //after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1308,7 +1249,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace +df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() ``` @@ -1340,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1368,22 +1309,22 @@ df.print() //after adding column Shape: (4,3) -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 │ 25 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 │ 35 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 │ 45 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 │ 55 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data - **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. To drop any rows that have missing data: @@ -1392,13 +1333,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropna({axis: 0}) df_drop.print() ``` {% endtab %} @@ -1439,27 +1380,27 @@ df_drop.print() ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + Shape: (1,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1467,45 +1408,44 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(1) +let df_drop = df.dropna({axis: 1}) df_drop.print() ``` ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ NaN │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 34 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╗ -║ │ C ║ -╟────────────┼───────────────────╢ -║ 0 │ 3 ║ -╟────────────┼───────────────────╢ -║ 1 │ 6 ║ -╟────────────┼───────────────────╢ -║ 2 │ 40 ║ -╟────────────┼───────────────────╢ -║ 3 │ 78 ║ -╚════════════╧═══════════════════╝ - +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ ``` Filling missing data: @@ -1515,13 +1455,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillna({ values: ["Apples"] }) df_filled.print() ``` @@ -1545,16 +1485,14 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} +let data = {"Name":["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) +let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) df_filled.print() ``` @@ -1616,7 +1554,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) +let df = new dfd.DataFrame(data) df.print() df.mean().print() //defaults to column axis ``` @@ -1670,11 +1608,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ A │ 4 ║ +║ 0 │ 4 ║ ╟───┼──────────────────────╢ -║ B │ 38.5 ║ +║ 1 │ 38.5 ║ ╟───┼──────────────────────╢ -║ C │ 31.75 ║ +║ 2 │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1728,7 +1666,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, { axis: 1 }) +let df_new = df.sub(sf, axis = 1) df_new.print() ``` @@ -1749,7 +1687,7 @@ df_new.print() #### Apply -Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: +Applying JavaScript functions to the data: ```javascript const dfd = require("danfojs") @@ -1758,11 +1696,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); +function sum_vals(x) { + return x + 20 } -let df_new = df.apply(sum_vals, { axis: 1 }) +let df_new = df.apply({callable: sum_vals }) df_new.print() ``` @@ -1783,18 +1721,22 @@ df_new.print() //after applying -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 22 │ 23 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 24 │ 25 │ 26 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 40 │ 50 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 59 │ 109 │ 98 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Applying Element wise operations to the data: +Applying Tensorflow functions to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. ```javascript const dfd = require("danfojs-node") @@ -1803,11 +1745,13 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 10 +df.print() + +function log_sig(x) { + return x.logSigmoid() } -let df_new = df.apply_map(sum_vals) +let df_new = df.apply({axis: 0, callable: log_sig }) df_new.print() ``` @@ -1826,19 +1770,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after apply_map + //after applying -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 12 │ 13 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 14 │ 15 │ 16 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 │ 50 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 49 │ 99 │ 88 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2325,36 +2269,29 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. ```javascript const dfd = require("danfojs-node") + let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] -} + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] + } let df = new dfd.DataFrame(data) -const csv = df.to_csv() -console.log(csv); -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH - - -df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs - - -df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version +df.to_csv().then((csv) => { + console.log(csv); +}).catch((err) => { + console.log(err); +}) ``` ```text @@ -2435,24 +2372,18 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.to_json() -console.log(json); -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] +df.to_json().then((json) => { + console.log(json); +}).catch((err) => { -const json = df.to_json({format: "row"}) -console.log(json); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} + console.log(err); +}) +``` +```text +[{"Abs":20.2,"Count":34,"country code":"NG"}, +{"Abs":30,"Count":4,"country code":"FR"}, +{"Abs":47.3,"Count":5,"country code":"GH"}] ``` diff --git a/release-notes.md b/release-notes.md index 1f8ab6b..fc8d8e9 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,12 @@ # Release Notes -### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.1\), Browser \(0.3.1\) +### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.2\), Browser \(0.3.2\) + +**Date:** 2nd Oct 2021 + +Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. + +### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.1\), Browser \(0.3.1\) **Date:** 1st Oct 2021 From 0b280849565a9e4996bd42b67e87e17e09cc523a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Oct 2021 15:29:54 +0100 Subject: [PATCH 013/202] Update version number --- getting-started.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/getting-started.md b/getting-started.md index a88f855..b3e0e33 100644 --- a/getting-started.md +++ b/getting-started.md @@ -17,7 +17,7 @@ npm install danfojs-node You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} @@ -45,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -84,7 +84,7 @@ s.print() - Document + Document @@ -145,7 +145,7 @@ s.print() - + Document @@ -208,7 +208,7 @@ df.print() - Document + Document @@ -256,7 +256,7 @@ df.ctypes.print() - Document + Document @@ -334,7 +334,7 @@ df.print() - Document + Document @@ -427,7 +427,7 @@ df.print() - Document + Document @@ -530,7 +530,7 @@ console.log(df.columns); - Document + Document @@ -598,7 +598,7 @@ df.tensor.print() - Document + Document @@ -678,7 +678,7 @@ df.describe().print() - Document + Document @@ -747,7 +747,7 @@ df.print() - Document + Document @@ -815,7 +815,7 @@ df['A'].print() - Document + Document @@ -1145,7 +1145,7 @@ query_df.print() //after query - Document + Document @@ -1264,7 +1264,7 @@ df.print() - Document + Document @@ -1353,7 +1353,7 @@ df_drop.print() - Document + Document @@ -1569,7 +1569,7 @@ df.mean().print() //defaults to column axis - Document + Document @@ -2197,7 +2197,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. - + Document @@ -2244,7 +2244,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2330,7 +2330,7 @@ dfd.read_csv("file:///home/Desktop/titanic.csv") - + Document From f18b33fd7dbc88855e2379367868ee7f7bfff89a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 00:29:34 +0000 Subject: [PATCH 014/202] GitBook: [master] 8 pages modified --- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/input-output/danfo.read_csv.md | 143 +---- .../input-output/danfo.read_excel.md | 12 +- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +- getting-started.md | 589 ++++++++++-------- 8 files changed, 381 insertions(+), 458 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3e20f6a..f74da8c 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,7 +21,9 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

value: Series, Array. New values to add }

+

values: Series, Array of new values to add +
inplace: Default to false.

+

}

@@ -30,13 +32,11 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** - ****return **Null** - ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,12 +53,11 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -112,12 +111,11 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -126,7 +124,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3e1318e..8445c35 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,7 +37,9 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** - ****return **DataFrame** +```text + ****return **DataFrame** +``` ## **Examples** @@ -46,7 +48,6 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -59,12 +60,11 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -73,7 +73,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,12 +117,11 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -132,7 +130,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,5 +156,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d1ab8f8..0bab005 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -22,9 +22,8 @@ description: >- source: str, path or URL - Any valid string path is acceptable. The string could be a URL. Valid - URL schemes include https, http, ftp, s3, gs, and file. Local file paths - are only accepted in Nodejs environment. + Any valid string path is acceptable. The string could be a URL or a valid + local file path. @@ -32,12 +31,12 @@ description: >- object, optional

-

A CSV Config object that contains configurations for reading and decoding - from CSV file(s). Supported params are:

-

start: The index position to start from when reading the CSV file.

-

end: The end position to stop at when reading the CSV file.

-

... csvConfigs: other supported Tensorflow csvConfig parameters. - See https://js.tensorflow.org/api/latest/#data.csv +

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

+

+

We set the following params by default:

+

dynamicTyping: true +

+

header: true

@@ -163,131 +162,5 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -**Reading Large Files** - -For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: - -**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_process_data() { - let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) - let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) - - df_chunk1.head().print() - df_chunk2.head().print() -} - -load_process_data() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - -
- - - - - - - -``` -{% endtab %} -{% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..9dbe248 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -27,13 +27,6 @@ description: Reads an excel file into DataFrame. >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. > Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

>

}

> > @@ -46,14 +39,15 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read\_excel** method can read excel files saved in local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index e412af9..9fd06ff 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 397b480..b9d73a8 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,12 +44,11 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + - ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 66dd124..48b3b1c 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,9 +9,7 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) - - -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -19,9 +17,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -### Setting up your environment +## Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -31,9 +29,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -46,7 +44,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -### Loading and processing your data +## Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -54,11 +52,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -80,7 +78,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -110,7 +108,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -120,7 +118,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -138,7 +136,6 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -159,7 +156,6 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -183,7 +179,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -193,7 +189,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -250,11 +246,11 @@ async function load_process_data() { load_process_data() ``` -### Model Building With Tensorflow.js +## Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -268,12 +264,11 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript - async function train() { const model = get_model() const data = await load_process_data() @@ -285,7 +280,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -298,15 +293,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -393,7 +388,6 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text - Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -419,13 +413,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index b3e0e33..480b689 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,16 +8,32 @@ description: >- ## Installation -There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: +There are three ways to install and use Danfo.js in your application + +For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: ```text npm install danfojs-node + +or + +yarn add danfojs-node +``` + +For client side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: + +```text +npm install danfojs + +or + +yarn add danfojs ``` -You can also install and use it in the browsers by using the CDN below: +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): ```markup - + ``` {% hint style="info" %} @@ -26,9 +42,9 @@ To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https:// ## 10 minutes to danfo.js -This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. +We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -45,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -84,7 +100,7 @@ s.print() - Document + Document @@ -114,7 +130,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ NaN ║ +║ 3 │ undefined ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -145,7 +161,7 @@ s.print() - + Document @@ -168,17 +184,15 @@ s.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 1 │ 34 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╚═══╧════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -208,7 +222,7 @@ df.print() - Document + Document @@ -256,7 +270,7 @@ df.ctypes.print() - Document + Document @@ -334,7 +348,7 @@ df.print() - Document + Document @@ -386,19 +400,17 @@ df.ctypes.print() ```text //output -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ string ║ -╟───┼──────────────────────╢ -║ B │ string ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ float32 ║ -╟───┼──────────────────────╢ -║ E │ string ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ string ║ +╟───┼─────────╢ +║ B │ string ║ +╟───┼─────────╢ +║ C │ int32 ║ +╟───┼─────────╢ +║ D │ float32 ║ +╟───┼─────────╢ +║ E │ string ║ +╚═══╧═════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -427,7 +439,7 @@ df.print() - Document + Document @@ -530,7 +542,7 @@ console.log(df.columns); - Document + Document @@ -598,7 +610,7 @@ df.tensor.print() - Document + Document @@ -678,7 +690,7 @@ df.describe().print() - Document + Document @@ -705,19 +717,23 @@ df.describe().print() ```text //output in console -╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ -╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -747,7 +763,7 @@ df.print() - Document + Document @@ -772,15 +788,17 @@ df.print() {% endtabs %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -815,7 +833,7 @@ df['A'].print() - Document + Document @@ -939,7 +957,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing, both endpoints are _included_: +Showing label slicing: ```javascript const dfd = require("danfojs-node") @@ -970,17 +988,15 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - Shape: (3,2) + -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1026,15 +1042,13 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1078,13 +1092,11 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1103,17 +1115,62 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ Count ║ +╟────────────┼───────────────────╢ +║ 0 │ 21 ║ +╟────────────┼───────────────────╢ +║ 1 │ 5 ║ +╟────────────┼───────────────────╢ +║ 2 │ 30 ║ +╟────────────┼───────────────────╢ +║ 3 │ 10 ║ +╚════════════╧═══════════════════╝ +``` + +#### Selection with Boolean Mask + +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. + +```javascript +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) + +let sub_df = df.iloc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` + +```text +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. + +```javascript +let sub_df = df.iloc({ + rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), + columns: [0] +}) +sub_df.print() + +//output +╔════════════╤═══════════════════╗ +║ │ Name ║ +╟────────────┼───────────────────╢ +║ 0 │ Apples ║ +╚════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1145,7 +1202,7 @@ query_df.print() //after query - Document + Document @@ -1194,7 +1251,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Selecting values from a DataFrame works on string columns: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1202,34 +1259,36 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +let query_df = df.query({ condition: df["B"].gt(5) }) query_df.print() //after query ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` -//after query +Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let query_df = df.query({ + condition: + df["B"].gt(5).and(df["A"].lt(30)) +}) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1249,7 +1308,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace +df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace df.print() ``` @@ -1264,7 +1323,7 @@ df.print() - Document + Document @@ -1281,7 +1340,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1309,22 +1368,22 @@ df.print() //after adding column Shape: (4,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 │ 25 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 │ 35 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 │ 45 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 │ 55 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data -danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. + **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1333,13 +1392,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} @@ -1353,7 +1412,7 @@ df_drop.print() - Document + Document @@ -1380,27 +1439,27 @@ df_drop.print() ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping - Shape: (1,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1408,44 +1467,45 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 1}) +let df_drop = df.dropna(1) df_drop.print() ``` ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 34 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ + ``` Filling missing data: @@ -1455,13 +1515,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() ``` @@ -1485,14 +1545,16 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -1554,7 +1616,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.print() df.mean().print() //defaults to column axis ``` @@ -1569,7 +1631,7 @@ df.mean().print() //defaults to column axis - Document + Document @@ -1608,11 +1670,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ 0 │ 4 ║ +║ A │ 4 ║ ╟───┼──────────────────────╢ -║ 1 │ 38.5 ║ +║ B │ 38.5 ║ ╟───┼──────────────────────╢ -║ 2 │ 31.75 ║ +║ C │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1666,7 +1728,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -1687,7 +1749,7 @@ df_new.print() #### Apply -Applying JavaScript functions to the data: +Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1696,11 +1758,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` @@ -1721,22 +1783,18 @@ df_new.print() //after applying -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` -Applying Tensorflow functions to the data: +Applying Element wise operations to the data: -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1745,13 +1803,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -function log_sig(x) { - return x.logSigmoid() +function sum_vals(x) { + return x + 10 } -let df_new = df.apply({axis: 0, callable: log_sig }) +let df_new = df.apply_map(sum_vals) df_new.print() ``` @@ -1770,19 +1826,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after applying + //after apply_map -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 12 │ 13 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 14 │ 15 │ 16 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 │ 50 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 49 │ 99 │ 88 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2197,7 +2253,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. - + Document @@ -2244,7 +2300,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2269,29 +2325,36 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") - let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] - } + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] +} let df = new dfd.DataFrame(data) -df.to_csv().then((csv) => { - console.log(csv); +const csv = df.to_csv() +console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH + + +df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs + + +df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version -}).catch((err) => { - console.log(err); -}) ``` ```text @@ -2330,7 +2393,7 @@ dfd.read_csv("file:///home/Desktop/titanic.csv") - + Document @@ -2372,18 +2435,24 @@ let data = { let df = new dfd.DataFrame(data) -df.to_json().then((json) => { - console.log(json); +const json = df.to_json() +console.log(json); +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] -}).catch((err) => { - console.log(err); -}) -``` +const json = df.to_json({format: "row"}) +console.log(json); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From 35cf0ab4049fb366c7209d7a4e948a889080624d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 12:26:12 +0000 Subject: [PATCH 015/202] GitBook: [master] 210 pages modified --- README.md | 12 +- SUMMARY.md | 3 + api-reference/README.md | 2 +- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 ++--- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 ++++++++++-------- api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 101 ++++++----- .../input-output/danfo.read_excel.md | 12 +- api-reference/input-output/danfo.to_csv.md | 157 ++++++++++++++++ api-reference/input-output/danfo.to_excel.md | 92 ++++++++++ api-reference/input-output/danfo.to_json.md | 160 ++++++++++++++++ api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +++--- getting-started.md | 4 +- 20 files changed, 667 insertions(+), 209 deletions(-) create mode 100644 api-reference/input-output/danfo.to_csv.md create mode 100644 api-reference/input-output/danfo.to_excel.md create mode 100644 api-reference/input-output/danfo.to_json.md diff --git a/README.md b/README.md index 92e7da5..b170fbb 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects +* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. -* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. +* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. {% page-ref page="getting-started.md" %} diff --git a/SUMMARY.md b/SUMMARY.md index 961418d..9adf7af 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,6 +17,9 @@ * [danfo.read\_excel](api-reference/input-output/danfo.read_excel.md) * [danfo.read\_json](api-reference/input-output/danfo.read_json.md) * [danfo.read\_csv](api-reference/input-output/danfo.read_csv.md) + * [danfo.to\_csv](api-reference/input-output/danfo.to_csv.md) + * [danfo.to\_excel](api-reference/input-output/danfo.to_excel.md) + * [danfo.to\_json](api-reference/input-output/danfo.to_json.md) * [Series](api-reference/series/README.md) * [Series.append](api-reference/series/series.append.md) * [Series.cumsum](api-reference/series/series.cumsum.md) diff --git a/api-reference/README.md b/api-reference/README.md index 70dff34..492db09 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index f74da8c..3e20f6a 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,9 +21,7 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

values: Series, Array of new values to add -
inplace: Default to false.

-

}

+

value: Series, Array. New values to add }

@@ -32,11 +30,13 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** + ****return **Null** + ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,11 +53,12 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -111,11 +112,12 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -124,6 +126,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 8445c35..3e1318e 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,9 +37,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** -```text - ****return **DataFrame** -``` + ****return **DataFrame** ## **Examples** @@ -48,6 +46,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript + const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -60,11 +59,12 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -73,6 +73,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -117,11 +118,12 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -130,6 +132,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -156,5 +159,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index b74b5da..692b225 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 1cb3b8f..54fc0ae 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,18 +17,24 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - kwargs + data + Series or Dataframe + The data to dummify + + + + options Object

{

-

data: Array | Series | DataFrame

-

prefix_sep: String separator for created columns e.g "_",

+

columns: Array of column names to dummify. If not specified, all + categorical columns are encoded.

+

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

-

columns: [Array] columns to be encoded in DataFrame.

}

- {prefix_sep: "_"} + {prefixSeparator: "_"} @@ -49,7 +55,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) dum_df.print() ``` {% endtab %} @@ -65,19 +71,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -96,7 +102,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df }) +let dum_df = dfd.get_dummies(df) dum_df.print() ``` {% endtab %} @@ -159,7 +165,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 752a196..5251d48 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 5e66567..43b2476 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 2e7c0a3..4077198 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Convert Object to datetime format +description: Converts an array of Date time string to Date object. --- # danfo.to\_datetime -danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,15 +17,12 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - - + @@ -38,14 +35,16 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan ## **Examples** -### **Convert Series to Dummy codes** +Converts a **Series** of Date strings to Date time and get time properties {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -let dt = dfd.to_datetime({data:sf}) +sf.print() + +let dt = dfd.toDateTime({data:sf}) dt.month().print() dt.month_name().print() @@ -65,85 +64,99 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + //Int representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╚═══╧══════════════════════╝ + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 //string representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╟───┼──────────────────────╢ -║ 3 │ Apr ║ -╟───┼──────────────────────╢ -║ 4 │ May ║ -╚═══╧══════════════════════╝ +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec //string representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Mon ║ -╟───┼──────────────────────╢ -║ 1 │ Thu ║ -╟───┼──────────────────────╢ -║ 2 │ Thu ║ -╟───┼──────────────────────╢ -║ 3 │ Sun ║ -╟───┼──────────────────────╢ -║ 4 │ Tue ║ -╚═══╧══════════════════════╝ - -//Int representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 2 ║ -╚═══╧══════════════════════╝ +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + //Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 0 ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f071ac9..f015c6e 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,7 +1,5 @@ --- -description: >- - Functions and methods to easily read tabular/structured data into DataFrame - and Series Objects +description: Functions for reading tabular/structured data into DataFrame/Series Objects --- # Input/Output @@ -11,8 +9,11 @@ description: >- | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | +| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 0bab005..570c7c3 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,10 +20,15 @@ description: >- - - - + + + @@ -32,14 +37,15 @@ description: >- + -
kwargs + data ObjectArray, Series -

{

-

data: Array | Series, the object to convert.

-

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", - and "%m-d-Y H%M%S%"

-

}

+

data: Array | Series with Date strings to convert to Date time.

+

<b></b>

source:str, path or URLAny valid string path is acceptable. The string could be a URL or a valid - local file path.source + File object, File path, URL +

Any valid string path is acceptable. The string could be a URL or a valid + local file path.

+

A browser input file object is + also supported.

+

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

-

-

We set the following params by default:

-

dynamicTyping: true -

-

header: true +

<b></b>

+
+

{

+

dynamicTyping: true,

+

header: true

+

}

@@ -48,16 +54,39 @@ description: >- ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. -The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("user_names.csv") //assumes file is in CWD +dfd.read_csv("./user_names.csv") //assumes file is in CWD + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading files from a URL** + +By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -76,8 +105,8 @@ dfd.read_csv("user_names.csv") //assumes file is in CWD - - + + Document @@ -105,26 +134,11 @@ dfd.read_csv("user_names.csv") //assumes file is in CWD {% endtab %} {% endtabs %} -**Loading Files from URL** +### **Reading an input file object in the browser** -By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series {% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - {% tab title="Browser" %} ```markup @@ -133,25 +147,20 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + Document - -
+ @@ -162,5 +171,3 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} - - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 9dbe248..d8e3d9e 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -27,6 +27,13 @@ description: Reads an excel file into DataFrame. >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. > Default will be the first sheet.

+>

header_index : int, (Optional) Only used in browser environment. +> The Index of the row which represents the header(columns) of the data. +> Default will be the first non empty row.

+>

data_index : int, (Optional) Only used in browser environment. The +> index of the row from which actual data(content) starts. Default will be +> the next row of header_index +>

>

}

> > @@ -39,15 +46,14 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved in local disk, or over the internet. +The **read\_excel** method can read excel files saved from local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -const path = require("path") -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") +local_xcel = 'testexcel.xls' async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md new file mode 100644 index 0000000..4bb5456 --- /dev/null +++ b/api-reference/input-output/danfo.to_csv.md @@ -0,0 +1,157 @@ +--- +description: Writes a DataFrame or Series to CSV format. +--- + +# danfo.to\_csv + +> danfo.**to\_csv**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)\] + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
data + Series or DataFrameThe Series or DataFrame to write to CSV
options + object, optional +

Configuration object:

+

{

+

filePath: Local file path to write the CSV file to. + If not specified, the CSV will be returned as a string. Only needed in + Nodejs version +
fileName: The name of the file to download as. Only + needed in browser environment. +
download: Boolean indicating whether to automatically + download the CSV file in the browser. Only needed in the browser environment.

+

header: Boolean indicating whether to include a header + row in the CSV file.

+

sep: Character to be used as a separator in the CSV + file.

+

+

}

+
{ +
download: true, +
sep: "," +
+
}
+ +The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +### Convert DataFrame to CSV string and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const csv = df.to_csv({ download: false }); +console.log(csv); + +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ filePath: "testOut.csv"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and download file in browser + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ fileName: "testOut.csv", download: true}); +``` + diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md new file mode 100644 index 0000000..0b781b4 --- /dev/null +++ b/api-reference/input-output/danfo.to_excel.md @@ -0,0 +1,92 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# danfo.to\_excel + +> danfo.**to\_excel**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)\] + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
data + Series or DataFrameThe Series or DataFrame to write to CSV
options + object, optional +

Configuration object:

+

{

+

filePath: Local file path to write the CSV file to. + If not specified, the CSV will be returned as a string. Only needed in + Nodejs version +
fileName: The name of the file to download as. Only + needed in the browser environment. +
sheetName: Name to call the excel sheet.

+

}

+
{ +
filePath: "./output.xlsx", +
sheetName: "Sheet1" +
+
}
+ +The **to\_excel** function can be used to write out a DataFrame or Series to Excel \(**.xlsx**\) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in a browser + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ fileName: "testOut.xlsx"}); +``` + diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md new file mode 100644 index 0000000..878eb5f --- /dev/null +++ b/api-reference/input-output/danfo.to_json.md @@ -0,0 +1,160 @@ +# danfo.to\_json + +> danfo.**to\_json**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)\] + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
data + Series or DataFrameThe Series or DataFrame to write to CSV
options + object, optional +

Configuration object:

+

{

+

filePath: Local file path to write the CSV file to. + If not specified, the CSV will be returned as a string. Only needed in + Nodejs version +
fileName: The name of the file to download as. Only + needed in browser environment. +
format: The format of the JSON. Can be one of row or column.

+

}

+
{ +
format: "column" +
}
+ +The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. + +### Convert DataFrame/Series to JSON and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = df.to_json({ download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = df.to_json({ + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ filePath: "./testOutput.json" }); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ fileName: "test_out.json" }); +``` + diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 9fd06ff..e412af9 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index b9d73a8..397b480 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,11 +44,12 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + + ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 48b3b1c..66dd124 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,7 +9,9 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. + + +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -17,9 +19,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -## Setting up your environment +### Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -29,9 +31,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -44,7 +46,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -## Loading and processing your data +### Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -52,11 +54,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -78,7 +80,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -108,7 +110,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -118,7 +120,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -136,6 +138,7 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -156,6 +159,7 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -179,7 +183,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -189,7 +193,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -246,11 +250,11 @@ async function load_process_data() { load_process_data() ``` -## Model Building With Tensorflow.js +### Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -264,11 +268,12 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript + async function train() { const model = get_model() const data = await load_process_data() @@ -280,7 +285,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -293,15 +298,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -388,6 +393,7 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text + Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -413,13 +419,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index 480b689..f5f99a2 100644 --- a/getting-started.md +++ b/getting-started.md @@ -20,7 +20,7 @@ or yarn add danfojs-node ``` -For client side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: +For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: ```text npm install danfojs @@ -37,7 +37,7 @@ For use directly in HTML files, you can add the latest script tag from [JsDelivr ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js From d44b5ac7105be4dca5a6798da389a1f3cdb15769 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 12:37:53 +0000 Subject: [PATCH 016/202] GitBook: [master] 11 pages modified --- README.md | 12 +- api-reference/README.md | 2 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 +- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 +++--- api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 194 ++++-- api-reference/input-output/danfo.read_json.md | 135 ++++- getting-started.md | 555 ++++++++---------- 11 files changed, 645 insertions(+), 491 deletions(-) diff --git a/README.md b/README.md index b170fbb..92e7da5 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects +* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. -* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. +* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. +New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. {% page-ref page="getting-started.md" %} diff --git a/api-reference/README.md b/api-reference/README.md index 492db09..70dff34 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index 692b225..b74b5da 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 54fc0ae..1cb3b8f 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,24 +17,18 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - data - Series or Dataframe - The data to dummify - - - - options + kwargs Object

{

-

columns: Array of column names to dummify. If not specified, all - categorical columns are encoded.

-

prefixSeparator: String separator for created columns e.g "_",

+

data: Array | Series | DataFrame

+

prefix_sep: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

+

columns: [Array] columns to be encoded in DataFrame.

}

- {prefixSeparator: "_"} + {prefix_sep: "_"} @@ -55,7 +49,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) dum_df.print() ``` {% endtab %} @@ -71,19 +65,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -102,7 +96,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df) +let dum_df = dfd.get_dummies({ data: df }) dum_df.print() ``` {% endtab %} @@ -165,7 +159,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 5251d48..752a196 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 43b2476..5e66567 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 4077198..2e7c0a3 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Converts an array of Date time string to Date object. +description: Convert Object to datetime format --- # danfo.to\_datetime -danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,12 +17,15 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo - - + @@ -35,16 +38,14 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo ## **Examples** -Converts a **Series** of Date strings to Date time and get time properties +### **Convert Series to Dummy codes** {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime({data:sf}) +let dt = dfd.to_datetime({data:sf}) dt.month().print() dt.month_name().print() @@ -64,99 +65,85 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - //Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 3 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╚═══╧══════════════════════╝ //string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Jan ║ +╟───┼──────────────────────╢ +║ 1 │ Feb ║ +╟───┼──────────────────────╢ +║ 2 │ Mar ║ +╟───┼──────────────────────╢ +║ 3 │ Apr ║ +╟───┼──────────────────────╢ +║ 4 │ May ║ +╚═══╧══════════════════════╝ //string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Mon ║ +╟───┼──────────────────────╢ +║ 1 │ Thu ║ +╟───┼──────────────────────╢ +║ 2 │ Thu ║ +╟───┼──────────────────────╢ +║ 3 │ Sun ║ +╟───┼──────────────────────╢ +║ 4 │ Tue ║ +╚═══╧══════════════════════╝ + +//Int representation for day of the week +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 2 ║ +╚═══╧══════════════════════╝ //Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 0 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 0 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f015c6e..f071ac9 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,5 +1,7 @@ --- -description: Functions for reading tabular/structured data into DataFrame/Series Objects +description: >- + Functions and methods to easily read tabular/structured data into DataFrame + and Series Objects --- # Input/Output @@ -9,11 +11,8 @@ description: Functions for reading tabular/structured data into DataFrame/Series | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | -| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) +Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 570c7c3..d1ab8f8 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,15 +20,11 @@ description: >- - - - + + + @@ -36,16 +32,15 @@ description: >- - +
data + kwargs Array, SeriesObject -

data: Array | Series with Date strings to convert to Date time.

-

<b></b>

+

{

+

data: Array | Series, the object to convert.

+

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", + and "%m-d-Y H%M%S%"

+

}

source - File object, File path, URL -

Any valid string path is acceptable. The string could be a URL or a valid - local file path.

-

A browser input file object is - also supported.

-
source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid + URL schemes include https, http, ftp, s3, gs, and file. Local file paths + are only accepted in Nodejs environment.
object, optional

-

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

-

<b></b>

-
-

{ +

A CSV Config object that contains configurations for reading and decoding + from CSV file(s). Supported params are:

+

start: The index position to start from when reading the CSV file.

+

end: The end position to stop at when reading the CSV file.

+

... csvConfigs: other supported Tensorflow csvConfig parameters. + See https://js.tensorflow.org/api/latest/#data.csv

-

dynamicTyping: true,

-

header: true

-

}

@@ -54,18 +49,16 @@ description: >- ****_**Promise**_. Resolves to DataFrame -The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. +### Example -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: +The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("./user_names.csv") //assumes file is in CWD +dfd.read_csv("user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -75,9 +68,45 @@ dfd.read_csv("./user_names.csv") //assumes file is in CWD }) ``` {% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` +{% endtab %} {% endtabs %} -### **Reading files from a URL** +**Loading Files from URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -105,8 +134,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -134,11 +163,29 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -### **Reading an input file object in the browser** +**Reading Large Files** + +For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series +**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. {% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_process_data() { + let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) + let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) + + df_chunk1.head().print() + df_chunk2.head().print() +} + +load_process_data() +``` +{% endtab %} + {% tab title="Browser" %} ```markup @@ -147,27 +194,100 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document - + +
+ + ``` {% endtab %} {% endtabs %} +```bash +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + + + diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 49528d0..5b54e20 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,24 +6,83 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] -| **Parameters** | Type | Description | -| :--- | :--- | :--- | -| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
source + Input file object, string file path or URL +

Any valid string path is acceptable. The string could be a URL. Valid + URL schemes include http, https, ftp, s3, gs, or a local path. Both relative + and absolute paths are supported

+

+

An input file object is also supported in the browser.

+
optionsObject +

Configuration options for reading JSON files. Supported options:

+

method: The HTTP method to use.

+

headers: Additional headers to send with the request if reading + JSON from remote url. Supports all the node-fetch options in + Nodejs, and all fetch options in + browsers.

+
{ +
method: "GET" +
}
**Returns:** ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. -The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: +### **Reading JSON files from local disk** {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("user_names.json") +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") .then(df => { df.head().print() @@ -36,6 +95,70 @@ dfd.read_json("user_names.json") {% tab title="Browser" %} ```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + ``` {% endtab %} diff --git a/getting-started.md b/getting-started.md index f5f99a2..a88f855 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,43 +8,27 @@ description: >- ## Installation -There are three ways to install and use Danfo.js in your application - -For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: +There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: ```text npm install danfojs-node - -or - -yarn add danfojs-node -``` - -For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: - -```text -npm install danfojs - -or - -yarn add danfojs ``` -For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): +You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. +We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -61,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -130,7 +114,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ undefined ║ +║ 3 │ NaN ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -184,15 +168,17 @@ s.print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 12 ║ -╟───┼────╢ -║ 1 │ 34 ║ -╟───┼────╢ -║ 2 │ 56 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -400,17 +386,19 @@ df.ctypes.print() ```text //output -╔═══╤═════════╗ -║ A │ string ║ -╟───┼─────────╢ -║ B │ string ║ -╟───┼─────────╢ -║ C │ int32 ║ -╟───┼─────────╢ -║ D │ float32 ║ -╟───┼─────────╢ -║ E │ string ║ -╚═══╧═════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ string ║ +╟───┼──────────────────────╢ +║ B │ string ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ float32 ║ +╟───┼──────────────────────╢ +║ E │ string ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -717,23 +705,19 @@ df.describe().print() ```text //output in console -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ +╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -788,17 +772,15 @@ df.print() {% endtabs %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ -4 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47.3 │ 5 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -20 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -957,7 +939,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing: +Showing label slicing, both endpoints are _included_: ```javascript const dfd = require("danfojs-node") @@ -988,15 +970,17 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - + Shape: (3,2) -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1042,13 +1026,15 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1092,11 +1078,13 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1115,62 +1103,17 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╗ -║ │ Count ║ -╟────────────┼───────────────────╢ -║ 0 │ 21 ║ -╟────────────┼───────────────────╢ -║ 1 │ 5 ║ -╟────────────┼───────────────────╢ -║ 2 │ 30 ║ -╟────────────┼───────────────────╢ -║ 3 │ 10 ║ -╚════════════╧═══════════════════╝ -``` - -#### Selection with Boolean Mask - -You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. - -```javascript -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) - -let sub_df = df.iloc({ rows: df["Count"].gt(10) }) -sub_df.print() -``` - -```text -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. - -```javascript -let sub_df = df.iloc({ - rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), - columns: [0] -}) -sub_df.print() - -//output -╔════════════╤═══════════════════╗ -║ │ Name ║ -╟────────────┼───────────────────╢ -║ 0 │ Apples ║ -╚════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1251,7 +1194,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: +Selecting values from a DataFrame works on string columns: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1259,36 +1202,34 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -let query_df = df.query({ condition: df["B"].gt(5) }) +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) query_df.print() //after query ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let query_df = df.query({ - condition: - df["B"].gt(5).and(df["A"].lt(30)) -}) -query_df.print() //after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1308,7 +1249,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace +df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() ``` @@ -1340,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1368,22 +1309,22 @@ df.print() //after adding column Shape: (4,3) -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 │ 25 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 │ 35 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 │ 45 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 │ 55 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data - **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. To drop any rows that have missing data: @@ -1392,13 +1333,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropna({axis: 0}) df_drop.print() ``` {% endtab %} @@ -1439,27 +1380,27 @@ df_drop.print() ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + Shape: (1,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1467,45 +1408,44 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(1) +let df_drop = df.dropna({axis: 1}) df_drop.print() ``` ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ NaN │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 34 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╗ -║ │ C ║ -╟────────────┼───────────────────╢ -║ 0 │ 3 ║ -╟────────────┼───────────────────╢ -║ 1 │ 6 ║ -╟────────────┼───────────────────╢ -║ 2 │ 40 ║ -╟────────────┼───────────────────╢ -║ 3 │ 78 ║ -╚════════════╧═══════════════════╝ - +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ ``` Filling missing data: @@ -1515,13 +1455,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillna({ values: ["Apples"] }) df_filled.print() ``` @@ -1545,16 +1485,14 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} +let data = {"Name":["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) +let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) df_filled.print() ``` @@ -1616,7 +1554,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) +let df = new dfd.DataFrame(data) df.print() df.mean().print() //defaults to column axis ``` @@ -1670,11 +1608,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ A │ 4 ║ +║ 0 │ 4 ║ ╟───┼──────────────────────╢ -║ B │ 38.5 ║ +║ 1 │ 38.5 ║ ╟───┼──────────────────────╢ -║ C │ 31.75 ║ +║ 2 │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1728,7 +1666,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, { axis: 1 }) +let df_new = df.sub(sf, axis = 1) df_new.print() ``` @@ -1749,7 +1687,7 @@ df_new.print() #### Apply -Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: +Applying JavaScript functions to the data: ```javascript const dfd = require("danfojs") @@ -1758,11 +1696,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); +function sum_vals(x) { + return x + 20 } -let df_new = df.apply(sum_vals, { axis: 1 }) +let df_new = df.apply({callable: sum_vals }) df_new.print() ``` @@ -1783,18 +1721,22 @@ df_new.print() //after applying -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 22 │ 23 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 24 │ 25 │ 26 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 40 │ 50 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 59 │ 109 │ 98 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Applying Element wise operations to the data: +Applying Tensorflow functions to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. ```javascript const dfd = require("danfojs-node") @@ -1803,11 +1745,13 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 10 +df.print() + +function log_sig(x) { + return x.logSigmoid() } -let df_new = df.apply_map(sum_vals) +let df_new = df.apply({axis: 0, callable: log_sig }) df_new.print() ``` @@ -1826,19 +1770,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after apply_map + //after applying -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 12 │ 13 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 14 │ 15 │ 16 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 │ 50 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 49 │ 99 │ 88 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2325,36 +2269,29 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. ```javascript const dfd = require("danfojs-node") + let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] -} + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] + } let df = new dfd.DataFrame(data) -const csv = df.to_csv() -console.log(csv); -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH - - -df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs - - -df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version +df.to_csv().then((csv) => { + console.log(csv); +}).catch((err) => { + console.log(err); +}) ``` ```text @@ -2435,24 +2372,18 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.to_json() -console.log(json); -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] +df.to_json().then((json) => { + console.log(json); +}).catch((err) => { -const json = df.to_json({format: "row"}) -console.log(json); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} + console.log(err); +}) +``` +```text +[{"Abs":20.2,"Count":34,"country code":"NG"}, +{"Abs":30,"Count":4,"country code":"FR"}, +{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From 5c9aaa86a2a92033a289cc9e1d1743812b134e5a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 12:41:22 +0000 Subject: [PATCH 017/202] GitBook: [master] 2 pages modified --- api-reference/input-output/danfo.read_excel.md | 18 ++++++++---------- api-reference/input-output/danfo.read_json.md | 4 +++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..a8165d2 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,14 +26,11 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

+> Default will be the first sheet. +>
method: The HTTP method to use.

+>

headers: Additional headers to send with the request if reading +> JSON from remote url. Supports all the node-fetch options in Nodejs, and +> all fetch options in browsers.

>

}

> > @@ -46,14 +43,15 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read\_excel** method can read excel files saved on a local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 5b54e20..2e978c3 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -35,11 +35,13 @@ description: Reads a JSON file into DataFrame. Object

Configuration options for reading JSON files. Supported options:

-

method: The HTTP method to use.

+

{ +
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

+

}

{
method: "GET" From 97213423825129342e7f6282b33136a341427426 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 13:03:06 +0000 Subject: [PATCH 018/202] GitBook: [master] 4 pages modified --- SUMMARY.md | 1 + .../input-output/danfo.read_excel.md | 18 ++- api-reference/input-output/danfo.read_json.md | 137 +----------------- api-reference/series/series.and.md | 132 +++++++++++++++++ 4 files changed, 149 insertions(+), 139 deletions(-) create mode 100644 api-reference/series/series.and.md diff --git a/SUMMARY.md b/SUMMARY.md index 9adf7af..7ec608e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -111,6 +111,7 @@ * [Series.sample](api-reference/series/series.sample.md) * [Series.tail](api-reference/series/series.tail.md) * [Series.head](api-reference/series/series.head.md) + * [Series.and](api-reference/series/series.and.md) * [Dataframe](api-reference/dataframe/README.md) * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index a8165d2..d8e3d9e 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,11 +26,14 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet. ->
method: The HTTP method to use.

->

headers: Additional headers to send with the request if reading -> JSON from remote url. Supports all the node-fetch options in Nodejs, and -> all fetch options in browsers.

+> Default will be the first sheet.

+>

header_index : int, (Optional) Only used in browser environment. +> The Index of the row which represents the header(columns) of the data. +> Default will be the first non empty row.

+>

data_index : int, (Optional) Only used in browser environment. The +> index of the row from which actual data(content) starts. Default will be +> the next row of header_index +>

>

}

> > @@ -43,15 +46,14 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved on a local disk, or over the internet. +The **read\_excel** method can read excel files saved from local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -const path = require("path") -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") +local_xcel = 'testexcel.xls' async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 2e978c3..49528d0 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,85 +6,24 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - Input file object, string file path or URL -

Any valid string path is acceptable. The string could be a URL. Valid - URL schemes include http, https, ftp, s3, gs, or a local path. Both relative - and absolute paths are supported

-

-

An input file object is also supported in the browser.

-
optionsObject -

Configuration options for reading JSON files. Supported options:

-

{ -
method: The HTTP method to use.

-

headers: Additional headers to send with the request if reading - JSON from remote url. Supports all the node-fetch options in - Nodejs, and all fetch options in - browsers.

-

}

-
{ -
method: "GET" -
}
+| **Parameters** | Type | Description | +| :--- | :--- | :--- | +| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | **Returns:** ****_**Promise**_. Resolves to DataFrame -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. +### Example -### **Reading JSON files from local disk** +The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") +dfd.read_json("user_names.json") .then(df => { df.head().print() @@ -97,70 +36,6 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple {% tab title="Browser" %} ```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - ``` {% endtab %} diff --git a/api-reference/series/series.and.md b/api-reference/series/series.and.md new file mode 100644 index 0000000..85c22cb --- /dev/null +++ b/api-reference/series/series.and.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical AND between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.and + +> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical AND between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.and(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + From d33fe63ebd0ac5e4ae85a0a818a0135dcd86bd99 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 13:39:23 +0000 Subject: [PATCH 019/202] GitBook: [master] 2 pages modified --- SUMMARY.md | 1 + api-reference/series/series.or.md | 132 ++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 api-reference/series/series.or.md diff --git a/SUMMARY.md b/SUMMARY.md index 7ec608e..6c1e2b7 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -112,6 +112,7 @@ * [Series.tail](api-reference/series/series.tail.md) * [Series.head](api-reference/series/series.head.md) * [Series.and](api-reference/series/series.and.md) + * [Series.or](api-reference/series/series.or.md) * [Dataframe](api-reference/dataframe/README.md) * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) diff --git a/api-reference/series/series.or.md b/api-reference/series/series.or.md new file mode 100644 index 0000000..948c61d --- /dev/null +++ b/api-reference/series/series.or.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical OR between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.or + +> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical OR between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.or(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + From 3f8fbed71543200531aaff6016491b1f9b9921e7 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 13:47:46 +0000 Subject: [PATCH 020/202] GitBook: [master] one page modified --- api-reference/series/series.append.md | 172 ++++++++++++++++++-------- 1 file changed, 117 insertions(+), 55 deletions(-) diff --git a/api-reference/series/series.append.md b/api-reference/series/series.append.md index 473b01a..c2e69a8 100644 --- a/api-reference/series/series.append.md +++ b/api-reference/series/series.append.md @@ -1,73 +1,136 @@ -# Series.append +--- +description: Add a new value or values to the end of a Series. +--- -danfo.Series.**append**\(val, inplace\) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)\] +# Series.append -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| val | Array \| Series | Object to append | | -| inplace | Boolean | Whether to perform operation inplace or not | false | +danfo.Series.**append**\(newValue, index, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)\] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
newValueArray, SeriesObject to append
indexArrayThe new index value(s) to append to the Series. Must contain the same + number of values as newValues as they map 1 - 1.
optionsObject +

{ +
inplace: Whether to perform operation in-place or not.

+

}

+
false
**Returns:** ****return **Series** -## **Examples** +\*\*\*\* -### **Append Series to Series** +### **Append new Series to the end of a Series** {% tabs %} {% tab title="Node" %} ```javascript -let sf1 = new dfd.Series([1, 2, 3, 4]) -let sf2 = new dfd.Series(["a", "b", "c"], {index: ['f1', 'f2', 'f3']}) +const dfd = require("danfojs-node") -new_sf = sf1.append(sf2) +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) + +new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) new_sf.print() ``` {% endtab %} +{% endtabs %} -{% tab title="Browser" %} -``` - +{% tabs %} +{% tab title="Output" %} +```text +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ ``` {% endtab %} {% endtabs %} +### **Append new Series to the end of a Series in-place** + {% tabs %} -{% tab title="Output" %} -```text -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 0 │ 1 ║ -╟────┼──────────────────────╢ -║ 1 │ 2 ║ -╟────┼──────────────────────╢ -║ 2 │ 3 ║ -╟────┼──────────────────────╢ -║ 3 │ 4 ║ -╟────┼──────────────────────╢ -║ f1 │ a ║ -╟────┼──────────────────────╢ -║ f2 │ b ║ -╟────┼──────────────────────╢ -║ f3 │ c ║ -╚════╧══════════════════════╝ +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) +let newIndex = ["f5", "f6", "f7"] + +sf1.append(sf2, newIndex, { inplace: true }) +sf1.print() ``` {% endtab %} {% endtabs %} -\*\*\*\* +```text +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ +``` -### **Append Array to Series** +### **Append an array to the end of Series** {% tabs %} {% tab title="Node" %} ```javascript -let sf1 = new dfd.Series([1, 2, 3, 4]) -let arr = ['f1', 'f2', 'f3'] +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sfArr = ["a", "b", "c"] -new_sf = sf1.append(arr) +new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) new_sf.print() ``` @@ -83,23 +146,22 @@ new_sf.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 0 │ f1 ║ -╟───┼──────────────────────╢ -║ 1 │ f2 ║ -╟───┼──────────────────────╢ -║ 2 │ f3 ║ -╚═══╧══════════════════════╝ +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ + ``` {% endtab %} {% endtabs %} From ed839475f1670c375226d26996ddccb5e0f31153 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 13:55:38 +0000 Subject: [PATCH 021/202] GitBook: [master] 4 pages modified --- api-reference/series/series.cummax.md | 21 +++++++++++++++++---- api-reference/series/series.cummin.md | 21 +++++++++++++++++---- api-reference/series/series.cumprod.md | 21 +++++++++++++++++---- api-reference/series/series.cumsum.md | 23 ++++++++++++++++++----- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 201ae11..afad306 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -4,11 +4,24 @@ description: Returns cumulative maximum over a series # Series.cummax -> danfo.Series.**cummax**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L825)\] +> danfo.Series.**cummax**\(options\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)\] -**Parameters:** None - -**Return**: Series + + + + + + + + + + +
optionsObject +

inplace: Whether to perform operation in-place or not.

+

+
{ +
inplace: false +
}
**Example** diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index f2337a8..bffe0de 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -4,11 +4,24 @@ description: Returns the cumulative min of a Series # Series.cummin -> danfo.Series.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L816)\] +> danfo.Series.**cummin**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)\] -**Parameters:** None - -**Return**: Series + + + + + + + + + + +
optionsObject +

inplace: Whether to perform operation in-place or not.

+

+
{ +
inplace: false +
}
**Example** diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 6b72547..96461e4 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -4,11 +4,24 @@ description: Return the cumulative product of a series # Series.cumprod -> danfo.Series.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L834)\] +> danfo.Series.**cumprod**\(\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)\] -**Parameters:** None - -**Return**: Series + + + + + + + + + + +
optionsObject +

inplace: Whether to perform operation in-place or not.

+

+
{ +
inplace: false +
}
**Example** diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index 205d777..fd475be 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -4,11 +4,24 @@ description: Return a cumulative sum of a series # Series.cumsum -> danfo.Series.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L807)\] - -**Parameters:** None - -**Return**: Series +> danfo.Series.**cumsum**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)\] + + + + + + + + + + + +
optionsObject +

inplace: Whether to perform operation in-place or not.

+

+
{ +
inplace: false +
}
**Example** From bd93f00d4e447e158765488d6a8403b91241cba1 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 14:26:47 +0000 Subject: [PATCH 022/202] GitBook: [master] 211 pages modified --- api-reference/series/series.argsort.md | 50 +++++++- api-reference/series/series.cummax.md | 27 +++-- api-reference/series/series.cummin.md | 27 +++-- api-reference/series/series.cumprod.md | 39 ++++--- api-reference/series/series.cumsum.md | 27 +++-- api-reference/series/series.dt.day.md | 44 +++---- api-reference/series/series.dt.hour.md | 18 ++- api-reference/series/series.dt.month.md | 28 +++-- api-reference/series/series.dt.month_name.md | 19 ++- api-reference/series/series.dt.monthday.md | 19 ++- api-reference/series/series.dt.second.md | 21 ++-- api-reference/series/series.dt.weekdays.md | 85 +++++++------- api-reference/series/series.dt.year.md | 19 ++- api-reference/series/series.fillna.md | 40 +++++-- api-reference/series/series.replace.md | 110 +++++++++++------- api-reference/series/series.str.capitalize.md | 26 ++++- api-reference/series/series.str.charat.md | 32 ++++- api-reference/series/series.str.concat.md | 46 +++++++- api-reference/series/series.str.endswith.md | 34 +++++- api-reference/series/series.str.includes.md | 34 +++++- api-reference/series/series.str.indexof.md | 34 +++++- api-reference/series/series.str.join.md | 61 +++++++--- .../series/series.str.lastindexof.md | 34 +++++- api-reference/series/series.str.len.md | 58 +++++---- api-reference/series/series.str.repeat.md | 34 +++++- api-reference/series/series.str.replace.md | 41 ++++++- api-reference/series/series.str.search.md | 40 +++++-- api-reference/series/series.str.slice.md | 41 ++++++- api-reference/series/series.str.split.md | 3 +- api-reference/series/series.str.startswith.md | 34 +++++- api-reference/series/series.str.substr.md | 42 ++++++- api-reference/series/series.str.substring.md | 41 ++++++- .../series/series.str.tolowercase.md | 28 ++++- .../series/series.str.touppercase.md | 26 ++++- api-reference/series/series.str.trim.md | 26 ++++- 35 files changed, 935 insertions(+), 353 deletions(-) diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 29c19e3..8926e7f 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -4,11 +4,30 @@ description: Return the integer indices that would sort the Series values # Series.argsort -> danfo.Series.**argsort**\(ascending\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] +> danfo.Series.**argsort**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| ascending | boolean | How to sort the indices. either **True** or **False** | true | + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectascending: How to sort the indices +

{ +
ascending: true

+

}

+
**Returns:** Series \(int element\) @@ -22,7 +41,9 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() +sf.argsort().print() //defaults to ascending order +sf.argsort({ ascending: false }).print() + ``` {% endtab %} {% endtabs %} @@ -49,6 +70,25 @@ sf.argsort().print() ╟───┼──────────────────────╢ ║ 7 │ 1 ║ ╚═══╧══════════════════════╝ + +//sorted in descending order +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 6 ║ +╟───┼───╢ +║ 2 │ 4 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index afad306..78422ea 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -9,18 +9,25 @@ description: Returns cumulative maximum over a series - - - - + + + + - + + + + + + + +
optionsObject -

inplace: Whether to perform operation in-place or not.

-

-
{ -
inplace: false -
}
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index bffe0de..d368c0c 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -9,18 +9,25 @@ description: Returns the cumulative min of a Series - - - - + + + + - + + + + + + + +
optionsObject -

inplace: Whether to perform operation in-place or not.

-

-
{ -
inplace: false -
}
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 96461e4..41c2898 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -6,22 +6,29 @@ description: Return the cumulative product of a series > danfo.Series.**cumprod**\(\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)\] - - - - - - - - - - -
optionsObject -

inplace: Whether to perform operation in-place or not.

-

-
{ -
inplace: false -
}
+> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +>
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. style="text-align:left"> +>

{

+>

inplace: false

+>

}

+>
**Example** diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index fd475be..db8021c 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -9,18 +9,25 @@ description: Return a cumulative sum of a series - - - - + + + + - + + + + + + + +
optionsObject -

inplace: Whether to perform operation in-place or not.

-

-
{ -
inplace: false -
}
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 09334c1..3e4fd5c 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -17,7 +17,7 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) let sf = new dfd.Series(data) sf.dt.day().print() @@ -32,26 +32,26 @@ sf.dt.day().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 0 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ ``` diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 1243049..8b9287f 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -22,7 +22,7 @@ let sf = new dfd.Series(data) // print series sf.print() // print hour series -sf.dt.hour().print() +sf.dt.hours().print() ``` {% endtab %} @@ -37,21 +37,17 @@ sf.dt.hour().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 2:00:00 AM ║ ╚═══╧══════════════════════╝ -//print hour series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╚═══╧═══╝ + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index 0e6dedb..a1b449f 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -32,20 +32,18 @@ sf.dt.month().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 7 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╟───┼──────────────────────╢ -║ 4 │ 11 ║ -╟───┼──────────────────────╢ -║ 5 │ 11 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 6 ║ +╟───┼────╢ +║ 1 │ 7 ║ +╟───┼────╢ +║ 2 │ 9 ║ +╟───┼────╢ +║ 3 │ 9 ║ +╟───┼────╢ +║ 4 │ 11 ║ +╟───┼────╢ +║ 5 │ 11 ║ +╚═══╧════╝ ``` diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index 82a7d3c..b137205 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -37,8 +37,6 @@ sf.dt.month_name().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2018, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 2/1/2018, 1:00:00 AM ║ @@ -46,16 +44,13 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print month name series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ Jan ║ +╟───┼─────╢ +║ 1 │ Feb ║ +╟───┼─────╢ +║ 2 │ Mar ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index 1c7e556..e52c916 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -37,8 +37,6 @@ sf.dt.monthday().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/2/2000, 1:00:00 AM ║ @@ -46,16 +44,13 @@ sf.dt.monthday().print() ║ 2 │ 1/3/2000, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print monthdays -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index e6fd771..5925e40 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -25,7 +25,7 @@ let sf = new dfd.Series(data) sf.print() //print the seconds obtained -sf.seconds().print() +sf.dt.seconds().print() ``` {% endtab %} @@ -41,8 +41,6 @@ sf.seconds().print() ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 1:00:01 AM ║ @@ -50,16 +48,13 @@ sf.seconds().print() ║ 2 │ 1/1/2000, 1:00:02 AM ║ ╚═══╧══════════════════════╝ -//the seconds obtained -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╚═══╧═══╝ ``` {% endtab %} diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index dc79e6c..64945fa 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -34,49 +34,48 @@ sf.dt.weekdays().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12/31/2016, 1:00:... ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ -//print days of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Sat ║ -╟───┼──────────────────────╢ -║ 1 │ Sun ║ -╟───┼──────────────────────╢ -║ 2 │ Mon ║ -╟───┼──────────────────────╢ -║ 3 │ Tue ║ -╟───┼──────────────────────╢ -║ 4 │ Wed ║ -╟───┼──────────────────────╢ -║ 5 │ Thu ║ -╟───┼──────────────────────╢ -║ 6 │ Fri ║ -╟───┼──────────────────────╢ -║ 7 │ Sat ║ -╟───┼──────────────────────╢ -║ 8 │ Sun ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ Sat ║ +╟───┼──────╢ +║ 1 │ Sun ║ +╟───┼──────╢ +║ 2 │ Mon ║ +╟───┼──────╢ +║ 3 │ Tue ║ +╟───┼──────╢ +║ 4 │ Wed ║ +╟───┼──────╢ +║ 5 │ Thur ║ +╟───┼──────╢ +║ 6 │ Fri ║ +╟───┼──────╢ +║ 7 │ Sat ║ +╟───┼──────╢ +║ 8 │ Sun ║ +╟───┼──────╢ +║ 9 │ Mon ║ +╚═══╧══════╝ ``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index a594255..c6a4040 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -28,8 +28,6 @@ sf.dt.year().print() ```text //print date time series ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2001, 1:00:00 AM ║ @@ -37,15 +35,12 @@ sf.dt.year().print() ║ 2 │ 1/1/2002, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print the year series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2000 ║ -╟───┼──────────────────────╢ -║ 1 │ 2001 ║ -╟───┼──────────────────────╢ -║ 2 │ 2002 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ 2000 ║ +╟───┼──────╢ +║ 1 │ 2001 ║ +╟───┼──────╢ +║ 2 │ 2002 ║ +╚═══╧══════╝ ``` diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index b1bea1b..f14e5d3 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -4,18 +4,38 @@ description: Replace all NaN value with specified value # Series.fillna -> danfo.Series.**fillna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**value**"\] | int \| String\| bool | value to replace the NaN values | | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | - -**Returns:** Series +> danfo.Series.**fillna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObject +

value: The value to replace all missing value with.

+

inplace: Boolean indicating whether to perform the operation inplace + or not. Defaults to false

+
+

{

+

inplace: false

+

}

+
**Examples** -Fill nan value and then return new series +### Fill nan value and then return new series {% tabs %} {% tab title="Node" %} @@ -62,7 +82,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Fill nan value without returning new Series +### Fill nan value in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index 4b49fa2..cf1dd06 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,19 +4,41 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**replace**"\] | int \| String\| bool | value to be replaced | | -| kwargs\["**with**"\] | int \| String \| bool | value to replace the previous value | | -| kwargs\["**inplace**"\] | Bool | mutate the series or create the new series | false | +> danfo.Series.**replace**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObject +

oldValue: The value you want to replace

+

newValue: The new value you want to replace the old value with

+

inplace: Boolean indicating whether to perform the operation inplace + or not

+
+

{

+

inplace: false

+

}

+
**Returns**: Series **Examples** -Replace a value in a series and return a new series +### Replace a value in a series and return a new series {% tabs %} {% tab title="Node" %} @@ -25,7 +47,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ replace: 10, with: -50 }) +let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) sf_rep.print() ``` @@ -35,28 +57,27 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + ``` {% endtab %} {% endtabs %} -Replace a value in a series , with out returning a new series +### Replace a value in-place {% tabs %} {% tab title="Node" %} @@ -65,7 +86,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ replace: 10, with: -50, inplace:true }) +sf.replace({ oldValue: 10, newValue: -50, inplace: true}) sf.print() ``` @@ -73,22 +94,21 @@ sf.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + ``` diff --git a/api-reference/series/series.str.capitalize.md b/api-reference/series/series.str.capitalize.md index 5df261a..10483b3 100644 --- a/api-reference/series/series.str.capitalize.md +++ b/api-reference/series/series.str.capitalize.md @@ -4,9 +4,31 @@ description: Capitalize the first character of each string # Series.str.capitalize -> danfo.Series.str.**capitalize**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] +> danfo.Series.str.**capitalize**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.charat.md b/api-reference/series/series.str.charat.md index 3df2bbc..9cb1d66 100644 --- a/api-reference/series/series.str.charat.md +++ b/api-reference/series/series.str.charat.md @@ -6,9 +6,35 @@ description: Obtain the character at the specified index (position) > danfo.Series.str.**charAt**\(index\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| index | int | the index at which to obtain the character | 0 | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
indexintthe index at which to obtain the character0
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(Character element\) diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index 0a24597..b27bc00 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -4,12 +4,46 @@ description: Joins two or more strings/arrays # Series.str.concat -> danfo.Series.str.**concat**\(other, position\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other** \(string or array\) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +> danfo.Series.str.**concat**\(other, position, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherstring or Arraystring or list of strings to add to each string element of the series""
positionIntThe position to add the other (string or array) is either 0 or 1. + 0 is to add the other at the beginning of each of the string element, and + 1 is to add to the end of the string element1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series \(String element\) diff --git a/api-reference/series/series.str.endswith.md b/api-reference/series/series.str.endswith.md index 645294d..18753cb 100644 --- a/api-reference/series/series.str.endswith.md +++ b/api-reference/series/series.str.endswith.md @@ -4,11 +4,37 @@ description: Checks whether a string ends with specified characters # Series.str.endsWith -> danfo.Series.str.**endsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] +> danfo.Series.str.**endsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.str.includes.md b/api-reference/series/series.str.includes.md index c2cb4af..cfa9c16 100644 --- a/api-reference/series/series.str.includes.md +++ b/api-reference/series/series.str.includes.md @@ -4,11 +4,37 @@ description: Checks whether a string contains the specified string/characters # Series.str.includes -> danfo.Series.str.includes\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] +> danfo.Series.str.includes\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index a823d20..fe93a74 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -4,11 +4,37 @@ description: the position of the first found occurrence of a specified value in # Series.str.indexOf -> danfo.Series.str.indexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] +> danfo.Series.str.indexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to obtain its index | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe string to obtain its index""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index 4c17295..a32c1bb 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -4,12 +4,43 @@ description: Join a new string value to all string elements in a Series. # Series.str.join -> danfo.Series.str.**join**\(valToJoin,joinChar\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] +> danfo.Series.str.**join**\(valToJoin, joinChar, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
valToJoinStringthe string value you want to""
joinCharStringThe delimiter to specify the joining" "
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** @@ -38,17 +69,15 @@ sf.str.join("new", "_").print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part_new ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentenc... ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════════╗ +║ 0 │ lower part_new ║ +╟───┼────────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼────────────────────────╢ +║ 2 │ this is a sentence_new ║ +╟───┼────────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧════════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.lastindexof.md b/api-reference/series/series.str.lastindexof.md index 130c50c..d2bfa98 100644 --- a/api-reference/series/series.str.lastindexof.md +++ b/api-reference/series/series.str.lastindexof.md @@ -6,11 +6,37 @@ description: >- # Series.str.lastIndexOf -danfo.Series.str.lastIndexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] +danfo.Series.str.lastIndexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to search for | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series diff --git a/api-reference/series/series.str.len.md b/api-reference/series/series.str.len.md index 60153e8..be82b70 100644 --- a/api-reference/series/series.str.len.md +++ b/api-reference/series/series.str.len.md @@ -4,13 +4,31 @@ description: Obtain the length of each string element in a Series # Series.str.len -> danfo.Series.str.**len**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] +> danfo.Series.str.**len**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] -**Parameters**: None - -**Returns:** - - return Series + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Examples** @@ -21,7 +39,7 @@ Returns the length \(number of character\) of a string, and also return the leng ```javascript const dfd = require("danfojs-node") -let data = ["dog", 5,"cat",["fog","mug"],"animals"] +let data = ["dog", 5,"cat","fog","mug","animals"] let sf = new dfd.Series(data) sf.str.len().print() ``` @@ -37,19 +55,19 @@ sf.str.len().print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ NaN ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index e6c1f32..2f1d49b 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -4,11 +4,37 @@ description: Repeat the the character(s) in a string for a specified number of t # Series.str.repeat -> danfo.Series.str.**repeat**\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] +> danfo.Series.str.**repeat**\(num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | integer | the string to search for | 1 | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
numintegerthe string to search for1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index c96137c..0950071 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,12 +4,43 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace\(searchValue, replaceValue\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] +> danfo.Series.str.replace\(searchValue, replaceValue, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| searchValue | string | the string to search for | "" | -| replaceValue | String | string to replace the searched string | "" | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
searchValuestringString | Character value to replace. Supports regex.""
replaceValueStringstring to replace the searched string""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 8824095..4367ae8 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -4,13 +4,39 @@ description: Obtain the index position of a searched character in a String # Series.str.search -> danfo.Series.str.**search**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] - - - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | String | the string to search for | "" | +> danfo.Series.str.**search**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strStringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index d314066..e843eb8 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -4,12 +4,43 @@ description: Obtain the substring of each element in a series # Series.str.slice -> danfo.Series.str.slice\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] +> danfo.Series.str.slice\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 65a82c7..4b88313 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,11 +6,12 @@ description: >- # Series.str.split -> danfo.Series.str.**split**\(splitVal\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L250)\] +> danfo.Series.str.**split**\(splitVal, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | | splitVal | String | separator or delimiter used to split the string | " " | +| options | Object | **inplace**: Whether to perform operation in-place or not. | { inplace: false } | **Returns** diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index 311bb2f..c141afd 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -4,11 +4,37 @@ description: Test whether a string begins with specified characters # Series.str.startsWith -> danfo.Series.str.**startsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] +> danfo.Series.str.**startsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index 1512f02..8869806 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -6,12 +6,44 @@ description: >- # Series.str.substr -> danfo.Series.str.substr\(startIndex, num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] +> danfo.Series.str.substr\(startIndex, num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
numNumberThe number of character to obtain starting from the startIndex1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 73ab3a8..7515af0 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -4,12 +4,43 @@ description: Obtain the substring of each element in a series # Series.str.substring -> danfo.Series.str.**substring**\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] +> danfo.Series.str.**substring**\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns** diff --git a/api-reference/series/series.str.tolowercase.md b/api-reference/series/series.str.tolowercase.md index ada457b..9dfb12f 100644 --- a/api-reference/series/series.str.tolowercase.md +++ b/api-reference/series/series.str.tolowercase.md @@ -4,11 +4,31 @@ description: Converts all characters to lower case. # Series.str.toLowerCase -> danfo.Series.str.toLowerCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] +> danfo.Series.str.toLowerCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] -**Parameters:** None - -**Returns**: Series \(String element\) + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.str.touppercase.md b/api-reference/series/series.str.touppercase.md index 7e23c08..4f630ae 100644 --- a/api-reference/series/series.str.touppercase.md +++ b/api-reference/series/series.str.touppercase.md @@ -4,9 +4,31 @@ description: Converts all characters to uppercase. # Series.str.toUpperCase -> danfo.Series.str.toUpperCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] +> danfo.Series.str.toUpperCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index 7e30db5..181c004 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -4,9 +4,31 @@ description: Remove leading and trailing Whitespace from a String element # Series.str.trim -> danfo.Series.str.**trim**\(\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** +> danfo.Series.str.**trim**\(options\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** From 8178b54e81132a01de8f205031027e084d28d65f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 14:59:04 +0000 Subject: [PATCH 023/202] GitBook: [master] 211 pages modified --- README.md | 12 +- SUMMARY.md | 3 +- api-reference/README.md | 2 +- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 +- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 +++--- api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 194 ++---- .../input-output/danfo.read_excel.md | 18 +- api-reference/input-output/danfo.read_json.md | 137 ++++- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- api-reference/series/README.md | 4 +- api-reference/series/series.abs.md | 26 +- .../series/series.drop_duplicates.md | 39 +- api-reference/series/series.dropna.md | 34 +- api-reference/series/series.eq.md | 2 +- api-reference/series/series.ge.md | 2 +- api-reference/series/series.gt.md | 2 +- api-reference/series/series.iloc.md | 30 +- api-reference/series/series.le.md | 2 +- api-reference/series/series.loc.md | 198 +++++++ api-reference/series/series.lt.md | 2 +- api-reference/series/series.ne.md | 2 +- api-reference/series/series.nunique.md | 2 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +- getting-started.md | 555 ++++++++++-------- 31 files changed, 980 insertions(+), 619 deletions(-) create mode 100644 api-reference/series/series.loc.md diff --git a/README.md b/README.md index 92e7da5..b170fbb 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects +* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. -* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. +* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. {% page-ref page="getting-started.md" %} diff --git a/SUMMARY.md b/SUMMARY.md index 6c1e2b7..0fe654f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -66,9 +66,7 @@ * [Series.value\_counts](api-reference/series/series.value_counts.md) * [Series.nunique](api-reference/series/series.nunique.md) * [Series.unique](api-reference/series/series.unique.md) - * [Series.corr](api-reference/series/series.corr.md) * [Series.abs](api-reference/series/series.abs.md) - * [Series.dot](api-reference/series/series.dot.md) * [Series.ne](api-reference/series/series.ne.md) * [Series.eq](api-reference/series/series.eq.md) * [Series.ge](api-reference/series/series.ge.md) @@ -76,6 +74,7 @@ * [Series.gt](api-reference/series/series.gt.md) * [Series.lt](api-reference/series/series.lt.md) * [Series.iloc](api-reference/series/series.iloc.md) + * [Series.loc](api-reference/series/series.loc.md) * [Series.size](api-reference/series/series.size.md) * [Series.ndim](api-reference/series/series.ndim.md) * [Series.shape](api-reference/series/series.shape.md) diff --git a/api-reference/README.md b/api-reference/README.md index 70dff34..492db09 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3e20f6a..f74da8c 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,7 +21,9 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

value: Series, Array. New values to add }

+

values: Series, Array of new values to add +
inplace: Default to false.

+

}

@@ -30,13 +32,11 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** - ****return **Null** - ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,12 +53,11 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -112,12 +111,11 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -126,7 +124,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3e1318e..8445c35 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,7 +37,9 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** - ****return **DataFrame** +```text + ****return **DataFrame** +``` ## **Examples** @@ -46,7 +48,6 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -59,12 +60,11 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -73,7 +73,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,12 +117,11 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -132,7 +130,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,5 +156,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index b74b5da..692b225 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 1cb3b8f..54fc0ae 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,18 +17,24 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - kwargs + data + Series or Dataframe + The data to dummify + + + + options Object

{

-

data: Array | Series | DataFrame

-

prefix_sep: String separator for created columns e.g "_",

+

columns: Array of column names to dummify. If not specified, all + categorical columns are encoded.

+

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

-

columns: [Array] columns to be encoded in DataFrame.

}

- {prefix_sep: "_"} + {prefixSeparator: "_"} @@ -49,7 +55,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) dum_df.print() ``` {% endtab %} @@ -65,19 +71,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -96,7 +102,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df }) +let dum_df = dfd.get_dummies(df) dum_df.print() ``` {% endtab %} @@ -159,7 +165,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 752a196..5251d48 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 5e66567..43b2476 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 2e7c0a3..4077198 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Convert Object to datetime format +description: Converts an array of Date time string to Date object. --- # danfo.to\_datetime -danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,15 +17,12 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - - + @@ -38,14 +35,16 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan ## **Examples** -### **Convert Series to Dummy codes** +Converts a **Series** of Date strings to Date time and get time properties {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -let dt = dfd.to_datetime({data:sf}) +sf.print() + +let dt = dfd.toDateTime({data:sf}) dt.month().print() dt.month_name().print() @@ -65,85 +64,99 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + //Int representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╚═══╧══════════════════════╝ + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 //string representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╟───┼──────────────────────╢ -║ 3 │ Apr ║ -╟───┼──────────────────────╢ -║ 4 │ May ║ -╚═══╧══════════════════════╝ +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec //string representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Mon ║ -╟───┼──────────────────────╢ -║ 1 │ Thu ║ -╟───┼──────────────────────╢ -║ 2 │ Thu ║ -╟───┼──────────────────────╢ -║ 3 │ Sun ║ -╟───┼──────────────────────╢ -║ 4 │ Tue ║ -╚═══╧══════════════════════╝ - -//Int representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 2 ║ -╚═══╧══════════════════════╝ +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + //Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 0 ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f071ac9..f015c6e 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,7 +1,5 @@ --- -description: >- - Functions and methods to easily read tabular/structured data into DataFrame - and Series Objects +description: Functions for reading tabular/structured data into DataFrame/Series Objects --- # Input/Output @@ -11,8 +9,11 @@ description: >- | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | +| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d1ab8f8..570c7c3 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,11 +20,15 @@ description: >- - - - + + + @@ -32,15 +36,16 @@ description: >- + -
kwargs + data ObjectArray, Series -

{

-

data: Array | Series, the object to convert.

-

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", - and "%m-d-Y H%M%S%"

-

}

+

data: Array | Series with Date strings to convert to Date time.

+

<b></b>

source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid - URL schemes include https, http, ftp, s3, gs, and file. Local file paths - are only accepted in Nodejs environment.source + File object, File path, URL +

Any valid string path is acceptable. The string could be a URL or a valid + local file path.

+

A browser input file object is + also supported.

+
object, optional

-

A CSV Config object that contains configurations for reading and decoding - from CSV file(s). Supported params are:

-

start: The index position to start from when reading the CSV file.

-

end: The end position to stop at when reading the CSV file.

-

... csvConfigs: other supported Tensorflow csvConfig parameters. - See https://js.tensorflow.org/api/latest/#data.csv +

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

+

<b></b>

+
+

{

+

dynamicTyping: true,

+

header: true

+

}

@@ -49,16 +54,18 @@ description: >- ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. -The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("user_names.csv") //assumes file is in CWD +dfd.read_csv("./user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -68,45 +75,9 @@ dfd.read_csv("user_names.csv") //assumes file is in CWD }) ``` {% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - - -``` -{% endtab %} {% endtabs %} -**Loading Files from URL** +### **Reading files from a URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -134,8 +105,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -163,29 +134,11 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -**Reading Large Files** - -For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: +### **Reading an input file object in the browser** -**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series {% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_process_data() { - let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) - let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) - - df_chunk1.head().print() - df_chunk2.head().print() -} - -load_process_data() -``` -{% endtab %} - {% tab title="Browser" %} ```markup @@ -194,100 +147,27 @@ load_process_data() - + Document - -
+ - - ``` {% endtab %} {% endtabs %} -```bash -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..a8165d2 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,14 +26,11 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

+> Default will be the first sheet. +>
method: The HTTP method to use.

+>

headers: Additional headers to send with the request if reading +> JSON from remote url. Supports all the node-fetch options in Nodejs, and +> all fetch options in browsers.

>

}

> > @@ -46,14 +43,15 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read\_excel** method can read excel files saved on a local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 49528d0..2e978c3 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,24 +6,85 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] -| **Parameters** | Type | Description | -| :--- | :--- | :--- | -| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
source + Input file object, string file path or URL +

Any valid string path is acceptable. The string could be a URL. Valid + URL schemes include http, https, ftp, s3, gs, or a local path. Both relative + and absolute paths are supported

+

+

An input file object is also supported in the browser.

+
optionsObject +

Configuration options for reading JSON files. Supported options:

+

{ +
method: The HTTP method to use.

+

headers: Additional headers to send with the request if reading + JSON from remote url. Supports all the node-fetch options in + Nodejs, and all fetch options in + browsers.

+

}

+
{ +
method: "GET" +
}
**Returns:** ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. -The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: +### **Reading JSON files from local disk** {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("user_names.json") +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") .then(df => { df.head().print() @@ -36,6 +97,70 @@ dfd.read_json("user_names.json") {% tab title="Browser" %} ```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + ``` {% endtab %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index e412af9..9fd06ff 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 397b480..b9d73a8 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,12 +44,11 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + - ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/api-reference/series/README.md b/api-reference/series/README.md index cc25049..55d25f4 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -49,7 +49,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise \(binary operator ge\). | | [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise \(binary operator ne\). | | [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise \(binary operator eq\). | -| [`Series.dot`](series.dot.md) | Compute the dot product between the Series and the columns of other. | +| [`Series.dot`]() | Compute the dot product between the Series and the columns of other. | ### Function application & GroupBy @@ -61,7 +61,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | | :--- | :--- | -| [`Series.corr`](series.corr.md) | Compute correlation with other Series, excluding missing values. | +| [`Series.corr`]() | Compute correlation with other Series, excluding missing values. | | [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | | [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | | [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index db9a8b4..c241eae 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,9 +4,31 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] +> danfo.Series.**abs**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] -**Parameters**: None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation in-place + or not. Defaults to false +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index d5fd7e2..eae885c 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -4,18 +4,39 @@ description: Remove duplicate rows # Series.drop\_duplicates -> danfo.Series.**drop\_duplicates**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | -| kwargs\["**keep**"\] | String | {"**first**"or "**last**"}. Specify if to keep the last or the first duplicate value | first | +> danfo.Series.**drop\_duplicates**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectkeep: "first" | "last", which duplicate value + to keep. Defaults to "first". +
inplace: Boolean indicating whether to perform the operation in-place + or not. Defaults to false
+

{

+

inplace: false

+

}

+
**Returns:** Series **Examples** -Drop duplicate by keeping the first value of the duplicate value +### Drop duplicate by keeping the first occurrence of the duplicate value {% tabs %} {% tab title="Node" %} @@ -51,7 +72,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Drop duplicate and keep only the last duplicated value +### Drop duplicate and keep only the last duplicated value {% tabs %} {% tab title="Node" %} @@ -87,7 +108,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Remove duplicate value in series without returning a new series +### Remove duplicate value in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 6fa1100..8e3a4be 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -4,17 +4,37 @@ description: Remove missing values from Series # Series.dropna -> danfo.Series.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | +> danfo.Series.**dropna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{ +
inplace: false

+

}

+
**Returns**: Series **Examples** -Drop all nan value and then return New Series. +### Drop all nan value and then return New Series. {% tabs %} {% tab title="Node" %} @@ -52,7 +72,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Drop nan values without returning new series +### Drop nan values in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 341dbb9..9e8a9c3 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -8,7 +8,7 @@ description: Check all the values in a series is equal to another value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| other | Series, Array or number | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index b3d8b69..a7c0ead 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is greater than or equal a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index a98f618..98eb444 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -8,7 +8,7 @@ description: Check if all the value in a series is greater than a value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index e580803..195677a 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -4,7 +4,7 @@ danfo.Series.**iloc**\(\) \[[source](https://github.com/opensource9ja/danfojs/bl | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| rows | Array | Array, slice or index of row position to return | | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | **Returns:** @@ -18,9 +18,10 @@ Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. +* A boolean mask. E.g \[ true, false, false \] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only ****the start label is included._ +_**Note:** only ****the start label is included, and the end label is ignored._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -30,7 +31,6 @@ _**Note:** only ****the start label is included._ {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -// const tf = require("@tensorflow/tfjs-node") let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) @@ -62,7 +62,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[0: 5\]". This will return all values from index positions 0 to 4. {% tabs %} {% tab title="Node" %} @@ -136,5 +136,27 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} +### Slice Series by boolean condition +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index e9056d7..0dde01a 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is less than or equal to a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns:** Series \(Boolean Element\) diff --git a/api-reference/series/series.loc.md b/api-reference/series/series.loc.md new file mode 100644 index 0000000..3b17e89 --- /dev/null +++ b/api-reference/series/series.loc.md @@ -0,0 +1,198 @@ +# Series.loc + +danfo.Series.**loc**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | + +**Returns:** + + ****return **Series** + +## **Examples** + +`.loc()` is label position based \(from `0` to `length-1` of the row axis\). + +Allowed inputs are: + +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false \] +* A string slice object with ints, e.g. `[`'`"a":"d"']` + +_**Note:** only ****the start label is included, and the end label is ignored._ + +`.loc` will raise a `ValueEror` if a requested label is not found. + +### **Indexing by specific row index** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc(["a", "g"]).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╟───┼─────╢ +║ e │ 30 ║ +╟───┼─────╢ +║ f │ 30 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╟───┼─────╢ +║ h │ 7 ║ +╚═══╧═════╝ + +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end\], e.g **\[\`"a":"e"\`\]**. This will return all values from label positions `a` to `e`. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc([`"a":"e"`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error: +`s.loc([a:e]).print()` +For the slice above to work, you must quote each slice, e.g: +`s.loc(["a":"e"]).print()` + +_**Quotes are not needed for numeric indices!**_ +{% endhint %} + +### By specifying a start index in a slice, all values after that index are returned. + +{% tabs %} +{% tab title="Node" %} +```javascript +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +let s = new dfd.Series(data) + +s.loc([`1:`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═════╗ +║ 1 │ 34 ║ +╟───┼─────╢ +║ 2 │ 2.2 ║ +╟───┼─────╢ +║ 3 │ 2 ║ +╟───┼─────╢ +║ 4 │ 30 ║ +╟───┼─────╢ +║ 5 │ 30 ║ +╟───┼─────╢ +║ 6 │ 2.1 ║ +╟───┼─────╢ +║ 7 │ 7 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} + +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.loc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` + diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index bb18486..73c45d1 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -8,7 +8,7 @@ description: Check if all values in a Series are less than a value. | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index 9901dcd..fcf182a 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -8,7 +8,7 @@ description: Check if all values in a series is not equal to a value(s) | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| other | Series, Array or number | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 8ddafe4..42f678d 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -1,5 +1,5 @@ --- -description: Obtain the number of unique values in a series +description: Returns the number of unique values in a series --- # Series.nunique diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 66dd124..48b3b1c 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,9 +9,7 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) - - -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -19,9 +17,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -### Setting up your environment +## Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -31,9 +29,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -46,7 +44,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -### Loading and processing your data +## Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -54,11 +52,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -80,7 +78,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -110,7 +108,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -120,7 +118,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -138,7 +136,6 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -159,7 +156,6 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -183,7 +179,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -193,7 +189,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -250,11 +246,11 @@ async function load_process_data() { load_process_data() ``` -### Model Building With Tensorflow.js +## Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -268,12 +264,11 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript - async function train() { const model = get_model() const data = await load_process_data() @@ -285,7 +280,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -298,15 +293,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -393,7 +388,6 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text - Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -419,13 +413,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index a88f855..f5f99a2 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,27 +8,43 @@ description: >- ## Installation -There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: +There are three ways to install and use Danfo.js in your application + +For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: ```text npm install danfojs-node + +or + +yarn add danfojs-node +``` + +For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: + +```text +npm install danfojs + +or + +yarn add danfojs ``` -You can also install and use it in the browsers by using the CDN below: +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. +We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -45,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -114,7 +130,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ NaN ║ +║ 3 │ undefined ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -168,17 +184,15 @@ s.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 1 │ 34 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╚═══╧════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -386,19 +400,17 @@ df.ctypes.print() ```text //output -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ string ║ -╟───┼──────────────────────╢ -║ B │ string ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ float32 ║ -╟───┼──────────────────────╢ -║ E │ string ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ string ║ +╟───┼─────────╢ +║ B │ string ║ +╟───┼─────────╢ +║ C │ int32 ║ +╟───┼─────────╢ +║ D │ float32 ║ +╟───┼─────────╢ +║ E │ string ║ +╚═══╧═════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -705,19 +717,23 @@ df.describe().print() ```text //output in console -╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ -╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -772,15 +788,17 @@ df.print() {% endtabs %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -939,7 +957,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing, both endpoints are _included_: +Showing label slicing: ```javascript const dfd = require("danfojs-node") @@ -970,17 +988,15 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - Shape: (3,2) + -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1026,15 +1042,13 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1078,13 +1092,11 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1103,17 +1115,62 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ Count ║ +╟────────────┼───────────────────╢ +║ 0 │ 21 ║ +╟────────────┼───────────────────╢ +║ 1 │ 5 ║ +╟────────────┼───────────────────╢ +║ 2 │ 30 ║ +╟────────────┼───────────────────╢ +║ 3 │ 10 ║ +╚════════════╧═══════════════════╝ +``` + +#### Selection with Boolean Mask + +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. + +```javascript +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) + +let sub_df = df.iloc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` + +```text +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. + +```javascript +let sub_df = df.iloc({ + rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), + columns: [0] +}) +sub_df.print() + +//output +╔════════════╤═══════════════════╗ +║ │ Name ║ +╟────────────┼───────────────────╢ +║ 0 │ Apples ║ +╚════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1194,7 +1251,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Selecting values from a DataFrame works on string columns: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1202,34 +1259,36 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +let query_df = df.query({ condition: df["B"].gt(5) }) query_df.print() //after query ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` -//after query +Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let query_df = df.query({ + condition: + df["B"].gt(5).and(df["A"].lt(30)) +}) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1249,7 +1308,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace +df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace df.print() ``` @@ -1281,7 +1340,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1309,22 +1368,22 @@ df.print() //after adding column Shape: (4,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 │ 25 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 │ 35 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 │ 45 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 │ 55 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data -danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. + **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1333,13 +1392,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} @@ -1380,27 +1439,27 @@ df_drop.print() ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping - Shape: (1,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1408,44 +1467,45 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 1}) +let df_drop = df.dropna(1) df_drop.print() ``` ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 34 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ + ``` Filling missing data: @@ -1455,13 +1515,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() ``` @@ -1485,14 +1545,16 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -1554,7 +1616,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.print() df.mean().print() //defaults to column axis ``` @@ -1608,11 +1670,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ 0 │ 4 ║ +║ A │ 4 ║ ╟───┼──────────────────────╢ -║ 1 │ 38.5 ║ +║ B │ 38.5 ║ ╟───┼──────────────────────╢ -║ 2 │ 31.75 ║ +║ C │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1666,7 +1728,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -1687,7 +1749,7 @@ df_new.print() #### Apply -Applying JavaScript functions to the data: +Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1696,11 +1758,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` @@ -1721,22 +1783,18 @@ df_new.print() //after applying -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` -Applying Tensorflow functions to the data: +Applying Element wise operations to the data: -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1745,13 +1803,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -function log_sig(x) { - return x.logSigmoid() +function sum_vals(x) { + return x + 10 } -let df_new = df.apply({axis: 0, callable: log_sig }) +let df_new = df.apply_map(sum_vals) df_new.print() ``` @@ -1770,19 +1826,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after applying + //after apply_map -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 12 │ 13 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 14 │ 15 │ 16 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 │ 50 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 49 │ 99 │ 88 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2269,29 +2325,36 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") - let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] - } + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] +} let df = new dfd.DataFrame(data) -df.to_csv().then((csv) => { - console.log(csv); +const csv = df.to_csv() +console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH + + +df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs + + +df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version -}).catch((err) => { - console.log(err); -}) ``` ```text @@ -2372,18 +2435,24 @@ let data = { let df = new dfd.DataFrame(data) -df.to_json().then((json) => { - console.log(json); +const json = df.to_json() +console.log(json); +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] -}).catch((err) => { - console.log(err); -}) -``` +const json = df.to_json({format: "row"}) +console.log(json); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From f777dfd0cebd670d867565d7d451d3a72dceec73 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 14:59:55 +0000 Subject: [PATCH 024/202] GitBook: [master] 65 pages modified --- README.md | 12 +- api-reference/README.md | 2 +- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 +- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 +++--- api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 194 ++++-- .../input-output/danfo.read_excel.md | 18 +- api-reference/input-output/danfo.read_json.md | 137 +---- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- api-reference/series/README.md | 4 +- api-reference/series/series.abs.md | 26 +- api-reference/series/series.argsort.md | 50 +- api-reference/series/series.cummax.md | 28 +- api-reference/series/series.cummin.md | 28 +- api-reference/series/series.cumprod.md | 28 +- api-reference/series/series.cumsum.md | 30 +- .../series/series.drop_duplicates.md | 39 +- api-reference/series/series.dropna.md | 34 +- api-reference/series/series.dt.day.md | 44 +- api-reference/series/series.dt.hour.md | 18 +- api-reference/series/series.dt.month.md | 28 +- api-reference/series/series.dt.month_name.md | 19 +- api-reference/series/series.dt.monthday.md | 19 +- api-reference/series/series.dt.second.md | 21 +- api-reference/series/series.dt.weekdays.md | 85 +-- api-reference/series/series.dt.year.md | 19 +- api-reference/series/series.eq.md | 2 +- api-reference/series/series.fillna.md | 40 +- api-reference/series/series.ge.md | 2 +- api-reference/series/series.gt.md | 2 +- api-reference/series/series.iloc.md | 30 +- api-reference/series/series.le.md | 2 +- api-reference/series/series.loc.md | 6 +- api-reference/series/series.lt.md | 2 +- api-reference/series/series.ne.md | 2 +- api-reference/series/series.nunique.md | 2 +- api-reference/series/series.replace.md | 110 ++-- api-reference/series/series.str.capitalize.md | 26 +- api-reference/series/series.str.charat.md | 32 +- api-reference/series/series.str.concat.md | 46 +- api-reference/series/series.str.endswith.md | 34 +- api-reference/series/series.str.includes.md | 34 +- api-reference/series/series.str.indexof.md | 34 +- api-reference/series/series.str.join.md | 61 +- .../series/series.str.lastindexof.md | 34 +- api-reference/series/series.str.len.md | 58 +- api-reference/series/series.str.repeat.md | 34 +- api-reference/series/series.str.replace.md | 41 +- api-reference/series/series.str.search.md | 40 +- api-reference/series/series.str.slice.md | 41 +- api-reference/series/series.str.split.md | 3 +- api-reference/series/series.str.startswith.md | 34 +- api-reference/series/series.str.substr.md | 42 +- api-reference/series/series.str.substring.md | 41 +- .../series/series.str.tolowercase.md | 28 +- .../series/series.str.touppercase.md | 26 +- api-reference/series/series.str.trim.md | 26 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +- getting-started.md | 555 ++++++++---------- 65 files changed, 946 insertions(+), 1740 deletions(-) diff --git a/README.md b/README.md index b170fbb..92e7da5 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects +* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. -* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. +* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. +New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. {% page-ref page="getting-started.md" %} diff --git a/api-reference/README.md b/api-reference/README.md index 492db09..70dff34 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index f74da8c..3e20f6a 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,9 +21,7 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

values: Series, Array of new values to add -
inplace: Default to false.

-

}

+

value: Series, Array. New values to add }

@@ -32,11 +30,13 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** + ****return **Null** + ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,11 +53,12 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -111,11 +112,12 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -124,6 +126,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 8445c35..3e1318e 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,9 +37,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** -```text - ****return **DataFrame** -``` + ****return **DataFrame** ## **Examples** @@ -48,6 +46,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript + const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -60,11 +59,12 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -73,6 +73,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -117,11 +118,12 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -130,6 +132,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -156,5 +159,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index 692b225..b74b5da 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 54fc0ae..1cb3b8f 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,24 +17,18 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - data - Series or Dataframe - The data to dummify - - - - options + kwargs Object

{

-

columns: Array of column names to dummify. If not specified, all - categorical columns are encoded.

-

prefixSeparator: String separator for created columns e.g "_",

+

data: Array | Series | DataFrame

+

prefix_sep: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

+

columns: [Array] columns to be encoded in DataFrame.

}

- {prefixSeparator: "_"} + {prefix_sep: "_"} @@ -55,7 +49,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) dum_df.print() ``` {% endtab %} @@ -71,19 +65,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -102,7 +96,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df) +let dum_df = dfd.get_dummies({ data: df }) dum_df.print() ``` {% endtab %} @@ -165,7 +159,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 5251d48..752a196 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 43b2476..5e66567 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 4077198..2e7c0a3 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Converts an array of Date time string to Date object. +description: Convert Object to datetime format --- # danfo.to\_datetime -danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,12 +17,15 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo - - + @@ -35,16 +38,14 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo ## **Examples** -Converts a **Series** of Date strings to Date time and get time properties +### **Convert Series to Dummy codes** {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime({data:sf}) +let dt = dfd.to_datetime({data:sf}) dt.month().print() dt.month_name().print() @@ -64,99 +65,85 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - //Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 3 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╚═══╧══════════════════════╝ //string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Jan ║ +╟───┼──────────────────────╢ +║ 1 │ Feb ║ +╟───┼──────────────────────╢ +║ 2 │ Mar ║ +╟───┼──────────────────────╢ +║ 3 │ Apr ║ +╟───┼──────────────────────╢ +║ 4 │ May ║ +╚═══╧══════════════════════╝ //string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Mon ║ +╟───┼──────────────────────╢ +║ 1 │ Thu ║ +╟───┼──────────────────────╢ +║ 2 │ Thu ║ +╟───┼──────────────────────╢ +║ 3 │ Sun ║ +╟───┼──────────────────────╢ +║ 4 │ Tue ║ +╚═══╧══════════════════════╝ + +//Int representation for day of the week +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 2 ║ +╚═══╧══════════════════════╝ //Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 0 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 0 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f015c6e..f071ac9 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,5 +1,7 @@ --- -description: Functions for reading tabular/structured data into DataFrame/Series Objects +description: >- + Functions and methods to easily read tabular/structured data into DataFrame + and Series Objects --- # Input/Output @@ -9,11 +11,8 @@ description: Functions for reading tabular/structured data into DataFrame/Series | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | -| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) +Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 570c7c3..d1ab8f8 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,15 +20,11 @@ description: >- - - - + + + @@ -36,16 +32,15 @@ description: >- - +
data + kwargs Array, SeriesObject -

data: Array | Series with Date strings to convert to Date time.

-

<b></b>

+

{

+

data: Array | Series, the object to convert.

+

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", + and "%m-d-Y H%M%S%"

+

}

source - File object, File path, URL -

Any valid string path is acceptable. The string could be a URL or a valid - local file path.

-

A browser input file object is - also supported.

-
source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid + URL schemes include https, http, ftp, s3, gs, and file. Local file paths + are only accepted in Nodejs environment.
object, optional

-

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

-

<b></b>

-
-

{ +

A CSV Config object that contains configurations for reading and decoding + from CSV file(s). Supported params are:

+

start: The index position to start from when reading the CSV file.

+

end: The end position to stop at when reading the CSV file.

+

... csvConfigs: other supported Tensorflow csvConfig parameters. + See https://js.tensorflow.org/api/latest/#data.csv

-

dynamicTyping: true,

-

header: true

-

}

@@ -54,18 +49,16 @@ description: >- ****_**Promise**_. Resolves to DataFrame -The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. +### Example -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: +The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("./user_names.csv") //assumes file is in CWD +dfd.read_csv("user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -75,9 +68,45 @@ dfd.read_csv("./user_names.csv") //assumes file is in CWD }) ``` {% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` +{% endtab %} {% endtabs %} -### **Reading files from a URL** +**Loading Files from URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -105,8 +134,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -134,11 +163,29 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -### **Reading an input file object in the browser** +**Reading Large Files** + +For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series +**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. {% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_process_data() { + let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) + let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) + + df_chunk1.head().print() + df_chunk2.head().print() +} + +load_process_data() +``` +{% endtab %} + {% tab title="Browser" %} ```markup @@ -147,27 +194,100 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document - + +
+ + ``` {% endtab %} {% endtabs %} +```bash +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + + + diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index a8165d2..d8e3d9e 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,11 +26,14 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet. ->
method: The HTTP method to use.

->

headers: Additional headers to send with the request if reading -> JSON from remote url. Supports all the node-fetch options in Nodejs, and -> all fetch options in browsers.

+> Default will be the first sheet.

+>

header_index : int, (Optional) Only used in browser environment. +> The Index of the row which represents the header(columns) of the data. +> Default will be the first non empty row.

+>

data_index : int, (Optional) Only used in browser environment. The +> index of the row from which actual data(content) starts. Default will be +> the next row of header_index +>

>

}

> > @@ -43,15 +46,14 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved on a local disk, or over the internet. +The **read\_excel** method can read excel files saved from local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -const path = require("path") -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") +local_xcel = 'testexcel.xls' async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 2e978c3..49528d0 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,85 +6,24 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - Input file object, string file path or URL -

Any valid string path is acceptable. The string could be a URL. Valid - URL schemes include http, https, ftp, s3, gs, or a local path. Both relative - and absolute paths are supported

-

-

An input file object is also supported in the browser.

-
optionsObject -

Configuration options for reading JSON files. Supported options:

-

{ -
method: The HTTP method to use.

-

headers: Additional headers to send with the request if reading - JSON from remote url. Supports all the node-fetch options in - Nodejs, and all fetch options in - browsers.

-

}

-
{ -
method: "GET" -
}
+| **Parameters** | Type | Description | +| :--- | :--- | :--- | +| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | **Returns:** ****_**Promise**_. Resolves to DataFrame -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. +### Example -### **Reading JSON files from local disk** +The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") +dfd.read_json("user_names.json") .then(df => { df.head().print() @@ -97,70 +36,6 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple {% tab title="Browser" %} ```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - ``` {% endtab %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 9fd06ff..e412af9 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index b9d73a8..397b480 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,11 +44,12 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + + ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/api-reference/series/README.md b/api-reference/series/README.md index 55d25f4..cc25049 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -49,7 +49,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise \(binary operator ge\). | | [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise \(binary operator ne\). | | [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise \(binary operator eq\). | -| [`Series.dot`]() | Compute the dot product between the Series and the columns of other. | +| [`Series.dot`](series.dot.md) | Compute the dot product between the Series and the columns of other. | ### Function application & GroupBy @@ -61,7 +61,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | | :--- | :--- | -| [`Series.corr`]() | Compute correlation with other Series, excluding missing values. | +| [`Series.corr`](series.corr.md) | Compute correlation with other Series, excluding missing values. | | [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | | [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | | [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index c241eae..db9a8b4 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,31 +4,9 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] +> danfo.Series.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation in-place - or not. Defaults to false -

{

-

inplace: false

-

}

-
+**Parameters**: None **Returns:** Series diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 8926e7f..29c19e3 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -4,30 +4,11 @@ description: Return the integer indices that would sort the Series values # Series.argsort -> danfo.Series.**argsort**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] +> danfo.Series.**argsort**\(ascending\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectascending: How to sort the indices -

{ -
ascending: true

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| ascending | boolean | How to sort the indices. either **True** or **False** | true | **Returns:** Series \(int element\) @@ -41,9 +22,7 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - +sf.argsort().print() ``` {% endtab %} {% endtabs %} @@ -70,25 +49,6 @@ sf.argsort({ ascending: false }).print() ╟───┼──────────────────────╢ ║ 7 │ 1 ║ ╚═══╧══════════════════════╝ - -//sorted in descending order -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 6 ║ -╟───┼───╢ -║ 2 │ 4 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╟───┼───╢ -║ 6 │ 0 ║ -╟───┼───╢ -║ 7 │ 3 ║ -╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 78422ea..201ae11 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -4,31 +4,11 @@ description: Returns cumulative maximum over a series # Series.cummax -> danfo.Series.**cummax**\(options\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)\] +> danfo.Series.**cummax**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L825)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index d368c0c..f2337a8 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -4,31 +4,11 @@ description: Returns the cumulative min of a Series # Series.cummin -> danfo.Series.**cummin**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)\] +> danfo.Series.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L816)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 41c2898..6b72547 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -4,31 +4,11 @@ description: Return the cumulative product of a series # Series.cumprod -> danfo.Series.**cumprod**\(\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)\] +> danfo.Series.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L834)\] -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> ->
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. style="text-align:left"> ->

{

->

inplace: false

->

}

->
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index db8021c..205d777 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -4,31 +4,11 @@ description: Return a cumulative sum of a series # Series.cumsum -> danfo.Series.**cumsum**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L807)\] + +**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index eae885c..d5fd7e2 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -4,39 +4,18 @@ description: Remove duplicate rows # Series.drop\_duplicates -> danfo.Series.**drop\_duplicates**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectkeep: "first" | "last", which duplicate value - to keep. Defaults to "first". -
inplace: Boolean indicating whether to perform the operation in-place - or not. Defaults to false
-

{

-

inplace: false

-

}

-
+> danfo.Series.**drop\_duplicates**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | +| kwargs\["**keep**"\] | String | {"**first**"or "**last**"}. Specify if to keep the last or the first duplicate value | first | **Returns:** Series **Examples** -### Drop duplicate by keeping the first occurrence of the duplicate value +Drop duplicate by keeping the first value of the duplicate value {% tabs %} {% tab title="Node" %} @@ -72,7 +51,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -### Drop duplicate and keep only the last duplicated value +Drop duplicate and keep only the last duplicated value {% tabs %} {% tab title="Node" %} @@ -108,7 +87,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -### Remove duplicate value in-place +Remove duplicate value in series without returning a new series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 8e3a4be..6fa1100 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -4,37 +4,17 @@ description: Remove missing values from Series # Series.dropna -> danfo.Series.**dropna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{ -
inplace: false

-

}

-
+> danfo.Series.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | **Returns**: Series **Examples** -### Drop all nan value and then return New Series. +Drop all nan value and then return New Series. {% tabs %} {% tab title="Node" %} @@ -72,7 +52,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -### Drop nan values in-place +Drop nan values without returning new series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 3e4fd5c..09334c1 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -17,7 +17,7 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) +let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) let sf = new dfd.Series(data) sf.dt.day().print() @@ -32,26 +32,26 @@ sf.dt.day().print() {% endtabs %} ```text -╔═══╤═══╗ -║ 0 │ 6 ║ -╟───┼───╢ -║ 1 │ 0 ║ -╟───┼───╢ -║ 2 │ 1 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 4 ║ -╟───┼───╢ -║ 6 │ 5 ║ -╟───┼───╢ -║ 7 │ 6 ║ -╟───┼───╢ -║ 8 │ 0 ║ -╟───┼───╢ -║ 9 │ 1 ║ -╚═══╧═══╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╟───┼──────────────────────╢ +║ 5 │ 4 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 0 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 8b9287f..1243049 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -22,7 +22,7 @@ let sf = new dfd.Series(data) // print series sf.print() // print hour series -sf.dt.hours().print() +sf.dt.hour().print() ``` {% endtab %} @@ -37,17 +37,21 @@ sf.dt.hours().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 2:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╚═══╧═══╝ - +//print hour series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index a1b449f..0e6dedb 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -32,18 +32,20 @@ sf.dt.month().print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 6 ║ -╟───┼────╢ -║ 1 │ 7 ║ -╟───┼────╢ -║ 2 │ 9 ║ -╟───┼────╢ -║ 3 │ 9 ║ -╟───┼────╢ -║ 4 │ 11 ║ -╟───┼────╢ -║ 5 │ 11 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 7 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 9 ║ +╟───┼──────────────────────╢ +║ 4 │ 11 ║ +╟───┼──────────────────────╢ +║ 5 │ 11 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index b137205..82a7d3c 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -37,6 +37,8 @@ sf.dt.month_name().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2018, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 2/1/2018, 1:00:00 AM ║ @@ -44,13 +46,16 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═════╗ -║ 0 │ Jan ║ -╟───┼─────╢ -║ 1 │ Feb ║ -╟───┼─────╢ -║ 2 │ Mar ║ -╚═══╧═════╝ +//print month name series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Jan ║ +╟───┼──────────────────────╢ +║ 1 │ Feb ║ +╟───┼──────────────────────╢ +║ 2 │ Mar ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index e52c916..1c7e556 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -37,6 +37,8 @@ sf.dt.monthday().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/2/2000, 1:00:00 AM ║ @@ -44,13 +46,16 @@ sf.dt.monthday().print() ║ 2 │ 1/3/2000, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╚═══╧═══╝ +//print monthdays +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index 5925e40..e6fd771 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -25,7 +25,7 @@ let sf = new dfd.Series(data) sf.print() //print the seconds obtained -sf.dt.seconds().print() +sf.seconds().print() ``` {% endtab %} @@ -41,6 +41,8 @@ sf.dt.seconds().print() ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 1:00:01 AM ║ @@ -48,13 +50,16 @@ sf.dt.seconds().print() ║ 2 │ 1/1/2000, 1:00:02 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 0 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╚═══╧═══╝ +//the seconds obtained +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index 64945fa..dc79e6c 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -34,48 +34,49 @@ sf.dt.weekdays().print() {% endtabs %} ```text -╔═══╤════════════════════════╗ -║ 0 │ 12/31/2016, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 9 │ 1/9/2017, 1:00:00 AM ║ -╚═══╧════════════════════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12/31/2016, 1:00:... ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╚═══╧══════════════════════╝ -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ +//print days of the week +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Sat ║ +╟───┼──────────────────────╢ +║ 1 │ Sun ║ +╟───┼──────────────────────╢ +║ 2 │ Mon ║ +╟───┼──────────────────────╢ +║ 3 │ Tue ║ +╟───┼──────────────────────╢ +║ 4 │ Wed ║ +╟───┼──────────────────────╢ +║ 5 │ Thu ║ +╟───┼──────────────────────╢ +║ 6 │ Fri ║ +╟───┼──────────────────────╢ +║ 7 │ Sat ║ +╟───┼──────────────────────╢ +║ 8 │ Sun ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index c6a4040..a594255 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -28,6 +28,8 @@ sf.dt.year().print() ```text //print date time series ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2001, 1:00:00 AM ║ @@ -35,12 +37,15 @@ sf.dt.year().print() ║ 2 │ 1/1/2002, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤══════╗ -║ 0 │ 2000 ║ -╟───┼──────╢ -║ 1 │ 2001 ║ -╟───┼──────╢ -║ 2 │ 2002 ║ -╚═══╧══════╝ +//print the year series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2000 ║ +╟───┼──────────────────────╢ +║ 1 │ 2001 ║ +╟───┼──────────────────────╢ +║ 2 │ 2002 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 9e8a9c3..341dbb9 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -8,7 +8,7 @@ description: Check all the values in a series is equal to another value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value to compare | | +| other | Series**\|** int\|String\|float | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index f14e5d3..b1bea1b 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -4,38 +4,18 @@ description: Replace all NaN value with specified value # Series.fillna -> danfo.Series.**fillna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObject -

value: The value to replace all missing value with.

-

inplace: Boolean indicating whether to perform the operation inplace - or not. Defaults to false

-
-

{

-

inplace: false

-

}

-
+> danfo.Series.**fillna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**value**"\] | int \| String\| bool | value to replace the NaN values | | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | + +**Returns:** Series **Examples** -### Fill nan value and then return new series +Fill nan value and then return new series {% tabs %} {% tab title="Node" %} @@ -82,7 +62,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -### Fill nan value in-place +Fill nan value without returning new Series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index a7c0ead..b3d8b69 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is greater than or equal a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index 98eb444..a98f618 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -8,7 +8,7 @@ description: Check if all the value in a series is greater than a value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index 195677a..e580803 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -4,7 +4,7 @@ danfo.Series.**iloc**\(\) \[[source](https://github.com/opensource9ja/danfojs/bl | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | +| rows | Array | Array, slice or index of row position to return | | **Returns:** @@ -18,10 +18,9 @@ Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. -* A boolean mask. E.g \[ true, false, false \] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only ****the start label is included, and the end label is ignored._ +_**Note:** only ****the start label is included._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -31,6 +30,7 @@ _**Note:** only ****the start label is included, and the end label is ignored._ {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +// const tf = require("@tensorflow/tfjs-node") let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) @@ -62,7 +62,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[0: 5\]". This will return all values from index positions 0 to 4. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. {% tabs %} {% tab title="Node" %} @@ -136,27 +136,5 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} -### Slice Series by boolean condition -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index 0dde01a..e9056d7 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is less than or equal to a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns:** Series \(Boolean Element\) diff --git a/api-reference/series/series.loc.md b/api-reference/series/series.loc.md index 3b17e89..f4f292e 100644 --- a/api-reference/series/series.loc.md +++ b/api-reference/series/series.loc.md @@ -1,3 +1,7 @@ +--- +description: Access a group of rows by label(s) or a boolean array. +--- + # Series.loc danfo.Series.**loc**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -19,7 +23,7 @@ Allowed inputs are: * An integer, e.g. `"r1"`. * A list or array of integers, e.g. `["a", "b", "d"]`. * A boolean mask. E.g \[ true, false, false \] -* A string slice object with ints, e.g. `[`'`"a":"d"']` +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` _**Note:** only ****the start label is included, and the end label is ignored._ diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index 73c45d1..bb18486 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -8,7 +8,7 @@ description: Check if all values in a Series are less than a value. | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index fcf182a..9901dcd 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -8,7 +8,7 @@ description: Check if all values in a series is not equal to a value(s) | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value to compare | | +| other | Series**\|** int\|String\|float | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 42f678d..8ddafe4 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -1,5 +1,5 @@ --- -description: Returns the number of unique values in a series +description: Obtain the number of unique values in a series --- # Series.nunique diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index cf1dd06..4b49fa2 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,41 +4,19 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObject -

oldValue: The value you want to replace

-

newValue: The new value you want to replace the old value with

-

inplace: Boolean indicating whether to perform the operation inplace - or not

-
-

{

-

inplace: false

-

}

-
+> danfo.Series.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**replace**"\] | int \| String\| bool | value to be replaced | | +| kwargs\["**with**"\] | int \| String \| bool | value to replace the previous value | | +| kwargs\["**inplace**"\] | Bool | mutate the series or create the new series | false | **Returns**: Series **Examples** -### Replace a value in a series and return a new series +Replace a value in a series and return a new series {% tabs %} {% tab title="Node" %} @@ -47,7 +25,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) +let sf_rep = sf.replace({ replace: 10, with: -50 }) sf_rep.print() ``` @@ -57,27 +35,28 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -50 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ -50 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -### Replace a value in-place +Replace a value in a series , with out returning a new series {% tabs %} {% tab title="Node" %} @@ -86,7 +65,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) +sf.replace({ replace: 10, with: -50, inplace:true }) sf.print() ``` @@ -94,21 +73,22 @@ sf.print() {% endtabs %} ```text -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -50 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ -50 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.str.capitalize.md b/api-reference/series/series.str.capitalize.md index 10483b3..5df261a 100644 --- a/api-reference/series/series.str.capitalize.md +++ b/api-reference/series/series.str.capitalize.md @@ -4,31 +4,9 @@ description: Capitalize the first character of each string # Series.str.capitalize -> danfo.Series.str.**capitalize**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] +> danfo.Series.str.**capitalize**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.charat.md b/api-reference/series/series.str.charat.md index 9cb1d66..3df2bbc 100644 --- a/api-reference/series/series.str.charat.md +++ b/api-reference/series/series.str.charat.md @@ -6,35 +6,9 @@ description: Obtain the character at the specified index (position) > danfo.Series.str.**charAt**\(index\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
indexintthe index at which to obtain the character0
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| index | int | the index at which to obtain the character | 0 | **Returns**: Series \(Character element\) diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index b27bc00..0a24597 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -4,46 +4,12 @@ description: Joins two or more strings/arrays # Series.str.concat -> danfo.Series.str.**concat**\(other, position, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherstring or Arraystring or list of strings to add to each string element of the series""
positionIntThe position to add the other (string or array) is either 0 or 1. - 0 is to add the other at the beginning of each of the string element, and - 1 is to add to the end of the string element1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.str.**concat**\(other, position\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | string or Array | string or list of strings to add to each string element of the series | "" | +| position | Int | The position to add the **other** \(string or array\) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | **Returns:** Series \(String element\) diff --git a/api-reference/series/series.str.endswith.md b/api-reference/series/series.str.endswith.md index 18753cb..645294d 100644 --- a/api-reference/series/series.str.endswith.md +++ b/api-reference/series/series.str.endswith.md @@ -4,37 +4,11 @@ description: Checks whether a string ends with specified characters # Series.str.endsWith -> danfo.Series.str.**endsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] +> danfo.Series.str.**endsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.str.includes.md b/api-reference/series/series.str.includes.md index cfa9c16..c2cb4af 100644 --- a/api-reference/series/series.str.includes.md +++ b/api-reference/series/series.str.includes.md @@ -4,37 +4,11 @@ description: Checks whether a string contains the specified string/characters # Series.str.includes -> danfo.Series.str.includes\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] +> danfo.Series.str.includes\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index fe93a74..a823d20 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -4,37 +4,11 @@ description: the position of the first found occurrence of a specified value in # Series.str.indexOf -> danfo.Series.str.indexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] +> danfo.Series.str.indexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe string to obtain its index""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the string to obtain its index | "" | **Returns:** Series diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index a32c1bb..4c17295 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -4,43 +4,12 @@ description: Join a new string value to all string elements in a Series. # Series.str.join -> danfo.Series.str.**join**\(valToJoin, joinChar, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] +> danfo.Series.str.**join**\(valToJoin,joinChar\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
valToJoinStringthe string value you want to""
joinCharStringThe delimiter to specify the joining" "
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| valToJoin | String | the string value you want to | "" | +| joinChar | String | The delimiter to specify the joining | " " | **Returns:** @@ -69,15 +38,17 @@ sf.str.join("new", "_").print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════════════════════════╗ -║ 0 │ lower part_new ║ -╟───┼────────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼────────────────────────╢ -║ 2 │ this is a sentence_new ║ -╟───┼────────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧════════════════════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower part_new ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentenc... ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.lastindexof.md b/api-reference/series/series.str.lastindexof.md index d2bfa98..130c50c 100644 --- a/api-reference/series/series.str.lastindexof.md +++ b/api-reference/series/series.str.lastindexof.md @@ -6,37 +6,11 @@ description: >- # Series.str.lastIndexOf -danfo.Series.str.lastIndexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] +danfo.Series.str.lastIndexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the string to search for | "" | **Returns**: Series diff --git a/api-reference/series/series.str.len.md b/api-reference/series/series.str.len.md index be82b70..60153e8 100644 --- a/api-reference/series/series.str.len.md +++ b/api-reference/series/series.str.len.md @@ -4,31 +4,13 @@ description: Obtain the length of each string element in a Series # Series.str.len -> danfo.Series.str.**len**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] +> danfo.Series.str.**len**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters**: None + +**Returns:** + + return Series **Examples** @@ -39,7 +21,7 @@ Returns the length \(number of character\) of a string, and also return the leng ```javascript const dfd = require("danfojs-node") -let data = ["dog", 5,"cat","fog","mug","animals"] +let data = ["dog", 5,"cat",["fog","mug"],"animals"] let sf = new dfd.Series(data) sf.str.len().print() ``` @@ -55,19 +37,19 @@ sf.str.len().print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╚═══╧═══╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ NaN ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 7 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index 2f1d49b..e6c1f32 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -4,37 +4,11 @@ description: Repeat the the character(s) in a string for a specified number of t # Series.str.repeat -> danfo.Series.str.**repeat**\(num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] +> danfo.Series.str.**repeat**\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
numintegerthe string to search for1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| num | integer | the string to search for | 1 | **Returns:** Series diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index 0950071..c96137c 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,43 +4,12 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace\(searchValue, replaceValue, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] +> danfo.Series.str.replace\(searchValue, replaceValue\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
searchValuestringString | Character value to replace. Supports regex.""
replaceValueStringstring to replace the searched string""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| searchValue | string | the string to search for | "" | +| replaceValue | String | string to replace the searched string | "" | **Returns:** Series diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 4367ae8..8824095 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -4,39 +4,13 @@ description: Obtain the index position of a searched character in a String # Series.str.search -> danfo.Series.str.**search**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strStringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.str.**search**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] + + + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | String | the string to search for | "" | **Returns:** diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index e843eb8..d314066 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -4,43 +4,12 @@ description: Obtain the substring of each element in a series # Series.str.slice -> danfo.Series.str.slice\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] +> danfo.Series.str.slice\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | **Returns:** diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 4b88313..65a82c7 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,12 +6,11 @@ description: >- # Series.str.split -> danfo.Series.str.**split**\(splitVal, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)\] +> danfo.Series.str.**split**\(splitVal\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L250)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | | splitVal | String | separator or delimiter used to split the string | " " | -| options | Object | **inplace**: Whether to perform operation in-place or not. | { inplace: false } | **Returns** diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index c141afd..311bb2f 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -4,37 +4,11 @@ description: Test whether a string begins with specified characters # Series.str.startsWith -> danfo.Series.str.**startsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] +> danfo.Series.str.**startsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index 8869806..1512f02 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -6,44 +6,12 @@ description: >- # Series.str.substr -> danfo.Series.str.substr\(startIndex, num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] +> danfo.Series.str.substr\(startIndex, num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
numNumberThe number of character to obtain starting from the startIndex1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| num | Number | The number of character to obtain starting from the startIndex | 1 | **Returns:** diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 7515af0..73ab3a8 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -4,43 +4,12 @@ description: Obtain the substring of each element in a series # Series.str.substring -> danfo.Series.str.**substring**\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] +> danfo.Series.str.**substring**\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | **Returns** diff --git a/api-reference/series/series.str.tolowercase.md b/api-reference/series/series.str.tolowercase.md index 9dfb12f..ada457b 100644 --- a/api-reference/series/series.str.tolowercase.md +++ b/api-reference/series/series.str.tolowercase.md @@ -4,31 +4,11 @@ description: Converts all characters to lower case. # Series.str.toLowerCase -> danfo.Series.str.toLowerCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] +> danfo.Series.str.toLowerCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Returns**: Series \(String element\) **Example** diff --git a/api-reference/series/series.str.touppercase.md b/api-reference/series/series.str.touppercase.md index 4f630ae..7e23c08 100644 --- a/api-reference/series/series.str.touppercase.md +++ b/api-reference/series/series.str.touppercase.md @@ -4,31 +4,9 @@ description: Converts all characters to uppercase. # Series.str.toUpperCase -> danfo.Series.str.toUpperCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] +> danfo.Series.str.toUpperCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index 181c004..7e30db5 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -4,31 +4,9 @@ description: Remove leading and trailing Whitespace from a String element # Series.str.trim -> danfo.Series.str.**trim**\(options\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** +> danfo.Series.str.**trim**\(\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns:** diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 48b3b1c..66dd124 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,7 +9,9 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. + + +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -17,9 +19,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -## Setting up your environment +### Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -29,9 +31,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -44,7 +46,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -## Loading and processing your data +### Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -52,11 +54,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -78,7 +80,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -108,7 +110,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -118,7 +120,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -136,6 +138,7 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -156,6 +159,7 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -179,7 +183,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -189,7 +193,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -246,11 +250,11 @@ async function load_process_data() { load_process_data() ``` -## Model Building With Tensorflow.js +### Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -264,11 +268,12 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript + async function train() { const model = get_model() const data = await load_process_data() @@ -280,7 +285,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -293,15 +298,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -388,6 +393,7 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text + Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -413,13 +419,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index f5f99a2..a88f855 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,43 +8,27 @@ description: >- ## Installation -There are three ways to install and use Danfo.js in your application - -For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: +There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: ```text npm install danfojs-node - -or - -yarn add danfojs-node -``` - -For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: - -```text -npm install danfojs - -or - -yarn add danfojs ``` -For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): +You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. +We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -61,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -130,7 +114,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ undefined ║ +║ 3 │ NaN ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -184,15 +168,17 @@ s.print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 12 ║ -╟───┼────╢ -║ 1 │ 34 ║ -╟───┼────╢ -║ 2 │ 56 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -400,17 +386,19 @@ df.ctypes.print() ```text //output -╔═══╤═════════╗ -║ A │ string ║ -╟───┼─────────╢ -║ B │ string ║ -╟───┼─────────╢ -║ C │ int32 ║ -╟───┼─────────╢ -║ D │ float32 ║ -╟───┼─────────╢ -║ E │ string ║ -╚═══╧═════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ string ║ +╟───┼──────────────────────╢ +║ B │ string ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ float32 ║ +╟───┼──────────────────────╢ +║ E │ string ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -717,23 +705,19 @@ df.describe().print() ```text //output in console -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ +╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -788,17 +772,15 @@ df.print() {% endtabs %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ -4 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47.3 │ 5 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -20 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -957,7 +939,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing: +Showing label slicing, both endpoints are _included_: ```javascript const dfd = require("danfojs-node") @@ -988,15 +970,17 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - + Shape: (3,2) -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1042,13 +1026,15 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1092,11 +1078,13 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1115,62 +1103,17 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╗ -║ │ Count ║ -╟────────────┼───────────────────╢ -║ 0 │ 21 ║ -╟────────────┼───────────────────╢ -║ 1 │ 5 ║ -╟────────────┼───────────────────╢ -║ 2 │ 30 ║ -╟────────────┼───────────────────╢ -║ 3 │ 10 ║ -╚════════════╧═══════════════════╝ -``` - -#### Selection with Boolean Mask - -You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. - -```javascript -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) - -let sub_df = df.iloc({ rows: df["Count"].gt(10) }) -sub_df.print() -``` - -```text -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. - -```javascript -let sub_df = df.iloc({ - rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), - columns: [0] -}) -sub_df.print() - -//output -╔════════════╤═══════════════════╗ -║ │ Name ║ -╟────────────┼───────────────────╢ -║ 0 │ Apples ║ -╚════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1251,7 +1194,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: +Selecting values from a DataFrame works on string columns: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1259,36 +1202,34 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -let query_df = df.query({ condition: df["B"].gt(5) }) +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) query_df.print() //after query ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let query_df = df.query({ - condition: - df["B"].gt(5).and(df["A"].lt(30)) -}) -query_df.print() //after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1308,7 +1249,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace +df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() ``` @@ -1340,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1368,22 +1309,22 @@ df.print() //after adding column Shape: (4,3) -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 │ 25 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 │ 35 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 │ 45 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 │ 55 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data - **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. To drop any rows that have missing data: @@ -1392,13 +1333,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropna({axis: 0}) df_drop.print() ``` {% endtab %} @@ -1439,27 +1380,27 @@ df_drop.print() ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + Shape: (1,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1467,45 +1408,44 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(1) +let df_drop = df.dropna({axis: 1}) df_drop.print() ``` ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ NaN │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 34 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╗ -║ │ C ║ -╟────────────┼───────────────────╢ -║ 0 │ 3 ║ -╟────────────┼───────────────────╢ -║ 1 │ 6 ║ -╟────────────┼───────────────────╢ -║ 2 │ 40 ║ -╟────────────┼───────────────────╢ -║ 3 │ 78 ║ -╚════════════╧═══════════════════╝ - +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ ``` Filling missing data: @@ -1515,13 +1455,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillna({ values: ["Apples"] }) df_filled.print() ``` @@ -1545,16 +1485,14 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} +let data = {"Name":["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) +let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) df_filled.print() ``` @@ -1616,7 +1554,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) +let df = new dfd.DataFrame(data) df.print() df.mean().print() //defaults to column axis ``` @@ -1670,11 +1608,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ A │ 4 ║ +║ 0 │ 4 ║ ╟───┼──────────────────────╢ -║ B │ 38.5 ║ +║ 1 │ 38.5 ║ ╟───┼──────────────────────╢ -║ C │ 31.75 ║ +║ 2 │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1728,7 +1666,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, { axis: 1 }) +let df_new = df.sub(sf, axis = 1) df_new.print() ``` @@ -1749,7 +1687,7 @@ df_new.print() #### Apply -Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: +Applying JavaScript functions to the data: ```javascript const dfd = require("danfojs") @@ -1758,11 +1696,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); +function sum_vals(x) { + return x + 20 } -let df_new = df.apply(sum_vals, { axis: 1 }) +let df_new = df.apply({callable: sum_vals }) df_new.print() ``` @@ -1783,18 +1721,22 @@ df_new.print() //after applying -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 22 │ 23 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 24 │ 25 │ 26 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 40 │ 50 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 59 │ 109 │ 98 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Applying Element wise operations to the data: +Applying Tensorflow functions to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. ```javascript const dfd = require("danfojs-node") @@ -1803,11 +1745,13 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 10 +df.print() + +function log_sig(x) { + return x.logSigmoid() } -let df_new = df.apply_map(sum_vals) +let df_new = df.apply({axis: 0, callable: log_sig }) df_new.print() ``` @@ -1826,19 +1770,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after apply_map + //after applying -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 12 │ 13 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 14 │ 15 │ 16 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 │ 50 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 49 │ 99 │ 88 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2325,36 +2269,29 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. ```javascript const dfd = require("danfojs-node") + let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] -} + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] + } let df = new dfd.DataFrame(data) -const csv = df.to_csv() -console.log(csv); -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH - - -df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs - - -df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version +df.to_csv().then((csv) => { + console.log(csv); +}).catch((err) => { + console.log(err); +}) ``` ```text @@ -2435,24 +2372,18 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.to_json() -console.log(json); -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] +df.to_json().then((json) => { + console.log(json); +}).catch((err) => { -const json = df.to_json({format: "row"}) -console.log(json); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} + console.log(err); +}) +``` +```text +[{"Abs":20.2,"Count":34,"country code":"NG"}, +{"Abs":30,"Count":4,"country code":"FR"}, +{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From 7dfb5b7de7e402cc0df084e0cfc6f446875feaee Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 15:29:24 +0000 Subject: [PATCH 025/202] GitBook: [master] 210 pages modified --- README.md | 12 +- SUMMARY.md | 1 - api-reference/README.md | 2 +- .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 +- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 +++--- api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 194 ++---- .../input-output/danfo.read_excel.md | 18 +- api-reference/input-output/danfo.read_json.md | 137 ++++- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- api-reference/series/README.md | 6 +- api-reference/series/series.abs.md | 26 +- api-reference/series/series.add.md | 36 +- api-reference/series/series.apply.md | 38 +- api-reference/series/series.argsort.md | 50 +- api-reference/series/series.copy.md | 2 +- api-reference/series/series.cummax.md | 28 +- api-reference/series/series.cummin.md | 28 +- api-reference/series/series.cumprod.md | 28 +- api-reference/series/series.cumsum.md | 30 +- api-reference/series/series.div.md | 37 +- .../series/series.drop_duplicates.md | 39 +- api-reference/series/series.dropna.md | 34 +- api-reference/series/series.dt.day.md | 44 +- api-reference/series/series.dt.hour.md | 18 +- api-reference/series/series.dt.month.md | 28 +- api-reference/series/series.dt.month_name.md | 19 +- api-reference/series/series.dt.monthday.md | 19 +- api-reference/series/series.dt.second.md | 21 +- api-reference/series/series.dt.weekdays.md | 85 ++- api-reference/series/series.dt.year.md | 19 +- api-reference/series/series.eq.md | 2 +- api-reference/series/series.fillna.md | 40 +- api-reference/series/series.ge.md | 2 +- api-reference/series/series.gt.md | 2 +- api-reference/series/series.iloc.md | 30 +- api-reference/series/series.le.md | 2 +- api-reference/series/series.lt.md | 2 +- api-reference/series/series.map.md | 38 +- api-reference/series/series.mod.md | 34 +- api-reference/series/series.mul.md | 36 +- api-reference/series/series.ne.md | 2 +- api-reference/series/series.nunique.md | 2 +- api-reference/series/series.pow.md | 34 +- api-reference/series/series.replace.md | 110 ++-- api-reference/series/series.reset_index.md | 137 ++--- api-reference/series/series.round.md | 34 +- api-reference/series/series.sample.md | 74 ++- api-reference/series/series.set_index.md | 99 ++-- api-reference/series/series.sort_values.md | 169 +++--- api-reference/series/series.str.capitalize.md | 26 +- api-reference/series/series.str.charat.md | 32 +- api-reference/series/series.str.concat.md | 46 +- api-reference/series/series.str.endswith.md | 34 +- api-reference/series/series.str.includes.md | 34 +- api-reference/series/series.str.indexof.md | 34 +- api-reference/series/series.str.join.md | 61 +- .../series/series.str.lastindexof.md | 34 +- api-reference/series/series.str.len.md | 58 +- api-reference/series/series.str.repeat.md | 34 +- api-reference/series/series.str.replace.md | 41 +- api-reference/series/series.str.search.md | 40 +- api-reference/series/series.str.slice.md | 41 +- api-reference/series/series.str.split.md | 3 +- api-reference/series/series.str.startswith.md | 34 +- api-reference/series/series.str.substr.md | 42 +- api-reference/series/series.str.substring.md | 41 +- .../series/series.str.tolowercase.md | 28 +- .../series/series.str.touppercase.md | 26 +- api-reference/series/series.str.trim.md | 26 +- api-reference/series/series.sub.md | 36 +- ...iction-using-danfo.js-and-tensorflow.js.md | 58 +- getting-started.md | 555 ++++++++++-------- 79 files changed, 2289 insertions(+), 1198 deletions(-) diff --git a/README.md b/README.md index 92e7da5..b170fbb 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects +* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. -* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. +* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. {% page-ref page="getting-started.md" %} diff --git a/SUMMARY.md b/SUMMARY.md index 0fe654f..d7821c4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -75,7 +75,6 @@ * [Series.lt](api-reference/series/series.lt.md) * [Series.iloc](api-reference/series/series.iloc.md) * [Series.loc](api-reference/series/series.loc.md) - * [Series.size](api-reference/series/series.size.md) * [Series.ndim](api-reference/series/series.ndim.md) * [Series.shape](api-reference/series/series.shape.md) * [Series.dtype](api-reference/series/series.dtype.md) diff --git a/api-reference/README.md b/api-reference/README.md index 70dff34..492db09 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3e20f6a..f74da8c 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,7 +21,9 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

value: Series, Array. New values to add }

+

values: Series, Array of new values to add +
inplace: Default to false.

+

}

@@ -30,13 +32,11 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** - ****return **Null** - ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,12 +53,11 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -112,12 +111,11 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -126,7 +124,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3e1318e..8445c35 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,7 +37,9 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** - ****return **DataFrame** +```text + ****return **DataFrame** +``` ## **Examples** @@ -46,7 +48,6 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -59,12 +60,11 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -73,7 +73,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,12 +117,11 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} -``` +```text ``` {% endtab %} @@ -132,7 +130,6 @@ df.print() {% tabs %} {% tab title="Output" %} ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,5 +156,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index b74b5da..692b225 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 1cb3b8f..54fc0ae 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,18 +17,24 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - kwargs + data + Series or Dataframe + The data to dummify + + + + options Object

{

-

data: Array | Series | DataFrame

-

prefix_sep: String separator for created columns e.g "_",

+

columns: Array of column names to dummify. If not specified, all + categorical columns are encoded.

+

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

-

columns: [Array] columns to be encoded in DataFrame.

}

- {prefix_sep: "_"} + {prefixSeparator: "_"} @@ -49,7 +55,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) dum_df.print() ``` {% endtab %} @@ -65,19 +71,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -96,7 +102,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df }) +let dum_df = dfd.get_dummies(df) dum_df.print() ``` {% endtab %} @@ -159,7 +165,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 752a196..5251d48 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 5e66567..43b2476 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 2e7c0a3..4077198 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Convert Object to datetime format +description: Converts an array of Date time string to Date object. --- # danfo.to\_datetime -danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,15 +17,12 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - - + @@ -38,14 +35,16 @@ danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/dan ## **Examples** -### **Convert Series to Dummy codes** +Converts a **Series** of Date strings to Date time and get time properties {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -let dt = dfd.to_datetime({data:sf}) +sf.print() + +let dt = dfd.toDateTime({data:sf}) dt.month().print() dt.month_name().print() @@ -65,85 +64,99 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + //Int representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╚═══╧══════════════════════╝ + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 //string representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╟───┼──────────────────────╢ -║ 3 │ Apr ║ -╟───┼──────────────────────╢ -║ 4 │ May ║ -╚═══╧══════════════════════╝ +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec //string representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Mon ║ -╟───┼──────────────────────╢ -║ 1 │ Thu ║ -╟───┼──────────────────────╢ -║ 2 │ Thu ║ -╟───┼──────────────────────╢ -║ 3 │ Sun ║ -╟───┼──────────────────────╢ -║ 4 │ Tue ║ -╚═══╧══════════════════════╝ - -//Int representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 2 ║ -╚═══╧══════════════════════╝ +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + //Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 0 ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f071ac9..f015c6e 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,7 +1,5 @@ --- -description: >- - Functions and methods to easily read tabular/structured data into DataFrame - and Series Objects +description: Functions for reading tabular/structured data into DataFrame/Series Objects --- # Input/Output @@ -11,8 +9,11 @@ description: >- | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | +| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d1ab8f8..570c7c3 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,11 +20,15 @@ description: >- - - - + + + @@ -32,15 +36,16 @@ description: >- + -
kwargs + data ObjectArray, Series -

{

-

data: Array | Series, the object to convert.

-

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", - and "%m-d-Y H%M%S%"

-

}

+

data: Array | Series with Date strings to convert to Date time.

+

<b></b>

source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid - URL schemes include https, http, ftp, s3, gs, and file. Local file paths - are only accepted in Nodejs environment.source + File object, File path, URL +

Any valid string path is acceptable. The string could be a URL or a valid + local file path.

+

A browser input file object is + also supported.

+
object, optional

-

A CSV Config object that contains configurations for reading and decoding - from CSV file(s). Supported params are:

-

start: The index position to start from when reading the CSV file.

-

end: The end position to stop at when reading the CSV file.

-

... csvConfigs: other supported Tensorflow csvConfig parameters. - See https://js.tensorflow.org/api/latest/#data.csv +

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

+

<b></b>

+
+

{

+

dynamicTyping: true,

+

header: true

+

}

@@ -49,16 +54,18 @@ description: >- ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. -The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("user_names.csv") //assumes file is in CWD +dfd.read_csv("./user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -68,45 +75,9 @@ dfd.read_csv("user_names.csv") //assumes file is in CWD }) ``` {% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - - -``` -{% endtab %} {% endtabs %} -**Loading Files from URL** +### **Reading files from a URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -134,8 +105,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -163,29 +134,11 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -**Reading Large Files** - -For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: +### **Reading an input file object in the browser** -**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series {% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_process_data() { - let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) - let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) - - df_chunk1.head().print() - df_chunk2.head().print() -} - -load_process_data() -``` -{% endtab %} - {% tab title="Browser" %} ```markup @@ -194,100 +147,27 @@ load_process_data() - + Document - -
+ - - ``` {% endtab %} {% endtabs %} -```bash -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..a8165d2 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,14 +26,11 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

+> Default will be the first sheet. +>
method: The HTTP method to use.

+>

headers: Additional headers to send with the request if reading +> JSON from remote url. Supports all the node-fetch options in Nodejs, and +> all fetch options in browsers.

>

}

> > @@ -46,14 +43,15 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read\_excel** method can read excel files saved on a local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 49528d0..2e978c3 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,24 +6,85 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] -| **Parameters** | Type | Description | -| :--- | :--- | :--- | -| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
source + Input file object, string file path or URL +

Any valid string path is acceptable. The string could be a URL. Valid + URL schemes include http, https, ftp, s3, gs, or a local path. Both relative + and absolute paths are supported

+

+

An input file object is also supported in the browser.

+
optionsObject +

Configuration options for reading JSON files. Supported options:

+

{ +
method: The HTTP method to use.

+

headers: Additional headers to send with the request if reading + JSON from remote url. Supports all the node-fetch options in + Nodejs, and all fetch options in + browsers.

+

}

+
{ +
method: "GET" +
}
**Returns:** ****_**Promise**_. Resolves to DataFrame -### Example +The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. -The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: +### **Reading JSON files from local disk** {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("user_names.json") +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") .then(df => { df.head().print() @@ -36,6 +97,70 @@ dfd.read_json("user_names.json") {% tab title="Browser" %} ```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + ``` {% endtab %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index e412af9..9fd06ff 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 397b480..b9d73a8 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,12 +44,11 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + - ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/api-reference/series/README.md b/api-reference/series/README.md index cc25049..8886e37 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -18,7 +18,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | | [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | | [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](series.size.md) | Return the number of elements in the underlying data. | +| [`Series.size`]() | Return the number of elements in the underlying data. | ### Conversion @@ -49,7 +49,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise \(binary operator ge\). | | [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise \(binary operator ne\). | | [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise \(binary operator eq\). | -| [`Series.dot`](series.dot.md) | Compute the dot product between the Series and the columns of other. | +| [`Series.dot`]() | Compute the dot product between the Series and the columns of other. | ### Function application & GroupBy @@ -61,7 +61,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | | :--- | :--- | -| [`Series.corr`](series.corr.md) | Compute correlation with other Series, excluding missing values. | +| [`Series.corr`]() | Compute correlation with other Series, excluding missing values. | | [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | | [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | | [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index db9a8b4..c241eae 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,9 +4,31 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] +> danfo.Series.**abs**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] -**Parameters**: None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation in-place + or not. Defaults to false +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.add.md b/api-reference/series/series.add.md index edde21c..9632650 100644 --- a/api-reference/series/series.add.md +++ b/api-reference/series/series.add.md @@ -4,11 +4,37 @@ description: 'Return Addition of series and other, element-wise (binary operator # Series.add -> danfo.Series.add\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +> danfo.Series.add\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)\] + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series diff --git a/api-reference/series/series.apply.md b/api-reference/series/series.apply.md index f32717f..9d0407b 100644 --- a/api-reference/series/series.apply.md +++ b/api-reference/series/series.apply.md @@ -1,14 +1,40 @@ --- -description: invoke a function on Series Value +description: Invoke a function on each value in a Series. --- # Series.apply -> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function | Function \(can be anonymous\) to apply | | +> danfo.series.**apply**\(callable, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
callableFunctionFunction (can be anonymous) to apply
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 29c19e3..8926e7f 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -4,11 +4,30 @@ description: Return the integer indices that would sort the Series values # Series.argsort -> danfo.Series.**argsort**\(ascending\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] +> danfo.Series.**argsort**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| ascending | boolean | How to sort the indices. either **True** or **False** | true | + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectascending: How to sort the indices +

{ +
ascending: true

+

}

+
**Returns:** Series \(int element\) @@ -22,7 +41,9 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() +sf.argsort().print() //defaults to ascending order +sf.argsort({ ascending: false }).print() + ``` {% endtab %} {% endtabs %} @@ -49,6 +70,25 @@ sf.argsort().print() ╟───┼──────────────────────╢ ║ 7 │ 1 ║ ╚═══╧══════════════════════╝ + +//sorted in descending order +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 6 ║ +╟───┼───╢ +║ 2 │ 4 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.copy.md b/api-reference/series/series.copy.md index 323fb47..73220c4 100644 --- a/api-reference/series/series.copy.md +++ b/api-reference/series/series.copy.md @@ -1,5 +1,5 @@ --- -description: Make a new copy of a Series +description: Makes a deep copy of a Series --- # Series.copy diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 201ae11..78422ea 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -4,11 +4,31 @@ description: Returns cumulative maximum over a series # Series.cummax -> danfo.Series.**cummax**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L825)\] +> danfo.Series.**cummax**\(options\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)\] -**Parameters:** None - -**Return**: Series + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index f2337a8..d368c0c 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -4,11 +4,31 @@ description: Returns the cumulative min of a Series # Series.cummin -> danfo.Series.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L816)\] +> danfo.Series.**cummin**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)\] -**Parameters:** None - -**Return**: Series + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 6b72547..41c2898 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -4,11 +4,31 @@ description: Return the cumulative product of a series # Series.cumprod -> danfo.Series.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L834)\] +> danfo.Series.**cumprod**\(\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)\] -**Parameters:** None - -**Return**: Series +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +>
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. style="text-align:left"> +>

{

+>

inplace: false

+>

}

+>
**Example** diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index 205d777..db8021c 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -4,11 +4,31 @@ description: Return a cumulative sum of a series # Series.cumsum -> danfo.Series.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L807)\] - -**Parameters:** None - -**Return**: Series +> danfo.Series.**cumsum**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.div.md b/api-reference/series/series.div.md index 4dd4fd0..495eba5 100644 --- a/api-reference/series/series.div.md +++ b/api-reference/series/series.div.md @@ -6,12 +6,37 @@ description: >- # Series.div -> danfo.Series.div\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)\] +> danfo.Series.div\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | -| round | bool | specify if to round off the floating number | true | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series @@ -51,7 +76,7 @@ sf1.div(sf2).print() {% endtab %} {% endtabs %} -divide with a value +### divide with a value {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index d5fd7e2..eae885c 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -4,18 +4,39 @@ description: Remove duplicate rows # Series.drop\_duplicates -> danfo.Series.**drop\_duplicates**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | -| kwargs\["**keep**"\] | String | {"**first**"or "**last**"}. Specify if to keep the last or the first duplicate value | first | +> danfo.Series.**drop\_duplicates**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectkeep: "first" | "last", which duplicate value + to keep. Defaults to "first". +
inplace: Boolean indicating whether to perform the operation in-place + or not. Defaults to false
+

{

+

inplace: false

+

}

+
**Returns:** Series **Examples** -Drop duplicate by keeping the first value of the duplicate value +### Drop duplicate by keeping the first occurrence of the duplicate value {% tabs %} {% tab title="Node" %} @@ -51,7 +72,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Drop duplicate and keep only the last duplicated value +### Drop duplicate and keep only the last duplicated value {% tabs %} {% tab title="Node" %} @@ -87,7 +108,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Remove duplicate value in series without returning a new series +### Remove duplicate value in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 6fa1100..8e3a4be 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -4,17 +4,37 @@ description: Remove missing values from Series # Series.dropna -> danfo.Series.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | +> danfo.Series.**dropna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{ +
inplace: false

+

}

+
**Returns**: Series **Examples** -Drop all nan value and then return New Series. +### Drop all nan value and then return New Series. {% tabs %} {% tab title="Node" %} @@ -52,7 +72,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Drop nan values without returning new series +### Drop nan values in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 09334c1..3e4fd5c 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -17,7 +17,7 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) let sf = new dfd.Series(data) sf.dt.day().print() @@ -32,26 +32,26 @@ sf.dt.day().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 0 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ ``` diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 1243049..8b9287f 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -22,7 +22,7 @@ let sf = new dfd.Series(data) // print series sf.print() // print hour series -sf.dt.hour().print() +sf.dt.hours().print() ``` {% endtab %} @@ -37,21 +37,17 @@ sf.dt.hour().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 2:00:00 AM ║ ╚═══╧══════════════════════╝ -//print hour series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╚═══╧═══╝ + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index 0e6dedb..a1b449f 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -32,20 +32,18 @@ sf.dt.month().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 7 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╟───┼──────────────────────╢ -║ 4 │ 11 ║ -╟───┼──────────────────────╢ -║ 5 │ 11 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 6 ║ +╟───┼────╢ +║ 1 │ 7 ║ +╟───┼────╢ +║ 2 │ 9 ║ +╟───┼────╢ +║ 3 │ 9 ║ +╟───┼────╢ +║ 4 │ 11 ║ +╟───┼────╢ +║ 5 │ 11 ║ +╚═══╧════╝ ``` diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index 82a7d3c..b137205 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -37,8 +37,6 @@ sf.dt.month_name().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2018, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 2/1/2018, 1:00:00 AM ║ @@ -46,16 +44,13 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print month name series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ Jan ║ +╟───┼─────╢ +║ 1 │ Feb ║ +╟───┼─────╢ +║ 2 │ Mar ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index 1c7e556..e52c916 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -37,8 +37,6 @@ sf.dt.monthday().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/2/2000, 1:00:00 AM ║ @@ -46,16 +44,13 @@ sf.dt.monthday().print() ║ 2 │ 1/3/2000, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print monthdays -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index e6fd771..5925e40 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -25,7 +25,7 @@ let sf = new dfd.Series(data) sf.print() //print the seconds obtained -sf.seconds().print() +sf.dt.seconds().print() ``` {% endtab %} @@ -41,8 +41,6 @@ sf.seconds().print() ```text ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 1:00:01 AM ║ @@ -50,16 +48,13 @@ sf.seconds().print() ║ 2 │ 1/1/2000, 1:00:02 AM ║ ╚═══╧══════════════════════╝ -//the seconds obtained -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╚═══╧═══╝ ``` {% endtab %} diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index dc79e6c..64945fa 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -34,49 +34,48 @@ sf.dt.weekdays().print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12/31/2016, 1:00:... ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ -//print days of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Sat ║ -╟───┼──────────────────────╢ -║ 1 │ Sun ║ -╟───┼──────────────────────╢ -║ 2 │ Mon ║ -╟───┼──────────────────────╢ -║ 3 │ Tue ║ -╟───┼──────────────────────╢ -║ 4 │ Wed ║ -╟───┼──────────────────────╢ -║ 5 │ Thu ║ -╟───┼──────────────────────╢ -║ 6 │ Fri ║ -╟───┼──────────────────────╢ -║ 7 │ Sat ║ -╟───┼──────────────────────╢ -║ 8 │ Sun ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ Sat ║ +╟───┼──────╢ +║ 1 │ Sun ║ +╟───┼──────╢ +║ 2 │ Mon ║ +╟───┼──────╢ +║ 3 │ Tue ║ +╟───┼──────╢ +║ 4 │ Wed ║ +╟───┼──────╢ +║ 5 │ Thur ║ +╟───┼──────╢ +║ 6 │ Fri ║ +╟───┼──────╢ +║ 7 │ Sat ║ +╟───┼──────╢ +║ 8 │ Sun ║ +╟───┼──────╢ +║ 9 │ Mon ║ +╚═══╧══════╝ ``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index a594255..c6a4040 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -28,8 +28,6 @@ sf.dt.year().print() ```text //print date time series ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2001, 1:00:00 AM ║ @@ -37,15 +35,12 @@ sf.dt.year().print() ║ 2 │ 1/1/2002, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print the year series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2000 ║ -╟───┼──────────────────────╢ -║ 1 │ 2001 ║ -╟───┼──────────────────────╢ -║ 2 │ 2002 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ 2000 ║ +╟───┼──────╢ +║ 1 │ 2001 ║ +╟───┼──────╢ +║ 2 │ 2002 ║ +╚═══╧══════╝ ``` diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 341dbb9..9e8a9c3 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -8,7 +8,7 @@ description: Check all the values in a series is equal to another value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| other | Series, Array or number | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index b1bea1b..f14e5d3 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -4,18 +4,38 @@ description: Replace all NaN value with specified value # Series.fillna -> danfo.Series.**fillna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**value**"\] | int \| String\| bool | value to replace the NaN values | | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | - -**Returns:** Series +> danfo.Series.**fillna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObject +

value: The value to replace all missing value with.

+

inplace: Boolean indicating whether to perform the operation inplace + or not. Defaults to false

+
+

{

+

inplace: false

+

}

+
**Examples** -Fill nan value and then return new series +### Fill nan value and then return new series {% tabs %} {% tab title="Node" %} @@ -62,7 +82,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Fill nan value without returning new Series +### Fill nan value in-place {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index b3d8b69..a7c0ead 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is greater than or equal a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index a98f618..98eb444 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -8,7 +8,7 @@ description: Check if all the value in a series is greater than a value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index e580803..195677a 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -4,7 +4,7 @@ danfo.Series.**iloc**\(\) \[[source](https://github.com/opensource9ja/danfojs/bl | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| rows | Array | Array, slice or index of row position to return | | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | **Returns:** @@ -18,9 +18,10 @@ Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. +* A boolean mask. E.g \[ true, false, false \] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only ****the start label is included._ +_**Note:** only ****the start label is included, and the end label is ignored._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -30,7 +31,6 @@ _**Note:** only ****the start label is included._ {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -// const tf = require("@tensorflow/tfjs-node") let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) @@ -62,7 +62,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[0: 5\]". This will return all values from index positions 0 to 4. {% tabs %} {% tab title="Node" %} @@ -136,5 +136,27 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} +### Slice Series by boolean condition +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index e9056d7..0dde01a 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is less than or equal to a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns:** Series \(Boolean Element\) diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index bb18486..73c45d1 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -8,7 +8,7 @@ description: Check if all values in a Series are less than a value. | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| other | Series, Array or number | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.map.md b/api-reference/series/series.map.md index 1071a1f..c992de7 100644 --- a/api-reference/series/series.map.md +++ b/api-reference/series/series.map.md @@ -1,25 +1,51 @@ --- -description: Map the value of a series to it representation +description: Map the value of a series to a function or Object --- # Series.map > danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] -| Parameter | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function or Object | callable can either be a function or an object\({}\) | | + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescriptionDefault
callableFunction or ObjectA function or object({})
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Example** -Mapping the element in a Series to a word +Mapping the element in a Series words in an Object {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let sf = new dfd.Series([1,2,3,4]) +let sf = new dfd.Series([1, 2, 3, 4]) let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } sf.map(map).print() diff --git a/api-reference/series/series.mod.md b/api-reference/series/series.mod.md index 59a0320..1dee05d 100644 --- a/api-reference/series/series.mod.md +++ b/api-reference/series/series.mod.md @@ -4,11 +4,37 @@ description: 'Return Modulo of series and other, element-wise (binary operator m # Series.mod -> danfo.Series.mod\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)\] +> danfo.Series.mod\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\|float | values | | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|floatvalues
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series diff --git a/api-reference/series/series.mul.md b/api-reference/series/series.mul.md index 855173b..463d52e 100644 --- a/api-reference/series/series.mul.md +++ b/api-reference/series/series.mul.md @@ -4,11 +4,37 @@ description: 'Return Multiplication of series and other, element-wise (binary op # Series.mul -> danfo.Series.mul\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +> danfo.Series.mul\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)\] + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index 9901dcd..fcf182a 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -8,7 +8,7 @@ description: Check if all values in a series is not equal to a value(s) | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| other | Series, Array or number | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 8ddafe4..42f678d 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -1,5 +1,5 @@ --- -description: Obtain the number of unique values in a series +description: Returns the number of unique values in a series --- # Series.nunique diff --git a/api-reference/series/series.pow.md b/api-reference/series/series.pow.md index 6a67b3b..e113ffe 100644 --- a/api-reference/series/series.pow.md +++ b/api-reference/series/series.pow.md @@ -6,11 +6,37 @@ description: >- # Series.pow -> danfo.Series.pow\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)\] +> danfo.Series.pow\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index 4b49fa2..cf1dd06 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,19 +4,41 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**replace**"\] | int \| String\| bool | value to be replaced | | -| kwargs\["**with**"\] | int \| String \| bool | value to replace the previous value | | -| kwargs\["**inplace**"\] | Bool | mutate the series or create the new series | false | +> danfo.Series.**replace**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObject +

oldValue: The value you want to replace

+

newValue: The new value you want to replace the old value with

+

inplace: Boolean indicating whether to perform the operation inplace + or not

+
+

{

+

inplace: false

+

}

+
**Returns**: Series **Examples** -Replace a value in a series and return a new series +### Replace a value in a series and return a new series {% tabs %} {% tab title="Node" %} @@ -25,7 +47,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ replace: 10, with: -50 }) +let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) sf_rep.print() ``` @@ -35,28 +57,27 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + ``` {% endtab %} {% endtabs %} -Replace a value in a series , with out returning a new series +### Replace a value in-place {% tabs %} {% tab title="Node" %} @@ -65,7 +86,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ replace: 10, with: -50, inplace:true }) +sf.replace({ oldValue: 10, newValue: -50, inplace: true}) sf.print() ``` @@ -73,22 +94,21 @@ sf.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + ``` diff --git a/api-reference/series/series.reset_index.md b/api-reference/series/series.reset_index.md index e03ea87..620904c 100644 --- a/api-reference/series/series.reset_index.md +++ b/api-reference/series/series.reset_index.md @@ -4,66 +4,28 @@ description: Reset the index of a series. # Series.reset\_index -> danfo.series.reset\_index\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] - -Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. +> danfo.series.reset\_index\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| kwargs | Object | kwargs is an object {} with key **inplace** with a boolean value. e.g {inplace: false} | inplace:false | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | **Returns :** Series -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) -let sf_reset = sf_new.reset_index() -sf_reset.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} +`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ {"alpha":"A","cou... ║ -╟───┼──────────────────────╢ -║ 1 │ {"alpha":"B","cou... ║ -╟───┼──────────────────────╢ -║ 2 │ {"alpha":"C","cou... ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} +### **Reset index to default values** {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = [20, 30, 40] +let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) +sf.print() -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) - -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) let sf_reset = sf.reset_index() sf_reset.print() - ``` {% endtab %} @@ -77,38 +39,37 @@ sf_reset.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ a │ 20 ║ +╟───┼────╢ +║ b │ 30 ║ +╟───┼────╢ +║ c │ 40 ║ +╚═══╧════╝ + +╔═══╤════╗ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 2 │ 40 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} -Reset index without returning a new Series +### Reset index to new values in-place {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) +sf.print() -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -sf.reset_index({"inplace":true}) +sf.reset_index({ inplace: true }) sf.print() + ``` {% endtab %} @@ -122,21 +83,33 @@ sf.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╟───┼───╢ +║ f │ 6 ║ +╚═══╧═══╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 4 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 6 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.round.md b/api-reference/series/series.round.md index 3dcc39f..acb6726 100644 --- a/api-reference/series/series.round.md +++ b/api-reference/series/series.round.md @@ -4,11 +4,37 @@ description: round off floating values in series # Series.round -> danfo.Series.round\(dp\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)\] +> danfo.Series.round\(dp, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| dp | int | decimal place to round off to | | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
dpintdecimal place to round off to
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.sample.md b/api-reference/series/series.sample.md index 4ab195e..7e91ca4 100644 --- a/api-reference/series/series.sample.md +++ b/api-reference/series/series.sample.md @@ -6,10 +6,36 @@ description: Return a random sample of items from an axis of object. > danfo.Series.sample\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
numIntThe number of rows to return.
optionsObjectseed: An integer specifying the random seed that will be used to + create the distribution. Ensures reproducibility of generated samples. +

{

+

seed: 1

+

}

+
**Returns:** @@ -33,20 +59,34 @@ load_data() {% tabs %} {% tab title="Output" %} ```javascript -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 7 │ 40 ║ -╟───┼──────────────────────╢ -║ 6 │ 30 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 2 │ 3 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 0 │ 1 ║ +╟───┼────╢ +║ 7 │ 40 ║ +╟───┼────╢ +║ 6 │ 30 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} +### Specify a seed when sampling + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5, { seed: 2 }) + sample.print() + +} +load_data() + +``` + diff --git a/api-reference/series/series.set_index.md b/api-reference/series/series.set_index.md index 91adf23..57abe40 100644 --- a/api-reference/series/series.set_index.md +++ b/api-reference/series/series.set_index.md @@ -4,12 +4,37 @@ description: Assign new Index to Series # Series.set\_index -> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["index"\] | Array | index to replace the former index | | -| kwargs\["inplace"\] | Boolean | return new series or not | false | +> danfo.series.**set\_index\(**options**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)\] + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescriptionDefault
indexArraynew index values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Returns:** Series @@ -19,9 +44,10 @@ description: Assign new Index to Series {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") - let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] let sf = new dfd.Series(data) +sf.print() + let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) sf_new.print() ``` @@ -37,15 +63,21 @@ sf_new.print() {% tabs %} {% tab title="Output" %} ```text -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ one │ {"alpha":"A","cou... ║ -╟───────┼──────────────────────╢ -║ two │ {"alpha":"B","cou... ║ -╟───────┼──────────────────────╢ -║ three │ {"alpha":"C","cou... ║ -╚═══════╧══════════════════════╝ +╔═══╤═════════════════════════╗ +║ 0 │ {"alpha":"A","count":1} ║ +╟───┼─────────────────────────╢ +║ 1 │ {"alpha":"B","count":2} ║ +╟───┼─────────────────────────╢ +║ 2 │ {"alpha":"C","count":3} ║ +╚═══╧═════════════════════════╝ + +╔═══════╤═════════════════════════╗ +║ one │ {"alpha":"A","count":1} ║ +╟───────┼─────────────────────────╢ +║ two │ {"alpha":"B","count":2} ║ +╟───────┼─────────────────────────╢ +║ three │ {"alpha":"C","count":3} ║ +╚═══════╧═════════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -89,16 +121,16 @@ sf_new.print() {% endtab %} {% endtabs %} -set index without creating a new series by using `inplace = true` +### Set index in-place {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs") -let data = [1,2,3,4,5,6] +let data = [1, 2, 3, 4, 5, 6] let sf = new dfd.Series(data) -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) sf.print() ``` {% endtab %} @@ -113,21 +145,20 @@ sf.print() {% tabs %} {% tab title="Output" %} ```text -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ one │ 1 ║ -╟───────┼──────────────────────╢ -║ two │ 2 ║ -╟───────┼──────────────────────╢ -║ three │ 3 ║ -╟───────┼──────────────────────╢ -║ four │ 4 ║ -╟───────┼──────────────────────╢ -║ five │ 5 ║ -╟───────┼──────────────────────╢ -║ six │ 6 ║ -╚═══════╧══════════════════════╝ +╔═══════╤═══╗ +║ one │ 1 ║ +╟───────┼───╢ +║ two │ 2 ║ +╟───────┼───╢ +║ three │ 3 ║ +╟───────┼───╢ +║ four │ 4 ║ +╟───────┼───╢ +║ five │ 5 ║ +╟───────┼───╢ +║ six │ 6 ║ +╚═══════╧═══╝ + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.sort_values.md b/api-reference/series/series.sort_values.md index 54966ac..35012f7 100644 --- a/api-reference/series/series.sort_values.md +++ b/api-reference/series/series.sort_values.md @@ -1,21 +1,43 @@ --- -description: Sort a Series in ascending or descending order +description: Sorts a Series in ascending or descending order --- # Series.sort\_values -> danfo.Series.sort\_values\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["inplace"\] | Boolean | return new series or not | false | -| kwargs\["ascending"\] | Boolean | select if to sort by ascending or descending | true | +> danfo.Series.sort\_values\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)\] + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObject +

inplace: Boolean indicating whether to perform the operation in-place + or not. Defaults to false

+

ascending: Whether to return sorted values in ascending order or + not. Defaults to true

+
+

{ +
ascending: true,

+

inplace: false

+

}

+
**Return:** Series -**Examples** - -Sort series values using the default settings +### Sort values in a Series {% tabs %} {% tab title="Node" %} @@ -34,32 +56,30 @@ sf2.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} -Sort series value without returning a new series +### Sort Series in-place {% tabs %} {% tab title="Node" %} @@ -68,7 +88,7 @@ const dfd = require("danfojs-node") let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] let sf1 = new dfd.Series(data1) -sf1.sort_values({ "inplace": true }) +sf1.sort_values({ inplace: true }) sf1.print() ``` @@ -78,32 +98,31 @@ sf1.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ + ``` {% endtab %} {% endtabs %} -Sort series value in descending order +Sort Series values in descending order {% tabs %} {% tab title="Node" %} @@ -122,27 +141,25 @@ sf1.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 6 │ 89 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 7 │ 0 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.capitalize.md b/api-reference/series/series.str.capitalize.md index 5df261a..10483b3 100644 --- a/api-reference/series/series.str.capitalize.md +++ b/api-reference/series/series.str.capitalize.md @@ -4,9 +4,31 @@ description: Capitalize the first character of each string # Series.str.capitalize -> danfo.Series.str.**capitalize**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] +> danfo.Series.str.**capitalize**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.charat.md b/api-reference/series/series.str.charat.md index 3df2bbc..9cb1d66 100644 --- a/api-reference/series/series.str.charat.md +++ b/api-reference/series/series.str.charat.md @@ -6,9 +6,35 @@ description: Obtain the character at the specified index (position) > danfo.Series.str.**charAt**\(index\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| index | int | the index at which to obtain the character | 0 | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
indexintthe index at which to obtain the character0
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(Character element\) diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index 0a24597..b27bc00 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -4,12 +4,46 @@ description: Joins two or more strings/arrays # Series.str.concat -> danfo.Series.str.**concat**\(other, position\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other** \(string or array\) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +> danfo.Series.str.**concat**\(other, position, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherstring or Arraystring or list of strings to add to each string element of the series""
positionIntThe position to add the other (string or array) is either 0 or 1. + 0 is to add the other at the beginning of each of the string element, and + 1 is to add to the end of the string element1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series \(String element\) diff --git a/api-reference/series/series.str.endswith.md b/api-reference/series/series.str.endswith.md index 645294d..18753cb 100644 --- a/api-reference/series/series.str.endswith.md +++ b/api-reference/series/series.str.endswith.md @@ -4,11 +4,37 @@ description: Checks whether a string ends with specified characters # Series.str.endsWith -> danfo.Series.str.**endsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] +> danfo.Series.str.**endsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.str.includes.md b/api-reference/series/series.str.includes.md index c2cb4af..cfa9c16 100644 --- a/api-reference/series/series.str.includes.md +++ b/api-reference/series/series.str.includes.md @@ -4,11 +4,37 @@ description: Checks whether a string contains the specified string/characters # Series.str.includes -> danfo.Series.str.includes\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] +> danfo.Series.str.includes\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index a823d20..fe93a74 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -4,11 +4,37 @@ description: the position of the first found occurrence of a specified value in # Series.str.indexOf -> danfo.Series.str.indexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] +> danfo.Series.str.indexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to obtain its index | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe string to obtain its index""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index 4c17295..a32c1bb 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -4,12 +4,43 @@ description: Join a new string value to all string elements in a Series. # Series.str.join -> danfo.Series.str.**join**\(valToJoin,joinChar\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] +> danfo.Series.str.**join**\(valToJoin, joinChar, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
valToJoinStringthe string value you want to""
joinCharStringThe delimiter to specify the joining" "
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** @@ -38,17 +69,15 @@ sf.str.join("new", "_").print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part_new ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentenc... ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════════╗ +║ 0 │ lower part_new ║ +╟───┼────────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼────────────────────────╢ +║ 2 │ this is a sentence_new ║ +╟───┼────────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧════════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.lastindexof.md b/api-reference/series/series.str.lastindexof.md index 130c50c..d2bfa98 100644 --- a/api-reference/series/series.str.lastindexof.md +++ b/api-reference/series/series.str.lastindexof.md @@ -6,11 +6,37 @@ description: >- # Series.str.lastIndexOf -danfo.Series.str.lastIndexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] +danfo.Series.str.lastIndexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to search for | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series diff --git a/api-reference/series/series.str.len.md b/api-reference/series/series.str.len.md index 60153e8..be82b70 100644 --- a/api-reference/series/series.str.len.md +++ b/api-reference/series/series.str.len.md @@ -4,13 +4,31 @@ description: Obtain the length of each string element in a Series # Series.str.len -> danfo.Series.str.**len**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] +> danfo.Series.str.**len**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] -**Parameters**: None - -**Returns:** - - return Series + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Examples** @@ -21,7 +39,7 @@ Returns the length \(number of character\) of a string, and also return the leng ```javascript const dfd = require("danfojs-node") -let data = ["dog", 5,"cat",["fog","mug"],"animals"] +let data = ["dog", 5,"cat","fog","mug","animals"] let sf = new dfd.Series(data) sf.str.len().print() ``` @@ -37,19 +55,19 @@ sf.str.len().print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ NaN ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index e6c1f32..2f1d49b 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -4,11 +4,37 @@ description: Repeat the the character(s) in a string for a specified number of t # Series.str.repeat -> danfo.Series.str.**repeat**\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] +> danfo.Series.str.**repeat**\(num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | integer | the string to search for | 1 | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
numintegerthe string to search for1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index c96137c..0950071 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,12 +4,43 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace\(searchValue, replaceValue\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] +> danfo.Series.str.replace\(searchValue, replaceValue, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| searchValue | string | the string to search for | "" | -| replaceValue | String | string to replace the searched string | "" | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
searchValuestringString | Character value to replace. Supports regex.""
replaceValueStringstring to replace the searched string""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 8824095..4367ae8 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -4,13 +4,39 @@ description: Obtain the index position of a searched character in a String # Series.str.search -> danfo.Series.str.**search**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] - - - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | String | the string to search for | "" | +> danfo.Series.str.**search**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strStringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index d314066..e843eb8 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -4,12 +4,43 @@ description: Obtain the substring of each element in a series # Series.str.slice -> danfo.Series.str.slice\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] +> danfo.Series.str.slice\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 65a82c7..4b88313 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,11 +6,12 @@ description: >- # Series.str.split -> danfo.Series.str.**split**\(splitVal\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L250)\] +> danfo.Series.str.**split**\(splitVal, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | | splitVal | String | separator or delimiter used to split the string | " " | +| options | Object | **inplace**: Whether to perform operation in-place or not. | { inplace: false } | **Returns** diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index 311bb2f..c141afd 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -4,11 +4,37 @@ description: Test whether a string begins with specified characters # Series.str.startsWith -> danfo.Series.str.**startsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] +> danfo.Series.str.**startsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index 1512f02..8869806 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -6,12 +6,44 @@ description: >- # Series.str.substr -> danfo.Series.str.substr\(startIndex, num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] +> danfo.Series.str.substr\(startIndex, num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
numNumberThe number of character to obtain starting from the startIndex1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 73ab3a8..7515af0 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -4,12 +4,43 @@ description: Obtain the substring of each element in a series # Series.str.substring -> danfo.Series.str.**substring**\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] +> danfo.Series.str.**substring**\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns** diff --git a/api-reference/series/series.str.tolowercase.md b/api-reference/series/series.str.tolowercase.md index ada457b..9dfb12f 100644 --- a/api-reference/series/series.str.tolowercase.md +++ b/api-reference/series/series.str.tolowercase.md @@ -4,11 +4,31 @@ description: Converts all characters to lower case. # Series.str.toLowerCase -> danfo.Series.str.toLowerCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] +> danfo.Series.str.toLowerCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] -**Parameters:** None - -**Returns**: Series \(String element\) + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Example** diff --git a/api-reference/series/series.str.touppercase.md b/api-reference/series/series.str.touppercase.md index 7e23c08..4f630ae 100644 --- a/api-reference/series/series.str.touppercase.md +++ b/api-reference/series/series.str.touppercase.md @@ -4,9 +4,31 @@ description: Converts all characters to uppercase. # Series.str.toUpperCase -> danfo.Series.str.toUpperCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] +> danfo.Series.str.toUpperCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index 7e30db5..181c004 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -4,9 +4,31 @@ description: Remove leading and trailing Whitespace from a String element # Series.str.trim -> danfo.Series.str.**trim**\(\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** +> danfo.Series.str.**trim**\(options\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** -**Parameters:** None + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. +

{

+

inplace: false

+

}

+
**Returns:** diff --git a/api-reference/series/series.sub.md b/api-reference/series/series.sub.md index 95da267..d9f1d7d 100644 --- a/api-reference/series/series.sub.md +++ b/api-reference/series/series.sub.md @@ -4,11 +4,37 @@ description: 'Return Subtraction of series and other, element-wise (binary opera # Series.sub -> danfo.Series.sub\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +> danfo.Series.sub\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)\] + + + + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or + not. Defaults to false +

{

+

inplace: false

+

}

+
**Return:** Series diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 66dd124..48b3b1c 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,9 +9,7 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) - - -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -19,9 +17,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -### Setting up your environment +## Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -31,9 +29,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -46,7 +44,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -### Loading and processing your data +## Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -54,11 +52,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -80,7 +78,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -110,7 +108,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -120,7 +118,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -138,7 +136,6 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -159,7 +156,6 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -183,7 +179,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -193,7 +189,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -250,11 +246,11 @@ async function load_process_data() { load_process_data() ``` -### Model Building With Tensorflow.js +## Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -268,12 +264,11 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript - async function train() { const model = get_model() const data = await load_process_data() @@ -285,7 +280,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -298,15 +293,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -393,7 +388,6 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text - Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -419,13 +413,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index a88f855..f5f99a2 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,27 +8,43 @@ description: >- ## Installation -There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: +There are three ways to install and use Danfo.js in your application + +For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: ```text npm install danfojs-node + +or + +yarn add danfojs-node +``` + +For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: + +```text +npm install danfojs + +or + +yarn add danfojs ``` -You can also install and use it in the browsers by using the CDN below: +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. +We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -45,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -114,7 +130,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ NaN ║ +║ 3 │ undefined ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -168,17 +184,15 @@ s.print() {% endtabs %} ```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 1 │ 34 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╚═══╧════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -386,19 +400,17 @@ df.ctypes.print() ```text //output -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ string ║ -╟───┼──────────────────────╢ -║ B │ string ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ float32 ║ -╟───┼──────────────────────╢ -║ E │ string ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ string ║ +╟───┼─────────╢ +║ B │ string ║ +╟───┼─────────╢ +║ C │ int32 ║ +╟───┼─────────╢ +║ D │ float32 ║ +╟───┼─────────╢ +║ E │ string ║ +╚═══╧═════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -705,19 +717,23 @@ df.describe().print() ```text //output in console -╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ -╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -772,15 +788,17 @@ df.print() {% endtabs %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -939,7 +957,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing, both endpoints are _included_: +Showing label slicing: ```javascript const dfd = require("danfojs-node") @@ -970,17 +988,15 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - Shape: (3,2) + -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1026,15 +1042,13 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1078,13 +1092,11 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1103,17 +1115,62 @@ sub_df.print() ``` ```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ Count ║ +╟────────────┼───────────────────╢ +║ 0 │ 21 ║ +╟────────────┼───────────────────╢ +║ 1 │ 5 ║ +╟────────────┼───────────────────╢ +║ 2 │ 30 ║ +╟────────────┼───────────────────╢ +║ 3 │ 10 ║ +╚════════════╧═══════════════════╝ +``` + +#### Selection with Boolean Mask + +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. + +```javascript +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) + +let sub_df = df.iloc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` + +```text +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. + +```javascript +let sub_df = df.iloc({ + rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), + columns: [0] +}) +sub_df.print() + +//output +╔════════════╤═══════════════════╗ +║ │ Name ║ +╟────────────┼───────────────────╢ +║ 0 │ Apples ║ +╚════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1194,7 +1251,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Selecting values from a DataFrame works on string columns: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1202,34 +1259,36 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +let query_df = df.query({ condition: df["B"].gt(5) }) query_df.print() //after query ``` ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` -//after query +Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let query_df = df.query({ + condition: + df["B"].gt(5).and(df["A"].lt(30)) +}) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1249,7 +1308,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace +df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace df.print() ``` @@ -1281,7 +1340,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1309,22 +1368,22 @@ df.print() //after adding column Shape: (4,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 │ 25 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 │ 35 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 │ 45 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 │ 55 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data -danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. + **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1333,13 +1392,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} @@ -1380,27 +1439,27 @@ df_drop.print() ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping - Shape: (1,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1408,44 +1467,45 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 1}) +let df_drop = df.dropna(1) df_drop.print() ``` ```text //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 34 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ + ``` Filling missing data: @@ -1455,13 +1515,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() ``` @@ -1485,14 +1545,16 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -1554,7 +1616,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.print() df.mean().print() //defaults to column axis ``` @@ -1608,11 +1670,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ 0 │ 4 ║ +║ A │ 4 ║ ╟───┼──────────────────────╢ -║ 1 │ 38.5 ║ +║ B │ 38.5 ║ ╟───┼──────────────────────╢ -║ 2 │ 31.75 ║ +║ C │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1666,7 +1728,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -1687,7 +1749,7 @@ df_new.print() #### Apply -Applying JavaScript functions to the data: +Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1696,11 +1758,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` @@ -1721,22 +1783,18 @@ df_new.print() //after applying -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` -Applying Tensorflow functions to the data: +Applying Element wise operations to the data: -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1745,13 +1803,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -function log_sig(x) { - return x.logSigmoid() +function sum_vals(x) { + return x + 10 } -let df_new = df.apply({axis: 0, callable: log_sig }) +let df_new = df.apply_map(sum_vals) df_new.print() ``` @@ -1770,19 +1826,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after applying + //after apply_map -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 12 │ 13 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 14 │ 15 │ 16 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 │ 50 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 49 │ 99 │ 88 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2269,29 +2325,36 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") - let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] - } + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] +} let df = new dfd.DataFrame(data) -df.to_csv().then((csv) => { - console.log(csv); +const csv = df.to_csv() +console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH + + +df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs + + +df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version -}).catch((err) => { - console.log(err); -}) ``` ```text @@ -2372,18 +2435,24 @@ let data = { let df = new dfd.DataFrame(data) -df.to_json().then((json) => { - console.log(json); +const json = df.to_json() +console.log(json); +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] -}).catch((err) => { - console.log(err); -}) -``` +const json = df.to_json({format: "row"}) +console.log(json); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From c799448e3e94af06730d0f7e37ca0b984a7b7e1b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 15:51:11 +0000 Subject: [PATCH 026/202] GitBook: [master] 80 pages modified --- README.md | 12 +- SUMMARY.md | 1 + api-reference/README.md | 2 +- .../dataframe/creating-a-dataframe.md | 254 ++++++++++++++++++ .../dataframe/danfo.dataframe.addcolumn.md | 15 +- .../dataframe/dataframe.set_index.md | 15 +- api-reference/general-functions/README.md | 2 +- .../general-functions/danfo.get_dummies.md | 48 ++-- .../general-functions/danfo.onehotencoder.md | 4 +- .../general-functions/danfo.standardscaler.md | 2 +- .../general-functions/danfo.to_datetime.md | 171 ++++++------ api-reference/input-output/README.md | 11 +- api-reference/input-output/danfo.read_csv.md | 194 ++++++++++--- .../input-output/danfo.read_excel.md | 18 +- api-reference/input-output/danfo.read_json.md | 137 +--------- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/timeseries-plots.md | 5 +- api-reference/series/README.md | 6 +- api-reference/series/series.abs.md | 26 +- api-reference/series/series.add.md | 36 +-- api-reference/series/series.apply.md | 38 +-- api-reference/series/series.argsort.md | 50 +--- api-reference/series/series.copy.md | 2 +- api-reference/series/series.cummax.md | 28 +- api-reference/series/series.cummin.md | 28 +- api-reference/series/series.cumprod.md | 28 +- api-reference/series/series.cumsum.md | 30 +-- api-reference/series/series.div.md | 37 +-- .../series/series.drop_duplicates.md | 39 +-- api-reference/series/series.dropna.md | 34 +-- api-reference/series/series.dt.day.md | 44 +-- api-reference/series/series.dt.hour.md | 18 +- api-reference/series/series.dt.month.md | 28 +- api-reference/series/series.dt.month_name.md | 19 +- api-reference/series/series.dt.monthday.md | 19 +- api-reference/series/series.dt.second.md | 21 +- api-reference/series/series.dt.weekdays.md | 85 +++--- api-reference/series/series.dt.year.md | 19 +- api-reference/series/series.eq.md | 2 +- api-reference/series/series.fillna.md | 40 +-- api-reference/series/series.ge.md | 2 +- api-reference/series/series.gt.md | 2 +- api-reference/series/series.iloc.md | 30 +-- api-reference/series/series.le.md | 2 +- api-reference/series/series.lt.md | 2 +- api-reference/series/series.map.md | 38 +-- api-reference/series/series.mod.md | 34 +-- api-reference/series/series.mul.md | 36 +-- api-reference/series/series.ne.md | 2 +- api-reference/series/series.nunique.md | 2 +- api-reference/series/series.pow.md | 34 +-- api-reference/series/series.replace.md | 110 ++++---- api-reference/series/series.reset_index.md | 137 ++++++---- api-reference/series/series.round.md | 34 +-- api-reference/series/series.sample.md | 74 ++--- api-reference/series/series.set_index.md | 99 +++---- api-reference/series/series.sort_values.md | 169 ++++++------ api-reference/series/series.str.capitalize.md | 26 +- api-reference/series/series.str.charat.md | 32 +-- api-reference/series/series.str.concat.md | 46 +--- api-reference/series/series.str.endswith.md | 34 +-- api-reference/series/series.str.includes.md | 34 +-- api-reference/series/series.str.indexof.md | 34 +-- api-reference/series/series.str.join.md | 61 ++--- .../series/series.str.lastindexof.md | 34 +-- api-reference/series/series.str.len.md | 58 ++-- api-reference/series/series.str.repeat.md | 34 +-- api-reference/series/series.str.replace.md | 41 +-- api-reference/series/series.str.search.md | 40 +-- api-reference/series/series.str.slice.md | 41 +-- api-reference/series/series.str.split.md | 3 +- api-reference/series/series.str.startswith.md | 34 +-- api-reference/series/series.str.substr.md | 42 +-- api-reference/series/series.str.substring.md | 41 +-- .../series/series.str.tolowercase.md | 28 +- .../series/series.str.touppercase.md | 26 +- api-reference/series/series.str.trim.md | 26 +- api-reference/series/series.sub.md | 36 +-- ...iction-using-danfo.js-and-tensorflow.js.md | 58 ++-- getting-started.md | 4 +- 80 files changed, 1211 insertions(+), 1979 deletions(-) create mode 100644 api-reference/dataframe/creating-a-dataframe.md diff --git a/README.md b/README.md index b170fbb..92e7da5 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. * Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects +* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\), Excel, and JSON data format. -* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. +* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. +New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. {% page-ref page="getting-started.md" %} diff --git a/SUMMARY.md b/SUMMARY.md index d7821c4..47af443 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -112,6 +112,7 @@ * [Series.and](api-reference/series/series.and.md) * [Series.or](api-reference/series/series.or.md) * [Dataframe](api-reference/dataframe/README.md) + * [Creating a DataFrame](api-reference/dataframe/creating-a-dataframe.md) * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) * [DataFrame.nunique](api-reference/dataframe/dataframe.nunique-1.md) diff --git a/api-reference/README.md b/api-reference/README.md index 492db09..70dff34 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md new file mode 100644 index 0000000..29d0fc2 --- /dev/null +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -0,0 +1,254 @@ +# Creating a DataFrame + +In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. + +### Creating a `DataFrame` from a JSON object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +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 }] + +df = new dfd.DataFrame(json_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Creating a `DataFrame` from a 2D tensor + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const tf = require("@tensorflow/tfjs-node") + + +let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) +let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) +df.print() +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ int32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ +``` + +### Creating a `DataFrame` from a dictionary of objects with the same length + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) + +console.log(dates); + +obj_data = {'A': dates, + 'B': ["bval1", "bval2", "bval3", "bval4"], + 'C': [10, 20, 30, 40], + 'D': [1.2, 3.45, 60.1, 45], + 'E': ["test", "train", "test", "train"] + } + +df = new dfd.DataFrame(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +//output in console +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D │ E ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying index, dtypes, columns + +You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. + +> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; +let index = ["a", "b"]; +let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] +let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] + +let df = new DataFrame(data1, { index, columns, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying memory mode + +To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: + +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; + +let df = new DataFrame(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. +{% endhint %} + +For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) + diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index f74da8c..3e20f6a 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -21,9 +21,7 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource Object

{column : str, name of the column to add

-

values: Series, Array of new values to add -
inplace: Default to false.

-

}

+

value: Series, Array. New values to add }

@@ -32,11 +30,13 @@ danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource **Returns:** + ****return **Null** + ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,11 +53,12 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -111,11 +112,12 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -124,6 +126,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 8445c35..3e1318e 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -37,9 +37,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc **Returns:** -```text - ****return **DataFrame** -``` + ****return **DataFrame** ## **Examples** @@ -48,6 +46,7 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript + const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -60,11 +59,12 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -73,6 +73,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -117,11 +118,12 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() + ``` {% endtab %} {% tab title="Browser" %} -```text +``` ``` {% endtab %} @@ -130,6 +132,7 @@ df.print() {% tabs %} {% tab title="Output" %} ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -156,5 +159,5 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index 692b225..b74b5da 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -22,7 +22,7 @@ description: Top level functions that can be called from the Danfo namespace ### Top-level dealing with datetime -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | | :--- | :--- | | [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 54fc0ae..1cb3b8f 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -17,24 +17,18 @@ danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/dan - data - Series or Dataframe - The data to dummify - - - - options + kwargs Object

{

-

columns: Array of column names to dummify. If not specified, all - categorical columns are encoded.

-

prefixSeparator: String separator for created columns e.g "_",

+

data: Array | Series | DataFrame

+

prefix_sep: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

+

columns: [Array] columns to be encoded in DataFrame.

}

- {prefixSeparator: "_"} + {prefix_sep: "_"} @@ -55,7 +49,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) dum_df.print() ``` {% endtab %} @@ -71,19 +65,19 @@ dum_df.print() {% tab title="Output" %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -102,7 +96,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df) +let dum_df = dfd.get_dummies({ data: df }) dum_df.print() ``` {% endtab %} @@ -165,7 +159,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 5251d48..752a196 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)\] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 43b2476..5e66567 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -6,7 +6,7 @@ description: Standardize features by removing the mean and scaling to unit varia class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: > z = \(x - u\) / s diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 4077198..2e7c0a3 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,10 +1,10 @@ --- -description: Converts an array of Date time string to Date object. +description: Convert Object to datetime format --- # danfo.to\_datetime -danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] @@ -17,12 +17,15 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo - - + @@ -35,16 +38,14 @@ danfo.**to\_datetime**\(data\) \[[source](https://github.com/opensource9ja/danfo ## **Examples** -Converts a **Series** of Date strings to Date time and get time properties +### **Convert Series to Dummy codes** {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime({data:sf}) +let dt = dfd.to_datetime({data:sf}) dt.month().print() dt.month_name().print() @@ -64,99 +65,85 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ```text - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - //Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 3 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╚═══╧══════════════════════╝ //string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Jan ║ +╟───┼──────────────────────╢ +║ 1 │ Feb ║ +╟───┼──────────────────────╢ +║ 2 │ Mar ║ +╟───┼──────────────────────╢ +║ 3 │ Apr ║ +╟───┼──────────────────────╢ +║ 4 │ May ║ +╚═══╧══════════════════════╝ //string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Mon ║ +╟───┼──────────────────────╢ +║ 1 │ Thu ║ +╟───┼──────────────────────╢ +║ 2 │ Thu ║ +╟───┼──────────────────────╢ +║ 3 │ Sun ║ +╟───┼──────────────────────╢ +║ 4 │ Tue ║ +╚═══╧══════════════════════╝ + +//Int representation for day of the week +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 2 ║ +╚═══╧══════════════════════╝ //Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 0 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 0 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f015c6e..f071ac9 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,5 +1,7 @@ --- -description: Functions for reading tabular/structured data into DataFrame/Series Objects +description: >- + Functions and methods to easily read tabular/structured data into DataFrame + and Series Objects --- # Input/Output @@ -9,11 +11,8 @@ description: Functions for reading tabular/structured data into DataFrame/Series | \`\` | | | :--- | :--- | | [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xlsx\) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | | [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | -| [to\_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to\_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to\_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects \(e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)\) +Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 570c7c3..d1ab8f8 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -20,15 +20,11 @@ description: >- - - - + + + @@ -36,16 +32,15 @@ description: >- - +
data + kwargs Array, SeriesObject -

data: Array | Series with Date strings to convert to Date time.

-

<b></b>

+

{

+

data: Array | Series, the object to convert.

+

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", + and "%m-d-Y H%M%S%"

+

}

source - File object, File path, URL -

Any valid string path is acceptable. The string could be a URL or a valid - local file path.

-

A browser input file object is - also supported.

-
source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid + URL schemes include https, http, ftp, s3, gs, and file. Local file paths + are only accepted in Nodejs environment.
object, optional

-

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

-

<b></b>

-
-

{ +

A CSV Config object that contains configurations for reading and decoding + from CSV file(s). Supported params are:

+

start: The index position to start from when reading the CSV file.

+

end: The end position to stop at when reading the CSV file.

+

... csvConfigs: other supported Tensorflow csvConfig parameters. + See https://js.tensorflow.org/api/latest/#data.csv

-

dynamicTyping: true,

-

header: true

-

}

@@ -54,18 +49,16 @@ description: >- ****_**Promise**_. Resolves to DataFrame -The **read\_csv** method can read a CSV file from a local disk, or over the internet \(URL\). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. +### Example -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: +The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("./user_names.csv") //assumes file is in CWD +dfd.read_csv("user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -75,9 +68,45 @@ dfd.read_csv("./user_names.csv") //assumes file is in CWD }) ``` {% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` +{% endtab %} {% endtabs %} -### **Reading files from a URL** +**Loading Files from URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -105,8 +134,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -134,11 +163,29 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -### **Reading an input file object in the browser** +**Reading Large Files** + +For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series +**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. {% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_process_data() { + let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) + let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) + + df_chunk1.head().print() + df_chunk2.head().print() +} + +load_process_data() +``` +{% endtab %} + {% tab title="Browser" %} ```markup @@ -147,27 +194,100 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document - + +
+ + ``` {% endtab %} {% endtabs %} +```bash +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + + + diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index a8165d2..d8e3d9e 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -26,11 +26,14 @@ description: Reads an excel file into DataFrame. > >

{

>

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet. ->
method: The HTTP method to use.

->

headers: Additional headers to send with the request if reading -> JSON from remote url. Supports all the node-fetch options in Nodejs, and -> all fetch options in browsers.

+> Default will be the first sheet.

+>

header_index : int, (Optional) Only used in browser environment. +> The Index of the row which represents the header(columns) of the data. +> Default will be the first non empty row.

+>

data_index : int, (Optional) Only used in browser environment. The +> index of the row from which actual data(content) starts. Default will be +> the next row of header_index +>

>

}

> > @@ -43,15 +46,14 @@ description: Reads an excel file into DataFrame. ### Example -The **read\_excel** method can read excel files saved on a local disk, or over the internet. +The **read\_excel** method can read excel files saved from local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -const path = require("path") -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") +local_xcel = 'testexcel.xls' async function load_process_data() { let df = await dfd.read_excel(local_xcel) diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 2e978c3..49528d0 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -6,85 +6,24 @@ description: Reads a JSON file into DataFrame. > danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - Input file object, string file path or URL -

Any valid string path is acceptable. The string could be a URL. Valid - URL schemes include http, https, ftp, s3, gs, or a local path. Both relative - and absolute paths are supported

-

-

An input file object is also supported in the browser.

-
optionsObject -

Configuration options for reading JSON files. Supported options:

-

{ -
method: The HTTP method to use.

-

headers: Additional headers to send with the request if reading - JSON from remote url. Supports all the node-fetch options in - Nodejs, and all fetch options in - browsers.

-

}

-
{ -
method: "GET" -
}
+| **Parameters** | Type | Description | +| :--- | :--- | :--- | +| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | **Returns:** ****_**Promise**_. Resolves to DataFrame -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. +### Example -### **Reading JSON files from local disk** +The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") +dfd.read_json("user_names.json") .then(df => { df.head().print() @@ -97,70 +36,6 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple {% tab title="Browser" %} ```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - ``` {% endtab %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 9fd06ff..e412af9 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29%20%282%29.png) +![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index b9d73a8..397b480 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,11 +44,12 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + + ``` ![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) diff --git a/api-reference/series/README.md b/api-reference/series/README.md index 8886e37..cc25049 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -18,7 +18,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | | [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | | [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`]() | Return the number of elements in the underlying data. | +| [`Series.size`](series.size.md) | Return the number of elements in the underlying data. | ### Conversion @@ -49,7 +49,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise \(binary operator ge\). | | [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise \(binary operator ne\). | | [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise \(binary operator eq\). | -| [`Series.dot`]() | Compute the dot product between the Series and the columns of other. | +| [`Series.dot`](series.dot.md) | Compute the dot product between the Series and the columns of other. | ### Function application & GroupBy @@ -61,7 +61,7 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | | :--- | :--- | -| [`Series.corr`]() | Compute correlation with other Series, excluding missing values. | +| [`Series.corr`](series.corr.md) | Compute correlation with other Series, excluding missing values. | | [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | | [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | | [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index c241eae..db9a8b4 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,31 +4,9 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] +> danfo.Series.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation in-place - or not. Defaults to false -

{

-

inplace: false

-

}

-
+**Parameters**: None **Returns:** Series diff --git a/api-reference/series/series.add.md b/api-reference/series/series.add.md index 9632650..edde21c 100644 --- a/api-reference/series/series.add.md +++ b/api-reference/series/series.add.md @@ -4,37 +4,11 @@ description: 'Return Addition of series and other, element-wise (binary operator # Series.add -> danfo.Series.add\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)\] - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+> danfo.Series.add\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\| | values | | **Return:** Series diff --git a/api-reference/series/series.apply.md b/api-reference/series/series.apply.md index 9d0407b..f32717f 100644 --- a/api-reference/series/series.apply.md +++ b/api-reference/series/series.apply.md @@ -1,40 +1,14 @@ --- -description: Invoke a function on each value in a Series. +description: invoke a function on Series Value --- # Series.apply -> danfo.series.**apply**\(callable, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
callableFunctionFunction (can be anonymous) to apply
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function | Function \(can be anonymous\) to apply | | **Returns:** diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 8926e7f..29c19e3 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -4,30 +4,11 @@ description: Return the integer indices that would sort the Series values # Series.argsort -> danfo.Series.**argsort**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] +> danfo.Series.**argsort**\(ascending\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectascending: How to sort the indices -

{ -
ascending: true

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| ascending | boolean | How to sort the indices. either **True** or **False** | true | **Returns:** Series \(int element\) @@ -41,9 +22,7 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - +sf.argsort().print() ``` {% endtab %} {% endtabs %} @@ -70,25 +49,6 @@ sf.argsort({ ascending: false }).print() ╟───┼──────────────────────╢ ║ 7 │ 1 ║ ╚═══╧══════════════════════╝ - -//sorted in descending order -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 6 ║ -╟───┼───╢ -║ 2 │ 4 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╟───┼───╢ -║ 6 │ 0 ║ -╟───┼───╢ -║ 7 │ 3 ║ -╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.copy.md b/api-reference/series/series.copy.md index 73220c4..323fb47 100644 --- a/api-reference/series/series.copy.md +++ b/api-reference/series/series.copy.md @@ -1,5 +1,5 @@ --- -description: Makes a deep copy of a Series +description: Make a new copy of a Series --- # Series.copy diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 78422ea..201ae11 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -4,31 +4,11 @@ description: Returns cumulative maximum over a series # Series.cummax -> danfo.Series.**cummax**\(options\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)\] +> danfo.Series.**cummax**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L825)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index d368c0c..f2337a8 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -4,31 +4,11 @@ description: Returns the cumulative min of a Series # Series.cummin -> danfo.Series.**cummin**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)\] +> danfo.Series.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L816)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 41c2898..6b72547 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -4,31 +4,11 @@ description: Return the cumulative product of a series # Series.cumprod -> danfo.Series.**cumprod**\(\)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)\] +> danfo.Series.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L834)\] -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> ->
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. style="text-align:left"> ->

{

->

inplace: false

->

}

->
+**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index db8021c..205d777 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -4,31 +4,11 @@ description: Return a cumulative sum of a series # Series.cumsum -> danfo.Series.**cumsum**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L807)\] + +**Parameters:** None + +**Return**: Series **Example** diff --git a/api-reference/series/series.div.md b/api-reference/series/series.div.md index 495eba5..4dd4fd0 100644 --- a/api-reference/series/series.div.md +++ b/api-reference/series/series.div.md @@ -6,37 +6,12 @@ description: >- # Series.div -> danfo.Series.div\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)\] +> danfo.Series.div\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\| | values | | +| round | bool | specify if to round off the floating number | true | **Return:** Series @@ -76,7 +51,7 @@ sf1.div(sf2).print() {% endtab %} {% endtabs %} -### divide with a value +divide with a value {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index eae885c..d5fd7e2 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -4,39 +4,18 @@ description: Remove duplicate rows # Series.drop\_duplicates -> danfo.Series.**drop\_duplicates**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectkeep: "first" | "last", which duplicate value - to keep. Defaults to "first". -
inplace: Boolean indicating whether to perform the operation in-place - or not. Defaults to false
-

{

-

inplace: false

-

}

-
+> danfo.Series.**drop\_duplicates**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | +| kwargs\["**keep**"\] | String | {"**first**"or "**last**"}. Specify if to keep the last or the first duplicate value | first | **Returns:** Series **Examples** -### Drop duplicate by keeping the first occurrence of the duplicate value +Drop duplicate by keeping the first value of the duplicate value {% tabs %} {% tab title="Node" %} @@ -72,7 +51,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -### Drop duplicate and keep only the last duplicated value +Drop duplicate and keep only the last duplicated value {% tabs %} {% tab title="Node" %} @@ -108,7 +87,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -### Remove duplicate value in-place +Remove duplicate value in series without returning a new series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 8e3a4be..6fa1100 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -4,37 +4,17 @@ description: Remove missing values from Series # Series.dropna -> danfo.Series.**dropna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{ -
inplace: false

-

}

-
+> danfo.Series.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | **Returns**: Series **Examples** -### Drop all nan value and then return New Series. +Drop all nan value and then return New Series. {% tabs %} {% tab title="Node" %} @@ -72,7 +52,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -### Drop nan values in-place +Drop nan values without returning new series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 3e4fd5c..09334c1 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -17,7 +17,7 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) +let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) let sf = new dfd.Series(data) sf.dt.day().print() @@ -32,26 +32,26 @@ sf.dt.day().print() {% endtabs %} ```text -╔═══╤═══╗ -║ 0 │ 6 ║ -╟───┼───╢ -║ 1 │ 0 ║ -╟───┼───╢ -║ 2 │ 1 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 4 ║ -╟───┼───╢ -║ 6 │ 5 ║ -╟───┼───╢ -║ 7 │ 6 ║ -╟───┼───╢ -║ 8 │ 0 ║ -╟───┼───╢ -║ 9 │ 1 ║ -╚═══╧═══╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╟───┼──────────────────────╢ +║ 5 │ 4 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 0 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 8b9287f..1243049 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -22,7 +22,7 @@ let sf = new dfd.Series(data) // print series sf.print() // print hour series -sf.dt.hours().print() +sf.dt.hour().print() ``` {% endtab %} @@ -37,17 +37,21 @@ sf.dt.hours().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 2:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╚═══╧═══╝ - +//print hour series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index a1b449f..0e6dedb 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -32,18 +32,20 @@ sf.dt.month().print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 6 ║ -╟───┼────╢ -║ 1 │ 7 ║ -╟───┼────╢ -║ 2 │ 9 ║ -╟───┼────╢ -║ 3 │ 9 ║ -╟───┼────╢ -║ 4 │ 11 ║ -╟───┼────╢ -║ 5 │ 11 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 7 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 9 ║ +╟───┼──────────────────────╢ +║ 4 │ 11 ║ +╟───┼──────────────────────╢ +║ 5 │ 11 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index b137205..82a7d3c 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -37,6 +37,8 @@ sf.dt.month_name().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2018, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 2/1/2018, 1:00:00 AM ║ @@ -44,13 +46,16 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═════╗ -║ 0 │ Jan ║ -╟───┼─────╢ -║ 1 │ Feb ║ -╟───┼─────╢ -║ 2 │ Mar ║ -╚═══╧═════╝ +//print month name series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Jan ║ +╟───┼──────────────────────╢ +║ 1 │ Feb ║ +╟───┼──────────────────────╢ +║ 2 │ Mar ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index e52c916..1c7e556 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -37,6 +37,8 @@ sf.dt.monthday().print() {% tab title="Output" %} ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/2/2000, 1:00:00 AM ║ @@ -44,13 +46,16 @@ sf.dt.monthday().print() ║ 2 │ 1/3/2000, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╚═══╧═══╝ +//print monthdays +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index 5925e40..e6fd771 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -25,7 +25,7 @@ let sf = new dfd.Series(data) sf.print() //print the seconds obtained -sf.dt.seconds().print() +sf.seconds().print() ``` {% endtab %} @@ -41,6 +41,8 @@ sf.dt.seconds().print() ```text ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 1:00:01 AM ║ @@ -48,13 +50,16 @@ sf.dt.seconds().print() ║ 2 │ 1/1/2000, 1:00:02 AM ║ ╚═══╧══════════════════════╝ -╔═══╤═══╗ -║ 0 │ 0 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╚═══╧═══╝ +//the seconds obtained +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index 64945fa..dc79e6c 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -34,48 +34,49 @@ sf.dt.weekdays().print() {% endtabs %} ```text -╔═══╤════════════════════════╗ -║ 0 │ 12/31/2016, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 9 │ 1/9/2017, 1:00:00 AM ║ -╚═══╧════════════════════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12/31/2016, 1:00:... ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╚═══╧══════════════════════╝ -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ +//print days of the week +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Sat ║ +╟───┼──────────────────────╢ +║ 1 │ Sun ║ +╟───┼──────────────────────╢ +║ 2 │ Mon ║ +╟───┼──────────────────────╢ +║ 3 │ Tue ║ +╟───┼──────────────────────╢ +║ 4 │ Wed ║ +╟───┼──────────────────────╢ +║ 5 │ Thu ║ +╟───┼──────────────────────╢ +║ 6 │ Fri ║ +╟───┼──────────────────────╢ +║ 7 │ Sat ║ +╟───┼──────────────────────╢ +║ 8 │ Sun ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index c6a4040..a594255 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -28,6 +28,8 @@ sf.dt.year().print() ```text //print date time series ╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2001, 1:00:00 AM ║ @@ -35,12 +37,15 @@ sf.dt.year().print() ║ 2 │ 1/1/2002, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤══════╗ -║ 0 │ 2000 ║ -╟───┼──────╢ -║ 1 │ 2001 ║ -╟───┼──────╢ -║ 2 │ 2002 ║ -╚═══╧══════╝ +//print the year series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2000 ║ +╟───┼──────────────────────╢ +║ 1 │ 2001 ║ +╟───┼──────────────────────╢ +║ 2 │ 2002 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 9e8a9c3..341dbb9 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -8,7 +8,7 @@ description: Check all the values in a series is equal to another value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value to compare | | +| other | Series**\|** int\|String\|float | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index f14e5d3..b1bea1b 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -4,38 +4,18 @@ description: Replace all NaN value with specified value # Series.fillna -> danfo.Series.**fillna**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObject -

value: The value to replace all missing value with.

-

inplace: Boolean indicating whether to perform the operation inplace - or not. Defaults to false

-
-

{

-

inplace: false

-

}

-
+> danfo.Series.**fillna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**value**"\] | int \| String\| bool | value to replace the NaN values | | +| kwargs\["**inplace**"\] | bool | return a new series or not. | false | + +**Returns:** Series **Examples** -### Fill nan value and then return new series +Fill nan value and then return new series {% tabs %} {% tab title="Node" %} @@ -82,7 +62,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -### Fill nan value in-place +Fill nan value without returning new Series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index a7c0ead..b3d8b69 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is greater than or equal a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index 98eb444..a98f618 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -8,7 +8,7 @@ description: Check if all the value in a series is greater than a value | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index 195677a..e580803 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -4,7 +4,7 @@ danfo.Series.**iloc**\(\) \[[source](https://github.com/opensource9ja/danfojs/bl | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | +| rows | Array | Array, slice or index of row position to return | | **Returns:** @@ -18,10 +18,9 @@ Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. -* A boolean mask. E.g \[ true, false, false \] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only ****the start label is included, and the end label is ignored._ +_**Note:** only ****the start label is included._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -31,6 +30,7 @@ _**Note:** only ****the start label is included, and the end label is ignored._ {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +// const tf = require("@tensorflow/tfjs-node") let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) @@ -62,7 +62,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[0: 5\]". This will return all values from index positions 0 to 4. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. {% tabs %} {% tab title="Node" %} @@ -136,27 +136,5 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} -### Slice Series by boolean condition -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index 0dde01a..e9056d7 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -8,7 +8,7 @@ description: Check if all the values in a series is less than or equal to a valu | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns:** Series \(Boolean Element\) diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index 73c45d1..bb18486 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -8,7 +8,7 @@ description: Check if all values in a Series are less than a value. | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value\(s\) to compare | | +| other | Series**\|** int\|float | value\(s\) to compare | | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.map.md b/api-reference/series/series.map.md index c992de7..1071a1f 100644 --- a/api-reference/series/series.map.md +++ b/api-reference/series/series.map.md @@ -1,51 +1,25 @@ --- -description: Map the value of a series to a function or Object +description: Map the value of a series to it representation --- # Series.map > danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParameterTypeDescriptionDefault
callableFunction or ObjectA function or object({})
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+| Parameter | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function or Object | callable can either be a function or an object\({}\) | | **Example** -Mapping the element in a Series words in an Object +Mapping the element in a Series to a word {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let sf = new dfd.Series([1, 2, 3, 4]) +let sf = new dfd.Series([1,2,3,4]) let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } sf.map(map).print() diff --git a/api-reference/series/series.mod.md b/api-reference/series/series.mod.md index 1dee05d..59a0320 100644 --- a/api-reference/series/series.mod.md +++ b/api-reference/series/series.mod.md @@ -4,37 +4,11 @@ description: 'Return Modulo of series and other, element-wise (binary operator m # Series.mod -> danfo.Series.mod\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)\] +> danfo.Series.mod\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|floatvalues
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\|float | values | | **Return:** Series diff --git a/api-reference/series/series.mul.md b/api-reference/series/series.mul.md index 463d52e..855173b 100644 --- a/api-reference/series/series.mul.md +++ b/api-reference/series/series.mul.md @@ -4,37 +4,11 @@ description: 'Return Multiplication of series and other, element-wise (binary op # Series.mul -> danfo.Series.mul\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)\] - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+> danfo.Series.mul\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\| | values | | **Return:** Series diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index fcf182a..9901dcd 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -8,7 +8,7 @@ description: Check if all values in a series is not equal to a value(s) | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| other | Series, Array or number | value to compare | | +| other | Series**\|** int\|String\|float | value to compare | | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 42f678d..8ddafe4 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -1,5 +1,5 @@ --- -description: Returns the number of unique values in a series +description: Obtain the number of unique values in a series --- # Series.nunique diff --git a/api-reference/series/series.pow.md b/api-reference/series/series.pow.md index e113ffe..6a67b3b 100644 --- a/api-reference/series/series.pow.md +++ b/api-reference/series/series.pow.md @@ -6,37 +6,11 @@ description: >- # Series.pow -> danfo.Series.pow\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)\] +> danfo.Series.pow\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\| | values | | **Return:** Series diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index cf1dd06..4b49fa2 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,41 +4,19 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObject -

oldValue: The value you want to replace

-

newValue: The new value you want to replace the old value with

-

inplace: Boolean indicating whether to perform the operation inplace - or not

-
-

{

-

inplace: false

-

}

-
+> danfo.Series.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["**replace**"\] | int \| String\| bool | value to be replaced | | +| kwargs\["**with**"\] | int \| String \| bool | value to replace the previous value | | +| kwargs\["**inplace**"\] | Bool | mutate the series or create the new series | false | **Returns**: Series **Examples** -### Replace a value in a series and return a new series +Replace a value in a series and return a new series {% tabs %} {% tab title="Node" %} @@ -47,7 +25,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) +let sf_rep = sf.replace({ replace: 10, with: -50 }) sf_rep.print() ``` @@ -57,27 +35,28 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -50 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ -50 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -### Replace a value in-place +Replace a value in a series , with out returning a new series {% tabs %} {% tab title="Node" %} @@ -86,7 +65,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) +sf.replace({ replace: 10, with: -50, inplace:true }) sf.print() ``` @@ -94,21 +73,22 @@ sf.print() {% endtabs %} ```text -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -50 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ -50 ║ +╚═══╧══════════════════════╝ ``` diff --git a/api-reference/series/series.reset_index.md b/api-reference/series/series.reset_index.md index 620904c..e03ea87 100644 --- a/api-reference/series/series.reset_index.md +++ b/api-reference/series/series.reset_index.md @@ -4,28 +4,66 @@ description: Reset the index of a series. # Series.reset\_index -> danfo.series.reset\_index\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] +> danfo.series.reset\_index\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] + +Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | +| kwargs | Object | kwargs is an object {} with key **inplace** with a boolean value. e.g {inplace: false} | inplace:false | **Returns :** Series -`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let sf = new dfd.Series(data) +let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) +let sf_reset = sf_new.reset_index() +sf_reset.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} -### **Reset index to default values** +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ {"alpha":"A","cou... ║ +╟───┼──────────────────────╢ +║ 1 │ {"alpha":"B","cou... ║ +╟───┼──────────────────────╢ +║ 2 │ {"alpha":"C","cou... ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = [20, 30, 40] -let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) -sf.print() +let data = [1,2,3,4,5,6] +let sf = new dfd.Series(data) + +sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) let sf_reset = sf.reset_index() sf_reset.print() + ``` {% endtab %} @@ -39,37 +77,38 @@ sf_reset.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════╗ -║ a │ 20 ║ -╟───┼────╢ -║ b │ 30 ║ -╟───┼────╢ -║ c │ 40 ║ -╚═══╧════╝ - -╔═══╤════╗ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 2 │ 40 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 6 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -### Reset index to new values in-place +Reset index without returning a new Series {% tabs %} {% tab title="Node" %} ```javascript -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) -sf.print() +const dfd = require("danfojs-node") -sf.reset_index({ inplace: true }) -sf.print() +let data = [1,2,3,4,5,6] +let sf = new dfd.Series(data) +sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +sf.reset_index({"inplace":true}) +sf.print() ``` {% endtab %} @@ -83,33 +122,21 @@ sf.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╟───┼───╢ -║ f │ 6 ║ -╚═══╧═══╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 4 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 6 ║ -╚═══╧═══╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 6 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.round.md b/api-reference/series/series.round.md index acb6726..3dcc39f 100644 --- a/api-reference/series/series.round.md +++ b/api-reference/series/series.round.md @@ -4,37 +4,11 @@ description: round off floating values in series # Series.round -> danfo.Series.round\(dp, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)\] +> danfo.Series.round\(dp\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
dpintdecimal place to round off to
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| dp | int | decimal place to round off to | | **Returns:** Series diff --git a/api-reference/series/series.sample.md b/api-reference/series/series.sample.md index 7e91ca4..4ab195e 100644 --- a/api-reference/series/series.sample.md +++ b/api-reference/series/series.sample.md @@ -6,36 +6,10 @@ description: Return a random sample of items from an axis of object. > danfo.Series.sample\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
numIntThe number of rows to return.
optionsObjectseed: An integer specifying the random seed that will be used to - create the distribution. Ensures reproducibility of generated samples. -

{

-

seed: 1

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | +| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | **Returns:** @@ -59,34 +33,20 @@ load_data() {% tabs %} {% tab title="Output" %} ```javascript -╔═══╤════╗ -║ 2 │ 3 ║ -╟───┼────╢ -║ 4 │ 5 ║ -╟───┼────╢ -║ 0 │ 1 ║ -╟───┼────╢ -║ 7 │ 40 ║ -╟───┼────╢ -║ 6 │ 30 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 7 │ 40 ║ +╟───┼──────────────────────╢ +║ 6 │ 30 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -### Specify a seed when sampling - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5, { seed: 2 }) - sample.print() - -} -load_data() - -``` - diff --git a/api-reference/series/series.set_index.md b/api-reference/series/series.set_index.md index 57abe40..91adf23 100644 --- a/api-reference/series/series.set_index.md +++ b/api-reference/series/series.set_index.md @@ -4,37 +4,12 @@ description: Assign new Index to Series # Series.set\_index -> danfo.series.**set\_index\(**options**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)\] - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterTypeDescriptionDefault
indexArraynew index values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["index"\] | Array | index to replace the former index | | +| kwargs\["inplace"\] | Boolean | return new series or not | false | **Returns:** Series @@ -44,10 +19,9 @@ description: Assign new Index to Series {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") + let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] let sf = new dfd.Series(data) -sf.print() - let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) sf_new.print() ``` @@ -63,21 +37,15 @@ sf_new.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═════════════════════════╗ -║ 0 │ {"alpha":"A","count":1} ║ -╟───┼─────────────────────────╢ -║ 1 │ {"alpha":"B","count":2} ║ -╟───┼─────────────────────────╢ -║ 2 │ {"alpha":"C","count":3} ║ -╚═══╧═════════════════════════╝ - -╔═══════╤═════════════════════════╗ -║ one │ {"alpha":"A","count":1} ║ -╟───────┼─────────────────────────╢ -║ two │ {"alpha":"B","count":2} ║ -╟───────┼─────────────────────────╢ -║ three │ {"alpha":"C","count":3} ║ -╚═══════╧═════════════════════════╝ +╔═══════╤══════════════════════╗ +║ │ 0 ║ +╟───────┼──────────────────────╢ +║ one │ {"alpha":"A","cou... ║ +╟───────┼──────────────────────╢ +║ two │ {"alpha":"B","cou... ║ +╟───────┼──────────────────────╢ +║ three │ {"alpha":"C","cou... ║ +╚═══════╧══════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -121,16 +89,16 @@ sf_new.print() {% endtab %} {% endtabs %} -### Set index in-place +set index without creating a new series by using `inplace = true` {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs") -let data = [1, 2, 3, 4, 5, 6] +let data = [1,2,3,4,5,6] let sf = new dfd.Series(data) -sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) +sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) sf.print() ``` {% endtab %} @@ -145,20 +113,21 @@ sf.print() {% tabs %} {% tab title="Output" %} ```text -╔═══════╤═══╗ -║ one │ 1 ║ -╟───────┼───╢ -║ two │ 2 ║ -╟───────┼───╢ -║ three │ 3 ║ -╟───────┼───╢ -║ four │ 4 ║ -╟───────┼───╢ -║ five │ 5 ║ -╟───────┼───╢ -║ six │ 6 ║ -╚═══════╧═══╝ - +╔═══════╤══════════════════════╗ +║ │ 0 ║ +╟───────┼──────────────────────╢ +║ one │ 1 ║ +╟───────┼──────────────────────╢ +║ two │ 2 ║ +╟───────┼──────────────────────╢ +║ three │ 3 ║ +╟───────┼──────────────────────╢ +║ four │ 4 ║ +╟───────┼──────────────────────╢ +║ five │ 5 ║ +╟───────┼──────────────────────╢ +║ six │ 6 ║ +╚═══════╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.sort_values.md b/api-reference/series/series.sort_values.md index 35012f7..54966ac 100644 --- a/api-reference/series/series.sort_values.md +++ b/api-reference/series/series.sort_values.md @@ -1,43 +1,21 @@ --- -description: Sorts a Series in ascending or descending order +description: Sort a Series in ascending or descending order --- # Series.sort\_values -> danfo.Series.sort\_values\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObject -

inplace: Boolean indicating whether to perform the operation in-place - or not. Defaults to false

-

ascending: Whether to return sorted values in ascending order or - not. Defaults to true

-
-

{ -
ascending: true,

-

inplace: false

-

}

-
+> danfo.Series.sort\_values\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs\["inplace"\] | Boolean | return new series or not | false | +| kwargs\["ascending"\] | Boolean | select if to sort by ascending or descending | true | **Return:** Series -### Sort values in a Series +**Examples** + +Sort series values using the default settings {% tabs %} {% tab title="Node" %} @@ -56,30 +34,32 @@ sf2.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 7 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 8 │ 4 ║ +╟───┼──────────────────────╢ +║ 0 │ 20 ║ +╟───┼──────────────────────╢ +║ 1 │ 30 ║ +╟───┼──────────────────────╢ +║ 5 │ 57 ║ +╟───┼──────────────────────╢ +║ 6 │ 89 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -### Sort Series in-place +Sort series value without returning a new series {% tabs %} {% tab title="Node" %} @@ -88,7 +68,7 @@ const dfd = require("danfojs-node") let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] let sf1 = new dfd.Series(data1) -sf1.sort_values({ inplace: true }) +sf1.sort_values({ "inplace": true }) sf1.print() ``` @@ -98,31 +78,32 @@ sf1.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ - +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 7 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 8 │ 4 ║ +╟───┼──────────────────────╢ +║ 0 │ 20 ║ +╟───┼──────────────────────╢ +║ 1 │ 30 ║ +╟───┼──────────────────────╢ +║ 5 │ 57 ║ +╟───┼──────────────────────╢ +║ 6 │ 89 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -Sort Series values in descending order +Sort series value in descending order {% tabs %} {% tab title="Node" %} @@ -141,25 +122,27 @@ sf1.print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════╗ -║ 6 │ 89 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 7 │ 0 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 6 │ 89 ║ +╟───┼──────────────────────╢ +║ 5 │ 57 ║ +╟───┼──────────────────────╢ +║ 1 │ 30 ║ +╟───┼──────────────────────╢ +║ 0 │ 20 ║ +╟───┼──────────────────────╢ +║ 8 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 7 │ 0 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.capitalize.md b/api-reference/series/series.str.capitalize.md index 10483b3..5df261a 100644 --- a/api-reference/series/series.str.capitalize.md +++ b/api-reference/series/series.str.capitalize.md @@ -4,31 +4,9 @@ description: Capitalize the first character of each string # Series.str.capitalize -> danfo.Series.str.**capitalize**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] +> danfo.Series.str.**capitalize**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.charat.md b/api-reference/series/series.str.charat.md index 9cb1d66..3df2bbc 100644 --- a/api-reference/series/series.str.charat.md +++ b/api-reference/series/series.str.charat.md @@ -6,35 +6,9 @@ description: Obtain the character at the specified index (position) > danfo.Series.str.**charAt**\(index\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
indexintthe index at which to obtain the character0
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| index | int | the index at which to obtain the character | 0 | **Returns**: Series \(Character element\) diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index b27bc00..0a24597 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -4,46 +4,12 @@ description: Joins two or more strings/arrays # Series.str.concat -> danfo.Series.str.**concat**\(other, position, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherstring or Arraystring or list of strings to add to each string element of the series""
positionIntThe position to add the other (string or array) is either 0 or 1. - 0 is to add the other at the beginning of each of the string element, and - 1 is to add to the end of the string element1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.str.**concat**\(other, position\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | string or Array | string or list of strings to add to each string element of the series | "" | +| position | Int | The position to add the **other** \(string or array\) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | **Returns:** Series \(String element\) diff --git a/api-reference/series/series.str.endswith.md b/api-reference/series/series.str.endswith.md index 18753cb..645294d 100644 --- a/api-reference/series/series.str.endswith.md +++ b/api-reference/series/series.str.endswith.md @@ -4,37 +4,11 @@ description: Checks whether a string ends with specified characters # Series.str.endsWith -> danfo.Series.str.**endsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] +> danfo.Series.str.**endsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns**: Series \(Boolean element\) diff --git a/api-reference/series/series.str.includes.md b/api-reference/series/series.str.includes.md index cfa9c16..c2cb4af 100644 --- a/api-reference/series/series.str.includes.md +++ b/api-reference/series/series.str.includes.md @@ -4,37 +4,11 @@ description: Checks whether a string contains the specified string/characters # Series.str.includes -> danfo.Series.str.includes\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] +> danfo.Series.str.includes\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns**: Series \(boolean element\) diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index fe93a74..a823d20 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -4,37 +4,11 @@ description: the position of the first found occurrence of a specified value in # Series.str.indexOf -> danfo.Series.str.indexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] +> danfo.Series.str.indexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe string to obtain its index""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the string to obtain its index | "" | **Returns:** Series diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index a32c1bb..4c17295 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -4,43 +4,12 @@ description: Join a new string value to all string elements in a Series. # Series.str.join -> danfo.Series.str.**join**\(valToJoin, joinChar, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] +> danfo.Series.str.**join**\(valToJoin,joinChar\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
valToJoinStringthe string value you want to""
joinCharStringThe delimiter to specify the joining" "
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| valToJoin | String | the string value you want to | "" | +| joinChar | String | The delimiter to specify the joining | " " | **Returns:** @@ -69,15 +38,17 @@ sf.str.join("new", "_").print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤════════════════════════╗ -║ 0 │ lower part_new ║ -╟───┼────────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼────────────────────────╢ -║ 2 │ this is a sentence_new ║ -╟───┼────────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧════════════════════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower part_new ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentenc... ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.lastindexof.md b/api-reference/series/series.str.lastindexof.md index d2bfa98..130c50c 100644 --- a/api-reference/series/series.str.lastindexof.md +++ b/api-reference/series/series.str.lastindexof.md @@ -6,37 +6,11 @@ description: >- # Series.str.lastIndexOf -danfo.Series.str.lastIndexOf\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] +danfo.Series.str.lastIndexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the string to search for | "" | **Returns**: Series diff --git a/api-reference/series/series.str.len.md b/api-reference/series/series.str.len.md index be82b70..60153e8 100644 --- a/api-reference/series/series.str.len.md +++ b/api-reference/series/series.str.len.md @@ -4,31 +4,13 @@ description: Obtain the length of each string element in a Series # Series.str.len -> danfo.Series.str.**len**\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] +> danfo.Series.str.**len**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters**: None + +**Returns:** + + return Series **Examples** @@ -39,7 +21,7 @@ Returns the length \(number of character\) of a string, and also return the leng ```javascript const dfd = require("danfojs-node") -let data = ["dog", 5,"cat","fog","mug","animals"] +let data = ["dog", 5,"cat",["fog","mug"],"animals"] let sf = new dfd.Series(data) sf.str.len().print() ``` @@ -55,19 +37,19 @@ sf.str.len().print() {% tabs %} {% tab title="Output" %} ```text -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╚═══╧═══╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ NaN ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 7 ║ +╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index 2f1d49b..e6c1f32 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -4,37 +4,11 @@ description: Repeat the the character(s) in a string for a specified number of t # Series.str.repeat -> danfo.Series.str.**repeat**\(num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] +> danfo.Series.str.**repeat**\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
numintegerthe string to search for1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| num | integer | the string to search for | 1 | **Returns:** Series diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index 0950071..c96137c 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,43 +4,12 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace\(searchValue, replaceValue, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] +> danfo.Series.str.replace\(searchValue, replaceValue\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
searchValuestringString | Character value to replace. Supports regex.""
replaceValueStringstring to replace the searched string""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| searchValue | string | the string to search for | "" | +| replaceValue | String | string to replace the searched string | "" | **Returns:** Series diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 4367ae8..8824095 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -4,39 +4,13 @@ description: Obtain the index position of a searched character in a String # Series.str.search -> danfo.Series.str.**search**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strStringthe string to search for""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+> danfo.Series.str.**search**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] + + + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | String | the string to search for | "" | **Returns:** diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index e843eb8..d314066 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -4,43 +4,12 @@ description: Obtain the substring of each element in a series # Series.str.slice -> danfo.Series.str.slice\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] +> danfo.Series.str.slice\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | **Returns:** diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 4b88313..65a82c7 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,12 +6,11 @@ description: >- # Series.str.split -> danfo.Series.str.**split**\(splitVal, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)\] +> danfo.Series.str.**split**\(splitVal\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L250)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | | splitVal | String | separator or delimiter used to split the string | " " | -| options | Object | **inplace**: Whether to perform operation in-place or not. | { inplace: false } | **Returns** diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index c141afd..311bb2f 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -4,37 +4,11 @@ description: Test whether a string begins with specified characters # Series.str.startsWith -> danfo.Series.str.**startsWith**\(str, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] +> danfo.Series.str.**startsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
strstringthe character(s) to check""
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| str | string | the character\(s\) to check | "" | **Returns:** Series \(Boolean element\) diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index 8869806..1512f02 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -6,44 +6,12 @@ description: >- # Series.str.substr -> danfo.Series.str.substr\(startIndex, num, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] +> danfo.Series.str.substr\(startIndex, num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
numNumberThe number of character to obtain starting from the startIndex1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| num | Number | The number of character to obtain starting from the startIndex | 1 | **Returns:** diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 7515af0..73ab3a8 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -4,43 +4,12 @@ description: Obtain the substring of each element in a series # Series.str.substring -> danfo.Series.str.**substring**\(startIndex, endIndex, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] +> danfo.Series.str.**substring**\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
startIndexNumberspecify the index to start obtaining the substring0
endIndexNumberspecify the index to end the substring1
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | **Returns** diff --git a/api-reference/series/series.str.tolowercase.md b/api-reference/series/series.str.tolowercase.md index 9dfb12f..ada457b 100644 --- a/api-reference/series/series.str.tolowercase.md +++ b/api-reference/series/series.str.tolowercase.md @@ -4,31 +4,11 @@ description: Converts all characters to lower case. # Series.str.toLowerCase -> danfo.Series.str.toLowerCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] +> danfo.Series.str.toLowerCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None + +**Returns**: Series \(String element\) **Example** diff --git a/api-reference/series/series.str.touppercase.md b/api-reference/series/series.str.touppercase.md index 4f630ae..7e23c08 100644 --- a/api-reference/series/series.str.touppercase.md +++ b/api-reference/series/series.str.touppercase.md @@ -4,31 +4,9 @@ description: Converts all characters to uppercase. # Series.str.toUpperCase -> danfo.Series.str.toUpperCase\(options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] +> danfo.Series.str.toUpperCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns**: Series \(String element\) diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index 181c004..7e30db5 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -4,31 +4,9 @@ description: Remove leading and trailing Whitespace from a String element # Series.str.trim -> danfo.Series.str.**trim**\(options\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** +> danfo.Series.str.**trim**\(\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
optionsObjectinplace: Whether to perform the operation in-place or not. -

{

-

inplace: false

-

}

-
+**Parameters:** None **Returns:** diff --git a/api-reference/series/series.sub.md b/api-reference/series/series.sub.md index d9f1d7d..95da267 100644 --- a/api-reference/series/series.sub.md +++ b/api-reference/series/series.sub.md @@ -4,37 +4,11 @@ description: 'Return Subtraction of series and other, element-wise (binary opera # Series.sub -> danfo.Series.sub\(other, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)\] - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
otherSeries|int|values
optionsObjectinplace: Boolean indicating whether to perform the operation inplace or - not. Defaults to false -

{

-

inplace: false

-

}

-
+> danfo.Series.sub\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series\|int\| | values | | **Return:** Series diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 48b3b1c..66dd124 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -9,7 +9,9 @@ description: >- > The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. + + +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -17,9 +19,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -## Setting up your environment +### Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -29,9 +31,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update \(14th Feb 2021\):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -44,7 +46,7 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -## Loading and processing your data +### Loading and processing your data To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. @@ -52,11 +54,11 @@ Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` @@ -78,7 +80,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -108,7 +110,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -118,7 +120,7 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: @@ -136,6 +138,7 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -156,6 +159,7 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: ```text + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -179,7 +183,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -189,7 +193,7 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. ```text ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -246,11 +250,11 @@ async function load_process_data() { load_process_data() ``` -## Model Building With Tensorflow.js +### Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -264,11 +268,12 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript + async function train() { const model = get_model() const data = await load_process_data() @@ -280,7 +285,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -293,15 +298,15 @@ async function train() { } } }); - + } ``` This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -388,6 +393,7 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: ```text + Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -413,13 +419,13 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 diff --git a/getting-started.md b/getting-started.md index f5f99a2..273631b 100644 --- a/getting-started.md +++ b/getting-started.md @@ -80,9 +80,9 @@ const dfd = require("danfojs-node") {% endtab %} {% endtabs %} -### Object creation +### Creating a DataFrame/Series -Creating a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting danfo.js create a default integer index: +You can create a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting Danfo.js create a default integer index: {% tabs %} {% tab title="Node" %} From 24ec3b84e9f1e346a7b2aa159bc2e526d3b554d6 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 16:01:58 +0000 Subject: [PATCH 027/202] GitBook: [master] 212 pages modified --- SUMMARY.md | 1 + .../dataframe/creating-a-dataframe.md | 57 +- api-reference/series/creating-a-series.md | 172 ++++++ getting-started.md | 559 ++++++++---------- 4 files changed, 474 insertions(+), 315 deletions(-) create mode 100644 api-reference/series/creating-a-series.md diff --git a/SUMMARY.md b/SUMMARY.md index 47af443..9752ec2 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -21,6 +21,7 @@ * [danfo.to\_excel](api-reference/input-output/danfo.to_excel.md) * [danfo.to\_json](api-reference/input-output/danfo.to_json.md) * [Series](api-reference/series/README.md) + * [Creating a Series](api-reference/series/creating-a-series.md) * [Series.append](api-reference/series/series.append.md) * [Series.cumsum](api-reference/series/series.cumsum.md) * [Series.cummax](api-reference/series/series.cummax.md) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index 29d0fc2..85a6d55 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -52,6 +52,61 @@ df.print() {% endtab %} {% endtabs %} +### Creating a `DataFrame` from an array of array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] +let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + ### Creating a `DataFrame` from a 2D tensor {% tabs %} @@ -122,7 +177,7 @@ df.ctypes.print() ╚═══╧══════════════════════╝ ``` -### Creating a `DataFrame` from a dictionary of objects with the same length +### Creating a `DataFrame` from an object {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md new file mode 100644 index 0000000..da079d5 --- /dev/null +++ b/api-reference/series/creating-a-series.md @@ -0,0 +1,172 @@ +# Creating a Series + +In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. + +### Creating a Series from an object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```javascript +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series from an array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = ["bval1", "bval2", "bval3", "bval4"] +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series and specifying index and dtypes + +You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. + +> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2, 3, 4, 5]; +let index = ["a", "b", "c", "d", "e"]; +let dtypes = ["int32",] + +let df = new Series(data1, { index, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╚═══╧═══╝ +``` + +### Creating a Series and specifying memory mode + +To use less space on Series creation, you can set the low memory mode as demonstrated below: + +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2.3, 3, 4, 5, "girl"]; + +let df = new Series(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the Series. +{% endhint %} + diff --git a/getting-started.md b/getting-started.md index 273631b..a88f855 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,43 +8,27 @@ description: >- ## Installation -There are three ways to install and use Danfo.js in your application - -For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: +There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: ```text npm install danfojs-node - -or - -yarn add danfojs-node -``` - -For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: - -```text -npm install danfojs - -or - -yarn add danfojs ``` -For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1&path=lib): +You can also install and use it in the browsers by using the CDN below: ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. +We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -61,7 +45,7 @@ const dfd = require("danfojs-node") - + @@ -80,9 +64,9 @@ const dfd = require("danfojs-node") {% endtab %} {% endtabs %} -### Creating a DataFrame/Series +### Object creation -You can create a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting Danfo.js create a default integer index: +Creating a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting danfo.js create a default integer index: {% tabs %} {% tab title="Node" %} @@ -130,7 +114,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ undefined ║ +║ 3 │ NaN ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -184,15 +168,17 @@ s.print() {% endtabs %} ```text -╔═══╤════╗ -║ 0 │ 12 ║ -╟───┼────╢ -║ 1 │ 34 ║ -╟───┼────╢ -║ 2 │ 56 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╚═══╧════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -400,17 +386,19 @@ df.ctypes.print() ```text //output -╔═══╤═════════╗ -║ A │ string ║ -╟───┼─────────╢ -║ B │ string ║ -╟───┼─────────╢ -║ C │ int32 ║ -╟───┼─────────╢ -║ D │ float32 ║ -╟───┼─────────╢ -║ E │ string ║ -╚═══╧═════════╝ +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ string ║ +╟───┼──────────────────────╢ +║ B │ string ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ float32 ║ +╟───┼──────────────────────╢ +║ E │ string ║ +╚═══╧══════════════════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -717,23 +705,19 @@ df.describe().print() ```text //output in console -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ +╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Sorting by values \(Defaults to ascending\): @@ -788,17 +772,15 @@ df.print() {% endtabs %} ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ -4 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47.3 │ 5 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -20 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -957,7 +939,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing: +Showing label slicing, both endpoints are _included_: ```javascript const dfd = require("danfojs-node") @@ -988,15 +970,17 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - + Shape: (3,2) -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1042,13 +1026,15 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1092,11 +1078,13 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1115,62 +1103,17 @@ sub_df.print() ``` ```text -╔════════════╤═══════════════════╗ -║ │ Count ║ -╟────────────┼───────────────────╢ -║ 0 │ 21 ║ -╟────────────┼───────────────────╢ -║ 1 │ 5 ║ -╟────────────┼───────────────────╢ -║ 2 │ 30 ║ -╟────────────┼───────────────────╢ -║ 3 │ 10 ║ -╚════════════╧═══════════════════╝ -``` - -#### Selection with Boolean Mask - -You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. - -```javascript -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) - -let sub_df = df.iloc({ rows: df["Count"].gt(10) }) -sub_df.print() -``` - -```text -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. - -```javascript -let sub_df = df.iloc({ - rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), - columns: [0] -}) -sub_df.print() - -//output -╔════════════╤═══════════════════╗ -║ │ Name ║ -╟────────────┼───────────────────╢ -║ 0 │ Apples ║ -╚════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1251,7 +1194,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: +Selecting values from a DataFrame works on string columns: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1259,36 +1202,34 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -let query_df = df.query({ condition: df["B"].gt(5) }) +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) query_df.print() //after query ``` ```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let query_df = df.query({ - condition: - df["B"].gt(5).and(df["A"].lt(30)) -}) -query_df.print() //after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1308,7 +1249,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace +df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace df.print() ``` @@ -1340,7 +1281,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1368,22 +1309,22 @@ df.print() //after adding column Shape: (4,3) -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 │ 25 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 │ 35 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 │ 45 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 │ 55 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data - **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. To drop any rows that have missing data: @@ -1392,13 +1333,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropna({axis: 0}) df_drop.print() ``` {% endtab %} @@ -1439,27 +1380,27 @@ df_drop.print() ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + Shape: (1,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1467,45 +1408,44 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(1) +let df_drop = df.dropna({axis: 1}) df_drop.print() ``` ```text //Before dropping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ NaN │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 34 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔════════════╤═══════════════════╗ -║ │ C ║ -╟────────────┼───────────────────╢ -║ 0 │ 3 ║ -╟────────────┼───────────────────╢ -║ 1 │ 6 ║ -╟────────────┼───────────────────╢ -║ 2 │ 40 ║ -╟────────────┼───────────────────╢ -║ 3 │ 78 ║ -╚════════════╧═══════════════════╝ - +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ ``` Filling missing data: @@ -1515,13 +1455,13 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillna({ values: ["Apples"] }) df_filled.print() ``` @@ -1545,16 +1485,14 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", NaN], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} +let data = {"Name":["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) +let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) df_filled.print() ``` @@ -1616,7 +1554,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) +let df = new dfd.DataFrame(data) df.print() df.mean().print() //defaults to column axis ``` @@ -1670,11 +1608,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ A │ 4 ║ +║ 0 │ 4 ║ ╟───┼──────────────────────╢ -║ B │ 38.5 ║ +║ 1 │ 38.5 ║ ╟───┼──────────────────────╢ -║ C │ 31.75 ║ +║ 2 │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1728,7 +1666,7 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, { axis: 1 }) +let df_new = df.sub(sf, axis = 1) df_new.print() ``` @@ -1749,7 +1687,7 @@ df_new.print() #### Apply -Applying functions to the data along specified axis. If axis = 1 \(default\), then the specified function \(`callable)` will be called with each column data, and vice versa: +Applying JavaScript functions to the data: ```javascript const dfd = require("danfojs") @@ -1758,11 +1696,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); +function sum_vals(x) { + return x + 20 } -let df_new = df.apply(sum_vals, { axis: 1 }) +let df_new = df.apply({callable: sum_vals }) df_new.print() ``` @@ -1783,18 +1721,22 @@ df_new.print() //after applying -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 22 │ 23 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 24 │ 25 │ 26 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 40 │ 50 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 59 │ 109 │ 98 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Applying Element wise operations to the data: +Applying Tensorflow functions to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. ```javascript const dfd = require("danfojs-node") @@ -1803,11 +1745,13 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 10 +df.print() + +function log_sig(x) { + return x.logSigmoid() } -let df_new = df.apply_map(sum_vals) +let df_new = df.apply({axis: 0, callable: log_sig }) df_new.print() ``` @@ -1826,19 +1770,19 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after apply_map + //after applying -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 12 │ 13 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 14 │ 15 │ 16 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 │ 50 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 49 │ 99 │ 88 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods @@ -2325,36 +2269,29 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. ```javascript const dfd = require("danfojs-node") + let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] -} + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] + } let df = new dfd.DataFrame(data) -const csv = df.to_csv() -console.log(csv); -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH - - -df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs - - -df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version +df.to_csv().then((csv) => { + console.log(csv); +}).catch((err) => { + console.log(err); +}) ``` ```text @@ -2435,24 +2372,18 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.to_json() -console.log(json); -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] +df.to_json().then((json) => { + console.log(json); +}).catch((err) => { -const json = df.to_json({format: "row"}) -console.log(json); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} + console.log(err); +}) +``` +```text +[{"Abs":20.2,"Count":34,"country code":"NG"}, +{"Abs":30,"Count":4,"country code":"FR"}, +{"Abs":47.3,"Count":5,"country code":"GH"}] ``` From c3bdeb2f42857cb734f93fbd37b4e98c8a401c99 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 16:10:48 +0000 Subject: [PATCH 028/202] GitBook: [master] 211 pages modified --- api-reference/dataframe/README.md | 6 ++- .../dataframe/creating-a-dataframe.md | 46 +++++++++++++++++++ api-reference/series/creating-a-series.md | 38 +++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/api-reference/dataframe/README.md b/api-reference/dataframe/README.md index 4b14800..6a997c3 100644 --- a/api-reference/dataframe/README.md +++ b/api-reference/dataframe/README.md @@ -4,7 +4,11 @@ description: 'Two-dimensional, size-mutable, potentially heterogeneous tabular d # Dataframe -> [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame)\(data, {**columns:** \[ Array \], **dtypes:** \[ Array \], **index:** \[Array\]}\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L20)\] +> `DataFrame`\(data, { +> **columns:** \[ Array \], +> **dtypes:** \[ Array \], +> **index:** \[Array\], +> **options**: Object}\) ### Attributes diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index 85a6d55..dd9931b 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -1,5 +1,51 @@ +--- +description: Creates a DataFrame object from flat structure +--- + # Creating a DataFrame +new danfo.**DataFrame**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

columns: Array of column names. If not specified, column names are + auto generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. ### Creating a `DataFrame` from a JSON object: diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index da079d5..dd16a93 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -1,5 +1,43 @@ # Creating a Series +new danfo.**Series**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. ### Creating a Series from an object: From e096a13e2bbbf36c01438cbf0fb72cd5549ab536 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 3 Oct 2021 16:32:34 +0000 Subject: [PATCH 029/202] GitBook: [master] 213 pages modified --- SUMMARY.md | 1 + api-reference/configuration-options.md | 129 +++++++++++++++++++++++++ api-reference/dataframe/README.md | 6 +- 3 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 api-reference/configuration-options.md diff --git a/SUMMARY.md b/SUMMARY.md index 9752ec2..c253e10 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -179,6 +179,7 @@ * [DataFrame.ne](api-reference/dataframe/danfo.dataframe.ne.md) * [DataFrame.eq](api-reference/dataframe/danfo.dataframe.eq.md) * [DataFrame.replace](api-reference/dataframe/danfo.dataframe.replace.md) + * [Configuration Options](api-reference/configuration-options.md) * [Plotting](api-reference/plotting/README.md) * [Timeseries Plots](api-reference/plotting/timeseries-plots.md) * [Violin Plots](api-reference/plotting/violin-plots.md) diff --git a/api-reference/configuration-options.md b/api-reference/configuration-options.md new file mode 100644 index 0000000..d1ea96b --- /dev/null +++ b/api-reference/configuration-options.md @@ -0,0 +1,129 @@ +--- +description: >- + This section describes all user configurable options available on + DataFrame/Series creation. +--- + +# Configuration Options + +On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. + +| Parameter | Description | +| :--- | :--- | +| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | +| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | +| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | +| lowMemoryMode | **Boolean**, whether to use minimal memory or not. Defaults to false. **Note:** There's a slight decrease in speed when low memory mode is set to true. | + +> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) + +## Examples of setting configs + +### Add a DataFrame header + +```javascript + const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] + }; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + }, + } +}); +df.print() +``` + +```javascript +╔════════════════════════════════════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟────────────┬───────────────────┬───────────────────┬───────────────────╢ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Configure column size and display format of DataFrame + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +}; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + columns: [ + { alignment: 'left' }, + { alignment: 'center', width: 20 }, + { alignment: 'right' }, + { alignment: 'justify' } + ], + }, + } +}); +df.print() +``` + +```javascript +╔══════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟───┬──────────────────────┬───────┬───────╢ +║ │ Name │ Count │ Price ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧══════════════════════╧═══════╧═══════╝ +``` + +### Configure the number of rows displayed when **print** is called + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250], + +}; +const df = new DataFrame(data, { + config: { + tableMaxColInConsole: 6, + tableMaxRow: 1 + } +}); +df.print() +``` + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference/dataframe/README.md b/api-reference/dataframe/README.md index 6a997c3..4b14800 100644 --- a/api-reference/dataframe/README.md +++ b/api-reference/dataframe/README.md @@ -4,11 +4,7 @@ description: 'Two-dimensional, size-mutable, potentially heterogeneous tabular d # Dataframe -> `DataFrame`\(data, { -> **columns:** \[ Array \], -> **dtypes:** \[ Array \], -> **index:** \[Array\], -> **options**: Object}\) +> [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame)\(data, {**columns:** \[ Array \], **dtypes:** \[ Array \], **index:** \[Array\]}\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L20)\] ### Attributes From 89ddbf7180d75c6a6df287aa9d4465337796f842 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 15:51:17 +0000 Subject: [PATCH 030/202] GitBook: No commit message --- .../dataframe/dataframe.sort_index.md | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_index.md b/api-reference/dataframe/dataframe.sort_index.md index e95017b..ed71450 100644 --- a/api-reference/dataframe/dataframe.sort_index.md +++ b/api-reference/dataframe/dataframe.sort_index.md @@ -1,39 +1,17 @@ --- description: Sort DataFrame by index --- +# DataFrame.sort_index -# DataFrame.sort\_index - -danfo.DataFrame.**sort\_index**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

ascending: Order of sorting

-

inplace: specify whether to perform the operation to the row/column - with/without creating a new DataFrame

-

}

-
{ascending: true, inplace:false}
+DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| kwargs | Object |

{

ascending: Order of sorting

inplace: specify whether to perform the operation to the row/column with/without creating a new DataFrame

}

| {**ascending**: true, **inplace:**false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -59,14 +37,13 @@ df2.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ col1 │ col2 │ col3 │ col4 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -93,5 +70,4 @@ df2.print() {% endtab %} {% endtabs %} -\*\*\*\* - +**** From 5e8ae74e21d4e49628db68ed01886f38eb29f20c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 15:52:17 +0000 Subject: [PATCH 031/202] GitBook: No commit message --- api-reference/dataframe/dataframe.sort_index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_index.md b/api-reference/dataframe/dataframe.sort_index.md index ed71450..0829afe 100644 --- a/api-reference/dataframe/dataframe.sort_index.md +++ b/api-reference/dataframe/dataframe.sort_index.md @@ -5,9 +5,9 @@ description: Sort DataFrame by index DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| kwargs | Object |

{

ascending: Order of sorting

inplace: specify whether to perform the operation to the row/column with/without creating a new DataFrame

}

| {**ascending**: true, **inplace:**false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | **Returns:** From 94c7b4307153eb9ef75065970e13e39e55d2f25a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:08:52 +0000 Subject: [PATCH 032/202] GitBook: No commit message --- api-reference/dataframe/dataframe.append.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index d13e0a0..827a2a9 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -1,18 +1,19 @@ --- description: Adds new row to the end of a DataFrame --- - # DataFrame.append -danfo.DataFrame.**append**\(val\) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)\] +danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| val | Array \| Series | Object to append | | +| Parameters | Type | Description | Default | +| ---------- | --------------- | ---------------- | ------- | +| newValues | | | | +| newValues | | | | +| newValues | Array \| Series | Object to append | | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -36,14 +37,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -72,5 +72,4 @@ new_df.print() {% endtab %} {% endtabs %} -\*\*\*\* - +**** From 763689af077f8bd506cef1b9faa83858aa5d8a59 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:09:57 +0000 Subject: [PATCH 033/202] GitBook: No commit message --- api-reference/dataframe/dataframe.append.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index 827a2a9..d7371a2 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -5,11 +5,11 @@ description: Adds new row to the end of a DataFrame danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] -| Parameters | Type | Description | Default | -| ---------- | --------------- | ---------------- | ------- | -| newValues | | | | -| newValues | | | | -| newValues | Array \| Series | Object to append | | +| Parameters | Type | Description | Default | +| ---------- | --------------------------- | ----------------------------------------------------------------------------------------------------- | ------- | +| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` | | +| options | Array \| Series | Object to append | | **Returns:** From 338bb0a669663d54e326968f0adf604ef12994b2 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:10:57 +0000 Subject: [PATCH 034/202] GitBook: No commit message --- api-reference/dataframe/dataframe.append.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index d7371a2..f602051 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -5,11 +5,11 @@ description: Adds new row to the end of a DataFrame danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | ----------------------------------------------------------------------------------------------------- | ------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` | | -| options | Array \| Series | Object to append | | +| Parameters | Type | Description | Default | +| ---------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | +| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | +| options | Object | Con | | **Returns:** From cda60d039b18cf3aa1554f16de6343e104504d55 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:11:59 +0000 Subject: [PATCH 035/202] GitBook: No commit message --- api-reference/dataframe/dataframe.append.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index f602051..9dd2234 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -5,11 +5,11 @@ description: Adds new row to the end of a DataFrame danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | -| options | Object | Con | | +| Parameters | Type | Description | Default | +| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | +| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | +| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| **Returns:** From c05d90ac16847fcffddb9f80b49a7be3dacfd99d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:14:14 +0000 Subject: [PATCH 036/202] GitBook: No commit message --- api-reference/dataframe/dataframe.append.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index 9dd2234..ae84a8b 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -17,7 +17,7 @@ danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danf ## **Examples** -### **Sort DataFrame by a column in ascending order** +### **Appends a new row to the end of a DataFrame** {% tabs %} {% tab title="Node" %} @@ -29,7 +29,7 @@ let data = [[0, 2, 4, "b"], let df = new dfd.DataFrame(data) df.print() -let new_df = df.append([[20, 40, 60, "d"]]) +let new_df = df.append([[20, 40, 60, "d"]], [3]) new_df.print() ``` From bba8c802d714f0207d33021c18891724bf4975bf Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:15:25 +0000 Subject: [PATCH 037/202] GitBook: No commit message --- .../dataframe/dataframe.nunique-1.md | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/api-reference/dataframe/dataframe.nunique-1.md b/api-reference/dataframe/dataframe.nunique-1.md index 4cf2a14..f06d4ed 100644 --- a/api-reference/dataframe/dataframe.nunique-1.md +++ b/api-reference/dataframe/dataframe.nunique-1.md @@ -1,18 +1,18 @@ # DataFrame.nunique -danfo.DataFrame.**nunique**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)\] +danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | +| Parameters | Type | Description | Default | +| ---------- | ---- | -------------------------------------- | ------- | +| axis | Int | 0 for row axis, and 1 for column axis | 1 | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -### Return number of unique values along column axis \(axis=1\) +### Return number of unique values along column axis (axis=1) {% tabs %} {% tab title="Node" %} @@ -32,30 +32,28 @@ df.nunique().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 3 ║ -╟───┼──────────────────────╢ -║ B │ 4 ║ -╟───┼──────────────────────╢ -║ C │ 2 ║ -╟───┼──────────────────────╢ -║ D │ 3 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 4 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╚═══╧═══╝ + ``` {% endtab %} {% endtabs %} -### Return number of unique values in row axis \(axis=0\) +### Return number of unique values in row axis (axis=0) {% tabs %} {% tab title="Node" %} @@ -75,14 +73,13 @@ df.nunique(axis=0).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -98,5 +95,4 @@ df.nunique(axis=0).print() {% endtab %} {% endtabs %} -**Note:** To get the unique elements along an axis, use ****[DataFrame.unique.](dataframe.nunique-1.md) - +**Note: **To get the unique elements along an axis, use** **[DataFrame.unique.](dataframe.nunique-1.md) From cf0fef3f77bd4210912850988119df52926e00c8 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:17:03 +0000 Subject: [PATCH 038/202] GitBook: No commit message --- api-reference/dataframe/dataframe.tensor.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/dataframe.tensor.md b/api-reference/dataframe/dataframe.tensor.md index 5f001fa..72ddf9a 100644 --- a/api-reference/dataframe/dataframe.tensor.md +++ b/api-reference/dataframe/dataframe.tensor.md @@ -1,18 +1,15 @@ --- -description: >- - Return a Tensorflow tensor representation of the DataFrame. Only the values in - the DataFrame will be returned, the axes labels will be removed. +description: Return a Tensorflow tensor representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. --- - # DataFrame.tensor -danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] +danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** - ****return **tf.tensor** +** **return** tf.tensor** -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype \(mainly float32\), and will replace any string value with NaN. Use with care. +> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. ## **Examples** @@ -38,14 +35,13 @@ tf_tensor.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` float32 Tensor { @@ -93,14 +89,13 @@ tf_tensor.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` float32 Tensor { @@ -122,4 +117,3 @@ Tensor ``` {% endtab %} {% endtabs %} - From c49ef3c45935653139923bb7248ed5d7bf49cb5b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:18:07 +0000 Subject: [PATCH 039/202] GitBook: No commit message --- api-reference/dataframe/dataframe.tensor.md | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/api-reference/dataframe/dataframe.tensor.md b/api-reference/dataframe/dataframe.tensor.md index 72ddf9a..125198f 100644 --- a/api-reference/dataframe/dataframe.tensor.md +++ b/api-reference/dataframe/dataframe.tensor.md @@ -43,23 +43,11 @@ tf_tensor.print() {% tab title="Output" %} ``` float32 - -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 0, - rankType: '2' -} - Tensor [[-20 , 34, 20], - [30 , -4, 2 ], - [47.2999992, 5 , 30]] + [30 , -4, 20], + [47.2999992, 5 , 30], + [-20 , 6 , 30]] ``` {% endtab %} {% endtabs %} @@ -72,7 +60,7 @@ String values in a Tensor are represented as NaN, so ensure to transform them be const dfd = require("danfojs-node") let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , + "Count": [34, 5, 6] , "country code": ["NG", "FR", "GH"] } From 77a4be27b34a74a71961eca2015f914c363e5870 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:19:10 +0000 Subject: [PATCH 040/202] GitBook: No commit message --- api-reference/dataframe/dataframe.print.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/api-reference/dataframe/dataframe.print.md b/api-reference/dataframe/dataframe.print.md index de4ea91..7a43db1 100644 --- a/api-reference/dataframe/dataframe.print.md +++ b/api-reference/dataframe/dataframe.print.md @@ -1,14 +1,9 @@ --- description: Pretty prints n number of rows in a DataFrame or Series to the console --- - # DataFrame.print -danfo.DataFrame.**print\(**rows**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| **rows** | Int | Number of rows to display. | 5 | +danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] ## **Examples** @@ -29,14 +24,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Abs │ Count │ country code ║ @@ -72,14 +66,13 @@ console.log(String(df)); {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` DataFrame { kwargs: { columns: [ 'Abs', 'Count', 'country code' ] }, series: false, @@ -129,4 +122,3 @@ DataFrame { ``` {% endtab %} {% endtabs %} - From 865e54c68ada4110375bef9a86295b85e803ad45 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:20:09 +0000 Subject: [PATCH 041/202] GitBook: No commit message --- api-reference/dataframe/dataframe.print.md | 64 +++++++--------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/api-reference/dataframe/dataframe.print.md b/api-reference/dataframe/dataframe.print.md index 7a43db1..415e45f 100644 --- a/api-reference/dataframe/dataframe.print.md +++ b/api-reference/dataframe/dataframe.print.md @@ -74,51 +74,29 @@ console.log(String(df)); {% tab title="Output" %} ``` DataFrame { - kwargs: { columns: [ 'Abs', 'Count', 'country code' ] }, - series: false, - data: [ [ 20.2, 34, 'NG' ], [ 30, 4, 'FR' ], [ 47.3, 5, 'GH' ] ], - row_data_tensor: Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 0, - rankType: '2' + '$isSeries': false, + '$config': Configs { + tableDisplayConfig: {}, + tableMaxRow: 10, + tableMaxColInConsole: 21, + dtypeTestLim: 7, + lowMemoryMode: false }, - index_arr: [ 0, 1, 2 ], - columns: [ 'Abs', 'Count', 'country code' ], - col_data: [ [ 20.2, 30, 47.3 ], [ 34, 4, 5 ], [ 'NG', 'FR', 'GH' ] ], - col_data_tensor: Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 1, - rankType: '2' - }, - col_types: [ 'float32', 'int32', 'string' ], - Abs: [Getter/Setter], - Count: [Getter/Setter], - 'country code': [Getter/Setter] + '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], + '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], + '$index': [ 0, 1, 2 ], + '$dtypes': [ 'float32', 'int32', 'string' ], + '$columns': [ 'Abs', 'Count', 'country code' ] } - - //after casting to string - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ FR ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ GH ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Abs │ Count │ country code ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.2 │ 34 │ NG ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ FR ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ GH ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} From ac7ab598fb7ec5e6d2bf62a76f18a12ec1d65725 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:21:07 +0000 Subject: [PATCH 042/202] GitBook: No commit message --- api-reference/dataframe/dataframe.to_csv.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 858cfa9..ae232da 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -1,14 +1,11 @@ --- description: Convert DataFrame data to a comma-separated values (csv) --- +# DataFrame.to_csv -# DataFrame.to\_csv +danfo.DataFrame.**to_csv**(configs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -danfo.DataFrame.**to\_csv**\(path\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - -**Returns:** - - ****returns **Promise** +**** ## **Examples** @@ -39,7 +36,7 @@ df.to_csv("/home/link/to/path.csv").then((csv) => { {% tabs %} {% tab title="Output" %} -```text +``` Abs,Count,country code 20.2,34,NG 30,4,FR @@ -49,6 +46,5 @@ Abs,Count,country code {% endtabs %} {% hint style="info" %} -To export DataFrame as Json, use [DataFrame.to\_json](dataframe.to_json.md) +To export DataFrame as Json, use [DataFrame.to_json](dataframe.to_json.md) {% endhint %} - From f607e73ec4e86fd465b6721bcfcd63e8d0916ebc Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:22:34 +0000 Subject: [PATCH 043/202] GitBook: No commit message --- api-reference/dataframe/dataframe.to_csv.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index ae232da..b48f0b7 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -3,9 +3,13 @@ description: Convert DataFrame data to a comma-separated values (csv) --- # DataFrame.to_csv -danfo.DataFrame.**to_csv**(configs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +DataFrame.**to_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -**** +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. ## **Examples** From bff1e98af01c13ebdf53ba1ea1475ee85ac0571b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:24:06 +0000 Subject: [PATCH 044/202] GitBook: No commit message --- api-reference/dataframe/dataframe.to_csv.md | 102 ++++++++++++++++---- 1 file changed, 81 insertions(+), 21 deletions(-) diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index b48f0b7..655b7e8 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -11,44 +11,104 @@ DataFrame.**to_csv**(options) \[[source](https://github.com/opensource9ja/danfoj The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. -## **Examples** +**** -### Convert DataFrame to CSV format +### Convert DataFrame to CSV string and return value {% tabs %} -{% tab title="Node" %} +{% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , - "country code": ["NG", "FR", "GH"] } +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; +let df = new dfd.DataFrame(data); -let df = new dfd.DataFrame(data) +const csv = df.to_csv({ download: false }); +console.log(csv); -df.to_csv("/home/link/to/path.csv").then((csv) => { - console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + -}).catch((err) => { + + + + + + - console.log(err); -}) ``` {% endtab %} {% endtabs %} +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + {% tabs %} -{% tab title="Output" %} -``` -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ filePath: "testOut.csv"}); ``` {% endtab %} {% endtabs %} -{% hint style="info" %} -To export DataFrame as Json, use [DataFrame.to_json](dataframe.to_json.md) -{% endhint %} +### Convert DataFrame to CSV string and download file in browser + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ fileName: "testOut.csv", download: true}); +``` + From 276b2acfb774b820ce38b6d65fcdb392696e99d9 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:25:00 +0000 Subject: [PATCH 045/202] GitBook: No commit message --- api-reference/dataframe/dataframe.to_json.md | 127 +++++++++++++++---- 1 file changed, 101 insertions(+), 26 deletions(-) diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 968ca81..f6082a0 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -1,51 +1,126 @@ --- description: Convert DataFrame to JSON format --- +# DataFrame.to_json -# DataFrame.to\_json +> DataFrame.**to_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] -danfo.DataFrame.**to\_json**\(path\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| -**Returns:** +The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - ****returns **Promise** - -## **Examples** - -### Convert DataFrame to JSON format +### Convert DataFrame/Series to JSON and return value {% tabs %} -{% tab title="Node" %} +{% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , - "country code": ["NG", "FR", "GH"] } +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = df.to_json({ download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = df.to_json({ + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + -let df = new dfd.DataFrame(data) + -df.to_json("/home/link/to/path.csv").then((json) => { - console.log(json); -}).catch((err) => { - console.log(err); -}) ``` {% endtab %} {% endtabs %} +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + {% tabs %} -{% tab title="Output" %} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ filePath: "./testOutput.json" }); ``` {% endtab %} {% endtabs %} -{% hint style="info" %} -To export DataFrame as CSV, use [DataFrame.to\_csv](dataframe.to_json.md) -{% endhint %} +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); +df.to_json({ fileName: "test_out.json" }); +``` From 0a9454aea9f3b7dd2486d74ab6551c5582136f27 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:27:31 +0000 Subject: [PATCH 046/202] GitBook: No commit message --- api-reference/input-output/danfo.to_csv.md | 71 +++++----------------- 1 file changed, 14 insertions(+), 57 deletions(-) diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index 4bb5456..d7d78bb 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -2,59 +2,16 @@ description: Writes a DataFrame or Series to CSV format. --- -# danfo.to\_csv - -> danfo.**to\_csv**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)\] - - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
data - Series or DataFrameThe Series or DataFrame to write to CSV
options - object, optional -

Configuration object:

-

{

-

filePath: Local file path to write the CSV file to. - If not specified, the CSV will be returned as a string. Only needed in - Nodejs version -
fileName: The name of the file to download as. Only - needed in browser environment. -
download: Boolean indicating whether to automatically - download the CSV file in the browser. Only needed in the browser environment.

-

header: Boolean indicating whether to include a header - row in the CSV file.

-

sep: Character to be used as a separator in the CSV - file.

-

-

}

-
{ -
download: true, -
sep: "," -
-
}
- -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. +# danfo.to_csv + +> danfo.**to_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. ### Convert DataFrame to CSV string and return value @@ -71,7 +28,7 @@ let data = { let df = new dfd.DataFrame(data); -const csv = df.to_csv({ download: false }); +const csv = dfd.to_csv(df, { download: false }); console.log(csv); //output @@ -134,7 +91,7 @@ let data = { let df = new dfd.DataFrame(data); -df.to_csv({ filePath: "testOut.csv"}); +dfd.to_csv(df, { filePath: "testOut.csv"}); ``` {% endtab %} {% endtabs %} @@ -144,6 +101,7 @@ df.to_csv({ filePath: "testOut.csv"}); You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript +const dfd = require("danfojs") let data = { Abs: [20.2, 30, 47.3], Count: [34, 4, 5], @@ -152,6 +110,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_csv({ fileName: "testOut.csv", download: true}); +dfd.to_csv(df, { fileName: "testOut.csv", download: true}); ``` - From 1f6b1a0c76a7c7b4b384f8b7ef79fe0ea0ce0c28 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:27:57 +0000 Subject: [PATCH 047/202] GitBook: No commit message --- api-reference/input-output/danfo.to_csv.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index d7d78bb..f4b0f54 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -96,12 +96,13 @@ dfd.to_csv(df, { filePath: "testOut.csv"}); {% endtab %} {% endtabs %} -### Convert DataFrame to CSV string and download file in browser +### Convert DataFrame to CSV string and download file in Client-side lib You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript const dfd = require("danfojs") + let data = { Abs: [20.2, 30, 47.3], Count: [34, 4, 5], From c35b5107dc4ecb1c9c35980c8141ebd7e9e51c11 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:28:29 +0000 Subject: [PATCH 048/202] GitBook: No commit message --- api-reference/input-output/danfo.to_excel.md | 58 ++++---------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index 0b781b4..cc383dd 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -4,53 +4,16 @@ description: >- download in browser. --- -# danfo.to\_excel +# danfo.to_excel -> danfo.**to\_excel**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)\] +> danfo.**to_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
data - Series or DataFrameThe Series or DataFrame to write to CSV
options - object, optional -

Configuration object:

-

{

-

filePath: Local file path to write the CSV file to. - If not specified, the CSV will be returned as a string. Only needed in - Nodejs version -
fileName: The name of the file to download as. Only - needed in the browser environment. -
sheetName: Name to call the excel sheet.

-

}

-
{ -
filePath: "./output.xlsx", -
sheetName: "Sheet1" -
-
}
+| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| -The **to\_excel** function can be used to write out a DataFrame or Series to Excel \(**.xlsx**\) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. ### Convert DataFrame to Excel and write to file path @@ -69,12 +32,12 @@ let data = { let df = new dfd.DataFrame(data); -df.to_excel({ filePath: "testOut.xlsx"}); +dfd.to_excel(df, { filePath: "testOut.xlsx"}); ``` {% endtab %} {% endtabs %} -### Convert DataFrame to Excel and download the file in a browser +### Convert DataFrame to Excel and download the file in Client-side lib You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. @@ -87,6 +50,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_excel({ fileName: "testOut.xlsx"}); +dfd.to_excel(df, { fileName: "testOut.xlsx"}); ``` - From 0bc39c185bf6c768d3074929cc218e318f728ae0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:29:21 +0000 Subject: [PATCH 049/202] GitBook: No commit message --- api-reference/input-output/danfo.to_json.md | 56 ++++----------------- 1 file changed, 10 insertions(+), 46 deletions(-) diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 878eb5f..785b9be 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -1,48 +1,13 @@ -# danfo.to\_json - -> danfo.**to\_json**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)\] - - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
data - Series or DataFrameThe Series or DataFrame to write to CSV
options - object, optional -

Configuration object:

-

{

-

filePath: Local file path to write the CSV file to. - If not specified, the CSV will be returned as a string. Only needed in - Nodejs version -
fileName: The name of the file to download as. Only - needed in browser environment. -
format: The format of the JSON. Can be one of row or column.

-

}

-
{ -
format: "column" -
}
- -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. +# danfo.to_json + +> danfo.**to_json**(data, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. ### Convert DataFrame/Series to JSON and return value @@ -157,4 +122,3 @@ let df = new dfd.DataFrame(data); df.to_json({ fileName: "test_out.json" }); ``` - From d12e4ef6169a505e49d0691f45658923cae6fa50 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:29:50 +0000 Subject: [PATCH 050/202] GitBook: No commit message --- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_excel.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index f4b0f54..06e7f95 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -4,7 +4,7 @@ description: Writes a DataFrame or Series to CSV format. # danfo.to_csv -> danfo.**to_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] +> danfo.**to_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] | **Parameters** | Type | Description | Default | | -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index cc383dd..5218852 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -6,7 +6,7 @@ description: >- # danfo.to_excel -> danfo.**to_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] +> danfo.**to_excel**(data, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] | **Parameters** | Type | Description | Default | | -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | From d26926d065626def8c61ca48b02d6f7710fc37c7 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:30:11 +0000 Subject: [PATCH 051/202] GitBook: No commit message --- api-reference/input-output/danfo.to_excel.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index 5218852..1fe1adf 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -6,7 +6,7 @@ description: >- # danfo.to_excel -> danfo.**to_excel**(data, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] +> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] | **Parameters** | Type | Description | Default | | -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 785b9be..93eaa97 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -1,6 +1,6 @@ # danfo.to_json -> danfo.**to_json**(data, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] +> danfo.**to_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] | **Parameters** | Type | Description | Default | | -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | From 52cebb91e4be157b933f7b4bf8ba428d5e99ce93 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:30:54 +0000 Subject: [PATCH 052/202] GitBook: No commit message --- api-reference/input-output/danfo.to_json.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 93eaa97..6ec9f70 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -24,7 +24,7 @@ let data = { let df = new dfd.DataFrame(data); -const jsonObj = df.to_json({ download: false }); //column format +const jsonObj = dfd.to_json(df, { download: false }); //column format console.log(jsonObj); //output @@ -35,7 +35,7 @@ console.log(jsonObj); ] //row format -const jsonObj = df.to_json({ +const jsonObj = dfd.to_json(df, { download: false, format: "row" }); @@ -102,7 +102,7 @@ let data = { let df = new dfd.DataFrame(data); -df.to_json({ filePath: "./testOutput.json" }); +dfd.to_json(df, { filePath: "./testOutput.json" }); ``` {% endtab %} {% endtabs %} @@ -120,5 +120,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_json({ fileName: "test_out.json" }); +dfd.to_json(df, { fileName: "test_out.json" }); ``` From 443d68cd5f8705154e977554cbb2b2e8a05ee197 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:33:05 +0000 Subject: [PATCH 053/202] GitBook: No commit message --- .../dataframe/dataframe.sort_values.md | 46 ++++--------------- 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 829c6c5..2272b53 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -2,40 +2,17 @@ description: Sort a Dataframe in ascending or descending order by a specified column name. --- -# DataFrame.sort\_values - -danfo.DataFrame.**sort\_values**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

by: This key can be either a single column name or a single array - of the same length as the calling DataFrame,

-

ascending: Order of sorting

-

inplace: specify whether to perform the operation to the row/column - with/without creating a new DataFrame

-

}

-
{ascending: true, inplace:false}
+# DataFrame.sort_values + +danfo.DataFrame.**sort_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -59,14 +36,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -102,14 +78,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -122,4 +97,3 @@ df.print() ``` {% endtab %} {% endtabs %} - From 9bd9f140292aef15e9c611713f38234c83405b74 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:34:28 +0000 Subject: [PATCH 054/202] GitBook: No commit message --- .../dataframe/dataframe.sort_values.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 2272b53..94fac01 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -24,8 +24,8 @@ danfo.DataFrame.**sort_values**(kwargs) \[[source](https://github.com/opensource const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } + "B": [34, 5, 6], + "C": [20, 3, 30] } let df = new dfd.DataFrame(data) @@ -44,15 +44,15 @@ df.print() {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -85,15 +85,15 @@ df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ -4 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} From b69a38cf321b81c0fc7c3538953df93ffb3f97cf Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:34:48 +0000 Subject: [PATCH 055/202] GitBook: No commit message --- SUMMARY.md | 48 ++++++++--------- api-reference/dataframe/dataframe.print.md | 5 +- .../dataframe/dataframe.sort_values.md | 4 +- api-reference/dataframe/dataframe.to_excel.md | 53 +++++++++++++++++++ 4 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 api-reference/dataframe/dataframe.to_excel.md diff --git a/SUMMARY.md b/SUMMARY.md index c253e10..268ee82 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -4,22 +4,22 @@ * [Getting Started](getting-started.md) * [API reference](api-reference/README.md) * [General Functions](api-reference/general-functions/README.md) - * [danfo.date\_range](api-reference/general-functions/danfo.date_range.md) + * [danfo.date_range](api-reference/general-functions/danfo.date_range.md) * [danfo.OneHotEncoder](api-reference/general-functions/danfo.onehotencoder.md) * [danfo.StandardScaler](api-reference/general-functions/danfo.standardscaler.md) * [danfo.MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) * [danfo.LabelEncoder](api-reference/general-functions/danfo.labelencoder.md) - * [danfo.to\_datetime](api-reference/general-functions/danfo.to_datetime.md) - * [danfo.get\_dummies](api-reference/general-functions/danfo.get_dummies.md) + * [danfo.to_datetime](api-reference/general-functions/danfo.to_datetime.md) + * [danfo.get_dummies](api-reference/general-functions/danfo.get_dummies.md) * [danfo.concat](api-reference/general-functions/danfo.concat.md) * [danfo.merge](api-reference/general-functions/danfo.merge.md) * [Input/Output](api-reference/input-output/README.md) - * [danfo.read\_excel](api-reference/input-output/danfo.read_excel.md) - * [danfo.read\_json](api-reference/input-output/danfo.read_json.md) - * [danfo.read\_csv](api-reference/input-output/danfo.read_csv.md) - * [danfo.to\_csv](api-reference/input-output/danfo.to_csv.md) - * [danfo.to\_excel](api-reference/input-output/danfo.to_excel.md) - * [danfo.to\_json](api-reference/input-output/danfo.to_json.md) + * [danfo.read_excel](api-reference/input-output/danfo.read_excel.md) + * [danfo.read_json](api-reference/input-output/danfo.read_json.md) + * [danfo.read_csv](api-reference/input-output/danfo.read_csv.md) + * [danfo.to_csv](api-reference/input-output/danfo.to_csv.md) + * [danfo.to_excel](api-reference/input-output/danfo.to_excel.md) + * [danfo.to_json](api-reference/input-output/danfo.to_json.md) * [Series](api-reference/series/README.md) * [Creating a Series](api-reference/series/creating-a-series.md) * [Series.append](api-reference/series/series.append.md) @@ -50,7 +50,7 @@ * [Series.dt.seconds](api-reference/series/series.dt.second.md) * [Series.dt.minutes](api-reference/series/series.dt.minute.md) * [Series.dt.monthday](api-reference/series/series.dt.monthday.md) - * [Series.dt.month\_name](api-reference/series/series.dt.month_name.md) + * [Series.dt.month_name](api-reference/series/series.dt.month_name.md) * [Series.dt.hour](api-reference/series/series.dt.hour.md) * [Series.dt.weekdays](api-reference/series/series.dt.weekdays.md) * [Series.dt.day](api-reference/series/series.dt.day.md) @@ -63,8 +63,8 @@ * [Series.isna](api-reference/series/series.isna.md) * [Series.fillna](api-reference/series/series.fillna.md) * [Series.dropna](api-reference/series/series.dropna.md) - * [Series.drop\_duplicates](api-reference/series/series.drop_duplicates.md) - * [Series.value\_counts](api-reference/series/series.value_counts.md) + * [Series.drop_duplicates](api-reference/series/series.drop_duplicates.md) + * [Series.value_counts](api-reference/series/series.value_counts.md) * [Series.nunique](api-reference/series/series.nunique.md) * [Series.unique](api-reference/series/series.unique.md) * [Series.abs](api-reference/series/series.abs.md) @@ -84,11 +84,11 @@ * [Series.index](api-reference/series/series.index.md) * [Series.apply](api-reference/series/series.apply.md) * [Series.map](api-reference/series/series.map.md) - * [Series.set\_index](api-reference/series/series.set_index.md) - * [Series.reset\_index](api-reference/series/series.reset_index.md) + * [Series.set_index](api-reference/series/series.set_index.md) + * [Series.reset_index](api-reference/series/series.reset_index.md) * [Series.describe](api-reference/series/series.describe.md) * [Series.copy](api-reference/series/series.copy.md) - * [Series.sort\_values](api-reference/series/series.sort_values.md) + * [Series.sort_values](api-reference/series/series.sort_values.md) * [Series.var](api-reference/series/series.var.md) * [Series.std](api-reference/series/series.std.md) * [Series.round](api-reference/series/series.round.md) @@ -114,16 +114,17 @@ * [Series.or](api-reference/series/series.or.md) * [Dataframe](api-reference/dataframe/README.md) * [Creating a DataFrame](api-reference/dataframe/creating-a-dataframe.md) - * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort_index.md) + * [DataFrame.sort_index](api-reference/dataframe/dataframe.sort_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) * [DataFrame.nunique](api-reference/dataframe/dataframe.nunique-1.md) * [DataFrame.tensor](api-reference/dataframe/dataframe.tensor.md) * [DataFrame.print](api-reference/dataframe/dataframe.print.md) - * [DataFrame.to\_csv](api-reference/dataframe/dataframe.to_csv.md) - * [DataFrame.to\_json](api-reference/dataframe/dataframe.to_json.md) - * [DataFrame.sort\_values](api-reference/dataframe/dataframe.sort_values.md) - * [DataFrame.set\_index](api-reference/dataframe/dataframe.set_index.md) - * [DataFrame.reset\_index](api-reference/dataframe/dataframe.reset_index.md) + * [DataFrame.to_csv](api-reference/dataframe/dataframe.to_csv.md) + * [DataFrame.to_json](api-reference/dataframe/dataframe.to_json.md) + * [DataFrame.to_excel](api-reference/dataframe/dataframe.to_excel.md) + * [DataFrame.sort_values](api-reference/dataframe/dataframe.sort_values.md) + * [DataFrame.set_index](api-reference/dataframe/dataframe.set_index.md) + * [DataFrame.reset_index](api-reference/dataframe/dataframe.reset_index.md) * [DataFrame.rename](api-reference/dataframe/dataframe.rename.md) * [DataFrame.drop](api-reference/dataframe/dataframe.drop.md) * [DataFrame.unique](api-reference/dataframe/dataframe.nunique.md) @@ -133,7 +134,7 @@ * [DataFrame.axes](api-reference/dataframe/dataframe.axes.md) * [DataFrame.ndim](api-reference/dataframe/dataframe.ndim.md) * [DataFrame.values](api-reference/dataframe/dataframe.values.md) - * [DataFrame.select\_dtypes](api-reference/dataframe/dataframe.select_dtypes.md) + * [DataFrame.select_dtypes](api-reference/dataframe/dataframe.select_dtypes.md) * [DataFrame.ctypes](api-reference/dataframe/dataframe.dtypes.md) * [DataFrame.index](api-reference/dataframe/dataframe.index.md) * [DataFrame.loc](api-reference/dataframe/danfo.dataframe.loc.md) @@ -192,7 +193,7 @@ * [Line Charts](api-reference/plotting/line-charts.md) * [Configuring your plots](api-reference/plotting/configuring-your-plots.md) * [Groupby](api-reference/groupby/README.md) - * [Groupby.get\_groups](api-reference/groupby/groupby.get_groups.md) + * [Groupby.get_groups](api-reference/groupby/groupby.get_groups.md) * [Groupby.col](api-reference/groupby/groupby.col.md) * [Groupby.max](api-reference/groupby/groupby.max.md) * [Groupby.min](api-reference/groupby/groupby.min.md) @@ -212,4 +213,3 @@ * [Building Data Driven Applications with Danfo.js - Book](building-data-driven-applications-with-danfo.js-book.md) * [Contributing Guide](contributing-guide.md) * [Release Notes](release-notes.md) - diff --git a/api-reference/dataframe/dataframe.print.md b/api-reference/dataframe/dataframe.print.md index 415e45f..d03232d 100644 --- a/api-reference/dataframe/dataframe.print.md +++ b/api-reference/dataframe/dataframe.print.md @@ -1,6 +1,9 @@ --- -description: Pretty prints n number of rows in a DataFrame or Series to the console +description: >- + Pretty prints default (10) number of rows in a DataFrame or Series to the + console --- + # DataFrame.print danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 94fac01..8da51fe 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -66,8 +66,8 @@ df.print() const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } + "B": [34, 5, 6], + "C": [20, 3, 30] } let df = new dfd.DataFrame(data) diff --git a/api-reference/dataframe/dataframe.to_excel.md b/api-reference/dataframe/dataframe.to_excel.md new file mode 100644 index 0000000..4adf437 --- /dev/null +++ b/api-reference/dataframe/dataframe.to_excel.md @@ -0,0 +1,53 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# DataFrame.to_excel + +> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| + +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in a browser + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ fileName: "testOut.xlsx"}); +``` From b79cf0ca76385c9e4aef7488b13462622654f92c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:36:40 +0000 Subject: [PATCH 056/202] GitBook: No commit message --- .../dataframe/dataframe.set_index.md | 55 +++++-------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3e1318e..deabe84 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -4,40 +4,19 @@ description: >- length). --- -# DataFrame.set\_index - -danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

key: This key can be either a single column name or a single array - of the same length as the calling DataFrame,

-

drop: Delete columns to be used as the new index.

-

inplace: specify whether to perform the operation to the row/column - with/without creating a new DataFrame

-

}

-
{drop: true, inplace:false}
+# DataFrame.set_index + +danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | +| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to

drop: Delete columns to be used as the new index.

inplace: specify whether to perform the operation to the row/column with/without creating a new DataFrame

}

| {**drop**: true, **inplace:**false} | **Returns:** - ****return **DataFrame** +``` + ****return **DataFrame** +``` ## **Examples** @@ -46,7 +25,6 @@ danfo.DataFrame.**set\_index**\(kwargs\) \[[source](https://github.com/opensourc {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -59,21 +37,18 @@ df.print() df.set_index({column: "A", inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text - +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,21 +93,18 @@ df.print() let new_index = ["a", "b", "a"] df.set_index({column: new_index, inplace: true}) df.print() - ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text - +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,5 +131,4 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset\_index](dataframe.reset_index.md). - +**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). From 1d518807611ddf0bf8d8d9fa69024219b6f5e038 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:37:53 +0000 Subject: [PATCH 057/202] GitBook: No commit message --- api-reference/dataframe/dataframe.set_index.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index deabe84..8bf81e2 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -8,15 +8,9 @@ description: >- danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to

drop: Delete columns to be used as the new index.

inplace: specify whether to perform the operation to the row/column with/without creating a new DataFrame

}

| {**drop**: true, **inplace:**false} | - -**Returns:** - -``` - ****return **DataFrame** -``` +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | ## **Examples** From 03bebdc663ff1b8d0e8f965e5bb737d59761eb42 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:38:52 +0000 Subject: [PATCH 058/202] GitBook: No commit message --- .../dataframe/dataframe.set_index.md | 95 ++++++++++++++----- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 8bf81e2..29f27b6 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -22,11 +22,11 @@ danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9 const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } + "B": [34, 5, 6], + "C": [20, 3, 30] } -let df = new dfd.DataFrame(data, {index: ["a", "b", "a"]}) +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) df.print() df.set_index({column: "A", inplace: true}) @@ -43,28 +43,79 @@ df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ -20 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 30 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **** +### **Setting index to a column in the DataFrame and dropping the column** -//after setting index +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") -╔══════╤═══════════════════╤═══════════════════╗ -║ │ B │ C ║ -╟──────┼───────────────────┼───────────────────╢ -║ -20 │ 34 │ 20 ║ -╟──────┼───────────────────┼───────────────────╢ -║ 30 │ -4 │ 20 ║ -╟──────┼───────────────────┼───────────────────╢ -║ 47.3 │ 5 │ 30 ║ -╚══════╧═══════════════════╧═══════════════════╝ +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) +df.print() + +df.set_index({column: "A", drinplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ -20 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 30 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} From 442cc61e04e2a09cd1fcc5645ebeeb0598b23bc7 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:40:08 +0000 Subject: [PATCH 059/202] GitBook: No commit message --- .../dataframe/dataframe.set_index.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 29f27b6..3d1152d 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -83,7 +83,7 @@ let data = { "A": [-20, 30, 47.3], let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) df.print() -df.set_index({column: "A", drinplace: true}) +df.set_index({column: "A", drop: true, inplace: true}) df.print() ``` {% endtab %} @@ -107,15 +107,15 @@ df.print() ║ c │ 47.3 │ 6 │ 30 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ -20 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 30 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ B │ C ║ +╟────────────┼───────────────────┼───────────────────╢ +║ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} From 8b01c35efb1e532250f6dc938487cdf6e41c557d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:41:02 +0000 Subject: [PATCH 060/202] GitBook: No commit message --- .../dataframe/dataframe.set_index.md | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index 3d1152d..e82c213 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -128,15 +128,15 @@ df.print() const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } + "B": [34, -5, 6], + "C": [20, 3, 30] } let df = new dfd.DataFrame(data) df.print() -let new_index = ["a", "b", "a"] -df.set_index({column: new_index, inplace: true}) +let new_index = ["a", "b", "c"] +df.set_index({index: new_index, inplace: true}) df.print() ``` {% endtab %} @@ -150,28 +150,25 @@ df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after setting the index - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} From 9ef3c7c79099bcbd25e57662ab515c1f993fb1da Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:42:12 +0000 Subject: [PATCH 061/202] GitBook: No commit message --- .../dataframe/dataframe.reset_index.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/dataframe.reset_index.md b/api-reference/dataframe/dataframe.reset_index.md index 7d5ff53..1a6c21c 100644 --- a/api-reference/dataframe/dataframe.reset_index.md +++ b/api-reference/dataframe/dataframe.reset_index.md @@ -1,18 +1,18 @@ --- -description: 'Reset the index of the DataFrame, and use the default one instead.' +description: Reset the index of the DataFrame, and use the default one instead. --- -# DataFrame.reset\_index +# DataFrame.reset_index -danfo.DataFrame.**reset\_index**\(inplace\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] +danfo.DataFrame.**reset_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| inplace | Boolean | **inplace**: specify whether to perform the operation to the row/column with/without creating a new DataFrame | false | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -39,14 +39,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -73,4 +72,3 @@ df.print() ``` {% endtab %} {% endtabs %} - From 16596358694b79416f474f70600ad0a46b0058fa Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:42:31 +0000 Subject: [PATCH 062/202] GitBook: No commit message --- .../dataframe/dataframe.reset_index.md | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/api-reference/dataframe/dataframe.reset_index.md b/api-reference/dataframe/dataframe.reset_index.md index 1a6c21c..00239fc 100644 --- a/api-reference/dataframe/dataframe.reset_index.md +++ b/api-reference/dataframe/dataframe.reset_index.md @@ -21,19 +21,20 @@ danfo.DataFrame.**reset_index**(options) \[[source](https://github.com/opensourc ```javascript const dfd = require("danfojs-node") -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } +let data = { + "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] +} -let df = new dfd.DataFrame(data, {index: ["a", "b", "a"]}) +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) df.print() -df.reset_index(true) //inplace +df.reset_index({ inplace: true }) //inplace //df = df.reset_index() //not in inplace df.print() - ``` {% endtab %} @@ -47,28 +48,26 @@ df.print() {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after reseting index - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From db01cd31a9f90cd1c5931183ff2331db24d7995e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:43:37 +0000 Subject: [PATCH 063/202] GitBook: No commit message --- api-reference/dataframe/dataframe.rename.md | 47 +++++---------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/api-reference/dataframe/dataframe.rename.md b/api-reference/dataframe/dataframe.rename.md index 2a26f85..652d189 100644 --- a/api-reference/dataframe/dataframe.rename.md +++ b/api-reference/dataframe/dataframe.rename.md @@ -7,44 +7,21 @@ description: >- # DataFrame.rename -danfo.DataFrame.**rename**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

mapper: Object of labels and transformations to apply to that axis’ - values.

-

axis: row=0, columns=1.

-

inplace: specify whether to perform the operation to the row/column - with/without creating a new DataFrame

-

}

-
{axis: 1, inplace:false}
+danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | +| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** ### Rename columns -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} @@ -64,14 +41,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ new_name │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -106,14 +82,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ new_name │ B │ new_c ║ @@ -149,14 +124,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -170,4 +144,3 @@ df.print() ``` {% endtab %} {% endtabs %} - From 181aa009efef266467d91ee943727ba251e85d65 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:44:50 +0000 Subject: [PATCH 064/202] GitBook: No commit message --- api-reference/dataframe/dataframe.rename.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/dataframe.rename.md b/api-reference/dataframe/dataframe.rename.md index 652d189..8e20993 100644 --- a/api-reference/dataframe/dataframe.rename.md +++ b/api-reference/dataframe/dataframe.rename.md @@ -30,7 +30,7 @@ const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], "B": [34, -4, 5], - "C": [20, 2, 3, 30] } + "C": [20, 2, 30] } let df = new dfd.DataFrame(data) @@ -69,8 +69,8 @@ df.print() const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } + "B": [34, -4, 6], + "C": [20, 2, 30] } let df = new dfd.DataFrame(data) From 0806698fb78861ce09c5269ff6c471816f7c9e69 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:45:20 +0000 Subject: [PATCH 065/202] GitBook: No commit message --- api-reference/dataframe/dataframe.rename.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/dataframe.rename.md b/api-reference/dataframe/dataframe.rename.md index 8e20993..6625bc1 100644 --- a/api-reference/dataframe/dataframe.rename.md +++ b/api-reference/dataframe/dataframe.rename.md @@ -110,13 +110,15 @@ df.print() ```javascript const dfd = require("danfojs-node") -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5, 6], - "C": [20, 2, 3, 30] } +let data = { + "A": [-20, 30, 47.3], + "B": [34, -4, 6], + "C": [20, 2, 30] +} -let df = new dfd.DataFrame(data, {index: ["a", "b", "a"]}) -df = df.rename({ mapper: {"a": 0}, axis: 0}) +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) +df = df.rename({ mapper: { "a": 0 }, axis: 0 }) df.print() ``` From 3bf789edffc9c72a88d99a8701479686e6659f63 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:46:23 +0000 Subject: [PATCH 066/202] GitBook: No commit message --- api-reference/dataframe/dataframe.drop.md | 47 +++++------------------ 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index 039a74b..385a4a7 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -6,44 +6,21 @@ description: >- # DataFrame.drop -danfo.DataFrame.**drop**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

columns: [Array(Columns| Index)] array of column names to drop

-

index: [Array(Columns| Index)] index labels to drop

-

axis: row=0, columns=1

-

inplace: specify whether to drop the row/column with/without creating - a new DataFrame

-

}

-
{axis: 1, inplace:false}
+danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | +| options | Object |

{

columns: Array of column names to drop

index: Arindex labels to drop

inplace: specify whether to drop the row/column with/without creating a new DataFrame

}

| {**axis**: 1, **inplace:**false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** ### Drop columns by specifying the names -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} @@ -63,14 +40,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ A │ D ║ ╟───┼───────────────────┼───────────────────╢ @@ -107,14 +83,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -147,14 +122,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -165,4 +139,3 @@ df.print() ``` {% endtab %} {% endtabs %} - From 0ee69fa7ece76699004d219b16033eac5790af0b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:47:31 +0000 Subject: [PATCH 067/202] GitBook: No commit message --- api-reference/dataframe/dataframe.drop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index 385a4a7..e023311 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -8,9 +8,9 @@ description: >- danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| options | Object |

{

columns: Array of column names to drop

index: Arindex labels to drop

inplace: specify whether to drop the row/column with/without creating a new DataFrame

}

| {**axis**: 1, **inplace:**false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | **Returns:** From f874b69e522ebd38ccf78fb832edbb0cc9d52d92 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:48:34 +0000 Subject: [PATCH 068/202] GitBook: No commit message --- api-reference/dataframe/dataframe.drop.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index e023311..3118b75 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -33,7 +33,7 @@ let data = { "A": [-20, 30, 47.3, -20], "D": ["a", "b", "c", "c"] } let df = new dfd.DataFrame(data) -df.drop({ columns: ["C", "B"], axis: 1, inplace: true }); +df.drop({ columns: ["C", "B"], inplace: true }); df.print() ``` {% endtab %} @@ -69,13 +69,15 @@ df.print() ```javascript const dfd = require("danfojs-node") -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } +let data = { + "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] +} let df = new dfd.DataFrame(data) -df.drop({ index: [0, 2], axis: 0, inplace: true }); +df.drop({ index: [0, 2], inplace: true }); df.print() ``` From 12eea58f998709a628a452dcfe3593fe952dd961 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:48:44 +0000 Subject: [PATCH 069/202] GitBook: No commit message --- api-reference/dataframe/dataframe.drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index 3118b75..2376308 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -116,7 +116,7 @@ let data = { "A": [-20, 30, 47.3, -20], "D": ["a", "b", "c", "c"] } let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.drop({ index: ["a", "c"], axis: 0, inplace: true }); +df.drop({ index: ["a", "c"], inplace: true }); df.print() ``` From 3cb9ca1b858fdea83f5b78412580f65ab74f0c37 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:51:05 +0000 Subject: [PATCH 070/202] GitBook: No commit message --- api-reference/dataframe/dataframe.astype.md | 44 +++++---------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index af73978..c32779f 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -4,35 +4,15 @@ description: Cast column of a DataFrame to a specified dtype. # DataFrame.astype -danfo.DataFrame.**astype**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

column: Array, label/column name of column to cast

-

dtype: dtype to cast to. One of [string, float32, int32]

-

}

-
+danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inpl | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -61,14 +41,13 @@ df.ctypes.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //before casting ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ @@ -148,14 +127,13 @@ df.ctypes.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -184,7 +162,7 @@ df.ctypes.print() {% endtab %} {% endtabs %} -**Note:** Casting a string column of alphabets/words to numeric form will return NaNs as values +**Note: **Casting a string column of alphabets/words to numeric form will return NaNs as values {% tabs %} {% tab title="Node" %} @@ -208,14 +186,13 @@ df.ctypes.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ @@ -243,4 +220,3 @@ df.ctypes.print() ``` {% endtab %} {% endtabs %} - From 22c8f9f308bf1001ef1fc163f60d80ccd4dfdd02 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:55:20 +0000 Subject: [PATCH 071/202] GitBook: No commit message --- api-reference/dataframe/dataframe.astype.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index c32779f..cdcffbe 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -6,9 +6,9 @@ description: Cast column of a DataFrame to a specified dtype. danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inpl | +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | **Returns:** From fd5620b86bb5d4e2a86677228d8ac034caf20453 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:57:00 +0000 Subject: [PATCH 072/202] GitBook: No commit message --- api-reference/dataframe/dataframe.astype.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index cdcffbe..fb388a3 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -119,7 +119,7 @@ let df = new dfd.DataFrame(data) let df_new = df.astype({column: "D", dtype: "int32"}) df_new.print() -df.ctypes.print() +df_new.ctypes.print() ``` @@ -178,7 +178,7 @@ let df = new dfd.DataFrame(data) let df_new = df.astype({column: "D", dtype: "int32"}) df_new.print() -df.ctypes.print() +df_new.ctypes.print() ``` From 0a549c0e78ecbf2016c9c91148e5d4e0b5d657a8 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 16:57:51 +0000 Subject: [PATCH 073/202] GitBook: No commit message --- api-reference/dataframe/dataframe.axes.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/api-reference/dataframe/dataframe.axes.md b/api-reference/dataframe/dataframe.axes.md index fbccf92..4bdc319 100644 --- a/api-reference/dataframe/dataframe.axes.md +++ b/api-reference/dataframe/dataframe.axes.md @@ -7,11 +7,11 @@ description: >- # DataFrame.axes -danfo.DataFrame.**axes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] +danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** - ****return **Object** +** **return** Object** ## **Examples** @@ -26,7 +26,7 @@ let data = {"A": [-20.1, 30, 47.3, -20], let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -console.log(df.axes) +console.log(df.axis) ``` @@ -34,16 +34,14 @@ console.log(df.axes) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` { index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } ``` {% endtab %} {% endtabs %} - From fa3de2bc3ace9240d97b9f5a9e2093076547d96f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:00:27 +0000 Subject: [PATCH 074/202] GitBook: No commit message --- api-reference/dataframe/dataframe.index.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/dataframe.index.md b/api-reference/dataframe/dataframe.index.md index cf14245..b5e817e 100644 --- a/api-reference/dataframe/dataframe.index.md +++ b/api-reference/dataframe/dataframe.index.md @@ -4,15 +4,11 @@ description: The index (row labels) of the DataFrame. # DataFrame.index -danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)\] - -**Returns:** - - ****return **new DataFrame** +danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] ## **Examples** -Returns auto-generated ****index of a ****DataFrame +Returns auto-generated** **index of a** **DataFrame {% tabs %} {% tab title="Node" %} @@ -30,20 +26,19 @@ console.log(df.index); {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` [0, 1, 2, 3] ``` {% endtab %} {% endtabs %} -Returns set ****index of a ****DataFrame +Returns set** **index of a** **DataFrame {% tabs %} {% tab title="Node" %} @@ -61,16 +56,14 @@ console.log(df.index); {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` [ 'r1', 'r2', 'r3', 'r4' ] ``` {% endtab %} {% endtabs %} - From e9ff3d3b18a7667f59a3009b19d4b9c5896901fc Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:00:57 +0000 Subject: [PATCH 075/202] GitBook: No commit message --- api-reference/dataframe/dataframe.index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/dataframe.index.md b/api-reference/dataframe/dataframe.index.md index b5e817e..0983db8 100644 --- a/api-reference/dataframe/dataframe.index.md +++ b/api-reference/dataframe/dataframe.index.md @@ -38,7 +38,7 @@ console.log(df.index); {% endtab %} {% endtabs %} -Returns set** **index of a** **DataFrame + {% tabs %} {% tab title="Node" %} From 5eac2977c3dc1084030be96395334bf4309766c3 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:02:34 +0000 Subject: [PATCH 076/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index f5fd6bf..4b5b76b 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -4,35 +4,15 @@ description: Access a group of rows and columns by label(s) # DataFrame.loc -danfo.DataFrame.**loc**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

rows: Array, labels of row index

-

columns: Array, labels of column names

-

}

-
+danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | +| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -40,7 +20,7 @@ danfo.DataFrame.**loc**\(kwargs\) \[[source](https://github.com/opensource9ja/da Allowed inputs are: -* A single label, e.g. `5` or `'a'`, \(note that `5` is interpreted as a _label_ of the index, and **not** as an integer position along the index\). +* A single label, e.g. `5` or `'a'`, (note that `5` is interpreted as a _label_ of the index, and **not** as an integer position along the index). * A list or array of labels, e.g. `['a', 'b', 'c']`. ### **Index by specific rows and return all columns** @@ -65,14 +45,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -120,14 +99,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -178,14 +156,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -213,5 +190,3 @@ sub_df.print() {% endtab %} {% endtabs %} - - From 495d7d97cfaa9bb715c2f15726744e56d411cff1 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:04:15 +0000 Subject: [PATCH 077/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 4b5b76b..4edc210 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -16,12 +16,18 @@ danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfoj ## **Examples** -`.loc()` is primarily label based, but row index also accepts numeric slices +`.loc()` is label position based-from `0` to `length-1` of the row axis. -Allowed inputs are: +Allowed inputs fare: -* A single label, e.g. `5` or `'a'`, (note that `5` is interpreted as a _label_ of the index, and **not** as an integer position along the index). -* A list or array of labels, e.g. `['a', 'b', 'c']`. +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` + +_**Note: **only** **the start label is included, and the end label is ignored. _ + +`.loc` will raise a `ValueEror` if a requested label is not found. ### **Index by specific rows and return all columns** From e7e970261c16b5717a07cf3fd0b0576974934f09 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:04:43 +0000 Subject: [PATCH 078/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 4edc210..dcde330 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -18,7 +18,7 @@ danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfoj `.loc()` is label position based-from `0` to `length-1` of the row axis. -Allowed inputs fare: +Allowed inputs for are: * An integer, e.g. `"r1"`. * A list or array of integers, e.g. `["a", "b", "d"]`. From b7aeb03e0291b5b91e4e48dda8dde90cd36aaaed Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:05:51 +0000 Subject: [PATCH 079/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index dcde330..5c9594e 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -125,7 +125,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after slicing + //after indexing ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Count │ Price ║ From fb3b047559c03181075d6714ec7fe315016a6001 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:06:52 +0000 Subject: [PATCH 080/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 5c9594e..ad432e8 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -196,3 +196,63 @@ sub_df.print() {% endtab %} {% endtabs %} +### **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +df.print() +let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +`s.loc([a:e]).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +`s.loc(["a":"e"]).print()`\ +\ +_**Quotes are not needed for numeric indices!**_ +{% endhint %} From 3b94dd32f2e047e727fb73e12cb434dd91db0590 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:08:04 +0000 Subject: [PATCH 081/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index ad432e8..703d0a4 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -249,10 +249,10 @@ sub_df.print() {% endtabs %} {% hint style="info" %} -Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ `s.loc([a:e]).print()`\ For the slice above to work, you must quote each slice, e.g:\ -`s.loc(["a":"e"]).print()`\ +``s.loc([`"a":"e"]).print()``\ \ _**Quotes are not needed for numeric indices!**_ {% endhint %} From cb2672aa821b8ccbbf5c8080d37268a86b7966bf Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:09:07 +0000 Subject: [PATCH 082/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 703d0a4..1ebb614 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -250,9 +250,9 @@ sub_df.print() {% hint style="info" %} Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -`s.loc([a:e]).print()`\ +df`.loc({ row: [a:e]}).print()`\ For the slice above to work, you must quote each slice, e.g:\ -``s.loc([`"a":"e"]).print()``\ +df``.loc({ row: [`"a":"e"`]}).print()``\ \ -_**Quotes are not needed for numeric indices!**_ +Inne_**Quotes are not needed for numeric indices!**_ {% endhint %} From cbb651a77d3e09a4cf99de895b794c43fa3a395a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:09:44 +0000 Subject: [PATCH 083/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 1ebb614..30c58a4 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -254,5 +254,5 @@ df`.loc({ row: [a:e]}).print()`\ For the slice above to work, you must quote each slice, e.g:\ df``.loc({ row: [`"a":"e"`]}).print()``\ \ -Inne_**Quotes are not needed for numeric indices!**_ +_**Inner**_ _**quotes are not needed for numeric indices!**_ {% endhint %} From a6f154a4a6db2fbd22594ac4e517adf17f7ada8c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:10:30 +0000 Subject: [PATCH 084/202] GitBook: No commit message --- api-reference/series/series.loc.md | 42 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/api-reference/series/series.loc.md b/api-reference/series/series.loc.md index f4f292e..aa36e72 100644 --- a/api-reference/series/series.loc.md +++ b/api-reference/series/series.loc.md @@ -4,28 +4,28 @@ description: Access a group of rows by label(s) or a boolean array. # Series.loc -danfo.Series.**loc**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -`.loc()` is label position based \(from `0` to `length-1` of the row axis\). +`.loc()` is label position based (from `0` to `length-1` of the row axis). Allowed inputs are: * An integer, e.g. `"r1"`. * A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false \] +* A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` -_**Note:** only ****the start label is included, and the end label is ignored._ +_**Note: **only** **the start label is included, and the end label is ignored. _ `.loc` will raise a `ValueEror` if a requested label is not found. @@ -49,14 +49,13 @@ s.loc(["a", "g"]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═════╗ ║ a │ 12 ║ ╟───┼─────╢ @@ -86,7 +85,7 @@ s.loc(["a", "g"]).print() ### **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end\], e.g **\[\`"a":"e"\`\]**. This will return all values from label positions `a` to `e`. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. {% tabs %} {% tab title="Node" %} @@ -104,14 +103,13 @@ s.loc([`"a":"e"`]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═════╗ ║ a │ 12 ║ ╟───┼─────╢ @@ -126,12 +124,12 @@ s.loc([`"a":"e"`]).print() {% endtabs %} {% hint style="info" %} -Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error: -`s.loc([a:e]).print()` -For the slice above to work, you must quote each slice, e.g: -`s.loc(["a":"e"]).print()` - -_**Quotes are not needed for numeric indices!**_ +Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +`s.loc([a:e]).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +`s.loc(["a":"e"]).print()`\ +\ +_**Inner quotes are not needed for numeric indices!**_ {% endhint %} ### By specifying a start index in a slice, all values after that index are returned. @@ -148,14 +146,13 @@ s.loc([`1:`]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═════╗ ║ 1 │ 34 ║ ╟───┼─────╢ @@ -190,7 +187,7 @@ s.loc(s.gt(20)).print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤════╗ ║ 1 │ 34 ║ ╟───┼────╢ @@ -199,4 +196,3 @@ s.loc(s.gt(20)).print() ║ 5 │ 30 ║ ╚═══╧════╝ ``` - From e69628db637efe6dfccb7692e0171bcef05f459a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:11:33 +0000 Subject: [PATCH 085/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 30c58a4..f729bfb 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -196,9 +196,9 @@ sub_df.print() {% endtab %} {% endtabs %} -### **Index by a slice of row** +## **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. {% tabs %} {% tab title="Node" %} @@ -256,3 +256,27 @@ df``.loc({ row: [`"a":"e"`]}).print()``\ \ _**Inner**_ _**quotes are not needed for numeric indices!**_ {% endhint %} + +### Slice DataFrame rby boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.loc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` From 2418a0891ceddb1422f7f6ade262f91a39adcffe Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:14:26 +0000 Subject: [PATCH 086/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index f729bfb..69aa95b 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -257,26 +257,33 @@ df``.loc({ row: [`"a":"e"`]}).print()``\ _**Inner**_ _**quotes are not needed for numeric indices!**_ {% endhint %} -### Slice DataFrame rby boolean condition +### Slice DataFrame rows by boolean condition {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.loc(s.gt(20)).print() +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let sub_df = df.loc({ rows: df["Count"].gt(10) }) +sub_df.print() ``` {% endtab %} {% endtabs %} ``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` From 0818c61135744ecbd62fae9650739a2e147d76f2 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:15:25 +0000 Subject: [PATCH 087/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 69aa95b..ba18be7 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -287,3 +287,36 @@ sub_df.print() ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` + +### Slice DataFrame rows by multiple boolean conditions + +By design, you can chain as many boolean logic as possible, as long as they resolve to a B + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let sub_df = df.loc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` From 12ce1fde1d38915b7d11f98e4a08758e92a5f177 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:16:27 +0000 Subject: [PATCH 088/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index ba18be7..3d32d0b 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -290,7 +290,9 @@ sub_df.print() ### Slice DataFrame rows by multiple boolean conditions -By design, you can chain as many boolean logic as possible, as long as they resolve to a B +{% hint style="info" %} +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +{% endhint %} {% tabs %} {% tab title="Node" %} @@ -304,7 +306,8 @@ let data = { } let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.loc({ rows: df["Count"].gt(10) }) +let condition = df["Count"].gt(6).and(df["Price"].lt(250)) +let sub_df = df.loc({ rows: condition }) sub_df.print() ``` {% endtab %} From e1cc1c10e5ee2e6ea0bfb627dc875e395afd2f9b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:17:27 +0000 Subject: [PATCH 089/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.loc.md | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 3d32d0b..266df6e 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -271,7 +271,7 @@ let data = { } let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.loc({ rows: df["Count"].gt(10) }) +let sub_df = df.loc({ rows: df["Count"].gt(6) }) sub_df.print() ``` {% endtab %} @@ -284,8 +284,11 @@ sub_df.print() ║ a │ Apples │ 21 │ 200 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` ### Slice DataFrame rows by multiple boolean conditions @@ -323,3 +326,39 @@ sub_df.print() ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` + +### Slice DataFrame with + +{% hint style="info" %} +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let condition = df["Count"].gt(6).and(df["Price"].lt(250)) +let sub_df = df.loc({ rows: condition }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` From c7bbc442c661db2884178f783fc7d62f01d10247 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:18:41 +0000 Subject: [PATCH 090/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 266df6e..ad3b897 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -327,10 +327,10 @@ sub_df.print() ``` -### Slice DataFrame with +### Slice DataFrame with boolean mask {% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +_You can index a DataFrame with an array of boolean values as long as they resolve to a Boolean array of the same length as the DataFrame. _ {% endhint %} {% tabs %} From 481a970ba85d2391386e9748f8b8ffee2ea75c0b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:19:25 +0000 Subject: [PATCH 091/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.loc.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index ad3b897..88d7556 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -330,7 +330,7 @@ sub_df.print() ### Slice DataFrame with boolean mask {% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to a Boolean array of the same length as the DataFrame. _ +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ {% endhint %} {% tabs %} @@ -345,8 +345,8 @@ let data = { } let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let condition = df["Count"].gt(6).and(df["Price"].lt(250)) -let sub_df = df.loc({ rows: condition }) + +let sub_df = df.loc({ rows: [false, true, true, true] }) sub_df.print() ``` {% endtab %} @@ -356,9 +356,12 @@ sub_df.print() ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ +║ b │ Mango │ 5 │ 300 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` From 69b091c51b7c622ce706546487b4d27b15f39cd2 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:20:36 +0000 Subject: [PATCH 092/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.iloc.md | 57 +++++-------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index 714537a..73eee00 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -4,45 +4,26 @@ description: Purely integer-location based indexing for selection by position. # DataFrame.iloc -danfo.DataFrame.**iloc**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{

-

rows: Array, index of row position

-

columns: Array, index of position along columns

-

}

-
+danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -`.iloc()` is primarily integer position based \(from `0` to `length-1` of the axis\). +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. * A string slice object with ints, e.g. `"1:7"` +* A `callable` function with one argument (the calling Series or DataFrame) and that returns valid output for indexing (one of the above). This is useful in method chains, when you don't have a reference to the calling object, but would like to base your selection on some value. _**Note:** only the start index is included._ @@ -69,14 +50,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -92,7 +72,7 @@ sub_df.print() ### **Index by a slice of row and return all columns** -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. The end index is not included. +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 4]". This will return all values between index position 1 and 3. The end index is not included. {% tabs %} {% tab title="Node" %} @@ -111,14 +91,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -152,14 +131,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -209,14 +187,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -266,14 +243,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -322,14 +298,13 @@ sub_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -356,5 +331,3 @@ sub_df.print() {% endtab %} {% endtabs %} - - From 5e901352cd2d19049a9ff50fec37f0f01b49fb2f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:20:55 +0000 Subject: [PATCH 093/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.iloc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index 73eee00..dce97b0 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -23,7 +23,7 @@ Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. * A string slice object with ints, e.g. `"1:7"` -* A `callable` function with one argument (the calling Series or DataFrame) and that returns valid output for indexing (one of the above). This is useful in method chains, when you don't have a reference to the calling object, but would like to base your selection on some value. +* A boolean array. _**Note:** only the start index is included._ From 07195c7932985acb89cc9cd4ef505f84844c1ae0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:22:23 +0000 Subject: [PATCH 094/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.iloc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index dce97b0..6b41cd0 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -72,7 +72,7 @@ sub_df.print() ### **Index by a slice of row and return all columns** -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 4]". This will return all values between index position 1 and 3. The end index is not included. +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. {% tabs %} {% tab title="Node" %} From 6fc0e066be7d5b04d215d075773683e8a8e414ca Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:23:21 +0000 Subject: [PATCH 095/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.iloc.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index 6b41cd0..eacbc99 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -208,7 +208,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after slice + //after indexing ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Count │ Price ║ @@ -263,8 +263,6 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - Shape: (1,1) - ╔═══╤═══════════════════╗ ║ │ Count ║ ╟───┼───────────────────╢ From df598fae9c69901467a511420f23892b9fa37c44 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:24:25 +0000 Subject: [PATCH 096/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.iloc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index eacbc99..f8e0f4c 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -272,7 +272,7 @@ sub_df.print() {% endtab %} {% endtabs %} -### More default slicing behaviour +### More default slicing behavior If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: From 272c95c8d5bc255c8fb8b5da1783d038fc190b93 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:26:03 +0000 Subject: [PATCH 097/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.iloc.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index f8e0f4c..7cdd77c 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -329,3 +329,111 @@ sub_df.print() {% endtab %} {% endtabs %} +### iloc indexing of DataFrame rows by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let sub_df = df.iloc({ rows: df["Count"].gt(6) }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + +### Slice DataFrame rows by multiple boolean conditions + +{% hint style="info" %} +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let condition = df["Count"].gt(6).and(df["Price"].lt(250)) +let sub_df = df.loc({ rows: condition }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +### Slice DataFrame with boolean mask + +{% hint style="info" %} +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) + +let sub_df = df.loc({ rows: [false, true, true, true] }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` From 1f803ac9504e4155fc400e839ea6488d1370138e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:26:38 +0000 Subject: [PATCH 098/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.iloc.md | 108 ------------------ 1 file changed, 108 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index 7cdd77c..f8e0f4c 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -329,111 +329,3 @@ sub_df.print() {% endtab %} {% endtabs %} -### iloc indexing of DataFrame rows by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.iloc({ rows: df["Count"].gt(6) }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -### Slice DataFrame rows by multiple boolean conditions - -{% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let condition = df["Count"].gt(6).and(df["Price"].lt(250)) -let sub_df = df.loc({ rows: condition }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` - -### Slice DataFrame with boolean mask - -{% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) - -let sub_df = df.loc({ rows: [false, true, true, true] }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` From 030a2e619d29ce5fc1c58ef5af45420a23c8b93f Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:28:05 +0000 Subject: [PATCH 099/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sample.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index 0a0f76e..8636b3a 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -4,19 +4,21 @@ description: Return a random sample of rows from DataFrame. # DataFrame.sample -danfo.DataFrame.**sample**\(num, seed\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)\] +danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | +| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | +| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | **Returns:** - ****return **{Promies} resolves to DataFrame** +** **return** {Promies} resolves to DataFrame** ## **Examples** +**Sam** + {% tabs %} {% tab title="Node" %} ```javascript @@ -41,14 +43,13 @@ load_data() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -59,4 +60,3 @@ load_data() ``` {% endtab %} {% endtabs %} - From e6f350950f6ce6fac89bd5f1c5c134823d18ffe8 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:29:07 +0000 Subject: [PATCH 100/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sample.md | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index 8636b3a..0418943 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -15,9 +15,9 @@ danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9j ** **return** {Promies} resolves to DataFrame** -## **Examples** +**** -**Sam** +## Sample a DataFrame randomly {% tabs %} {% tab title="Node" %} @@ -60,3 +60,47 @@ load_data() ``` {% endtab %} {% endtabs %} + +## Sample a DataFrame randomly wit + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(2); + s_df.print(); + +} + +load_data() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ + +``` +{% endtab %} +{% endtabs %} From 160c300b159687029e6606ea4d7cde2dd398a15e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:30:09 +0000 Subject: [PATCH 101/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sample.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index 0418943..ba2498f 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -61,7 +61,9 @@ load_data() {% endtab %} {% endtabs %} -## Sample a DataFrame randomly wit +## Sample a DataFrame randomly with seed + +By setting a seed when using `sample`, you can ensure that the random-sampling is reproduc {% tabs %} {% tab title="Node" %} @@ -69,16 +71,16 @@ load_data() const dfd = require("danfojs-node") async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(3, { seed: 2 }); + s_df.print(); - let df = new dfd.DataFrame(data); - let s_df = await df.sample(2); - s_df.print(); - } load_data() From 6c5ccd1aefc54f6996918ed26c0f4f874f10f3b8 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:30:44 +0000 Subject: [PATCH 102/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sample.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index ba2498f..73e057a 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -63,7 +63,7 @@ load_data() ## Sample a DataFrame randomly with seed -By setting a seed when using `sample`, you can ensure that the random-sampling is reproduc +By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. {% tabs %} {% tab title="Node" %} @@ -96,12 +96,16 @@ load_data() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} From 385b353955975f028c15f0cae3a04ab6b80514aa Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:31:54 +0000 Subject: [PATCH 103/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.add.md | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index 3277882..a4ac6bc 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -1,23 +1,23 @@ --- -description: 'Get Addition of DataFrame and other, element-wise (binary operator add).' +description: Get Addition of DataFrame and other, element-wise (binary operator add). --- # DataFrame.add -danfo.DataFrame.**add**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)\] +danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | --------------------------------------------------------------------- | ------------ | +| other | DataFrame, Series, Array or Scalar | Object to ad with | | +| option | Object |

{

axis: 0 for row, 1 for column

}

| { axis: 1 } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Addition of **scalar to** DataFrame: +### Addition of** scalar to **DataFrame: {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -59,7 +58,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of **Series to** DataFrame along the column axis: +### Addition of** Series to **DataFrame along the column axis: {% tabs %} {% tab title="Node" %} @@ -81,14 +80,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -104,7 +102,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of ****DataFrame to a DataFrame +### Addition of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -129,14 +127,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -152,7 +149,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of ****JavaScript Array to DataFrame +### Addition of** **JavaScript Array to DataFrame {% tabs %} {% tab title="Node" %} @@ -173,14 +170,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -196,5 +192,3 @@ df_new.print() {% endtab %} {% endtabs %} - - From ec5d993ecea1f7bb0a181701cfe8696ddf1b9f44 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:33:33 +0000 Subject: [PATCH 104/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.add.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index a4ac6bc..345717d 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -6,10 +6,10 @@ description: Get Addition of DataFrame and other, element-wise (binary operator danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | --------------------------------------------------------------------- | ------------ | -| other | DataFrame, Series, Array or Scalar | Object to ad with | | -| option | Object |

{

axis: 0 for row, 1 for column

}

| { axis: 1 } | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** @@ -17,7 +17,7 @@ danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9 ## **Examples** -### Addition of** scalar to **DataFrame: +### Addition of** scalar to **DataFrame al {% tabs %} {% tab title="Node" %} From 43414720e68c902efed0e7e6f86ccbd5a3498c13 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:34:27 +0000 Subject: [PATCH 105/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.add.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index 345717d..b176403 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -17,15 +17,17 @@ danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9 ## **Examples** -### Addition of** scalar to **DataFrame al +### Addition of** scalar to **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - {"Col2": [23, 20, 10, 24]} +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) let df_new = df.add(2) @@ -58,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** Series to **DataFrame along the column axis: +### Addition of** Series to **DataFrame along the row axis {% tabs %} {% tab title="Node" %} From 726a8cbd0648f5f61822958e97247f875da47d1d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:35:47 +0000 Subject: [PATCH 106/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.add.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index b176403..f2f93cc 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** Series to **DataFrame along the row axis +### Addition of** Series to **DataFrame along the row axis 0 {% tabs %} {% tab title="Node" %} From 1e2d84c77fdb6264534eb08ecf08031df674ee25 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:36:49 +0000 Subject: [PATCH 107/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.add.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index f2f93cc..557d7e0 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -60,21 +60,22 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** Series to **DataFrame along the row axis 0 +### Addition of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } - let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.add(sf, axis = 1) +let df_new = df.add(sf, { axis: 1 }) df_new.print() ``` @@ -151,7 +152,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** **JavaScript Array to DataFrame +### Addition of** ** Array to DataFrame along {% tabs %} {% tab title="Node" %} From 827408552699fa36ed7d6ecd8b3dcf92d3743aa4 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:38:23 +0000 Subject: [PATCH 108/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.add.md | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index 557d7e0..ab33851 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -152,20 +152,22 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** ** Array to DataFrame along +### Addition of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + let df = new dfd.DataFrame(data) -let val = [2,2] +let val = [2, 2, 2, 2] -let df_new = df.add(val, axis=1) +let df_new = df.add(val, { axis: 0 }) df_new.print() ``` @@ -180,17 +182,18 @@ df_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From 295cdb068ac27586adaf93e043f344defacf2291 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:39:26 +0000 Subject: [PATCH 109/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.add.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index ab33851..467c143 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -198,3 +198,49 @@ df_new.print() {% endtab %} {% endtabs %} +### Addition works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.add(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + From 3a5ae78d99ef55de3cd5d166ffa325a812c9c63b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:40:48 +0000 Subject: [PATCH 110/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sub.md | 174 +++++++++++------- 1 file changed, 110 insertions(+), 64 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index 439c9cb..bfa7be7 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -1,31 +1,33 @@ --- -description: 'Get Subtraction of dataframe and other, element-wise (binary operator sub).' +description: Get Subtraction of dataframe and other, element-wise (binary operator sub). --- # DataFrame.sub -danfo.DataFrame.**sub**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L365)\] +danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Subtraction of **scalar from** DataFrame: +### Subtraction of** scalar to **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) let df_new = df.sub(2) @@ -36,44 +38,44 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Subtraction of **Series from** DataFrame along the column axis: +### Addition of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } - let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -81,37 +83,36 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ -║ 0 │ -3 │ -2 ║ +║ 0 │ 5 │ 8 ║ ╟───┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ -3 ║ +║ 1 │ 8 │ 7 ║ ╟───┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ -5 ║ +║ 2 │ 9 │ 5 ║ ╟───┼───────────────────┼───────────────────╢ -║ 3 │ -3 │ -1 ║ +║ 3 │ 5 │ 9 ║ ╚═══╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Subtraction of ****DataFrame from a DataFrame +### Addition of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") +const dfd = require("danfojs") -let data = {"Col1": [1, 4, 5, 0], +let data = {"Col1": [1, 4, 5, 0], "Col2": [2, 0, 1, 4]} let data2 = {"new_col1": [1, 5, 20, 10], @@ -120,7 +121,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.sub(df2) +let df_new = df.add(df2) df_new.print() @@ -129,43 +130,44 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ -18 ║ +║ 0 │ 2 │ 22 ║ ╟───┼───────────────────┼───────────────────╢ -║ 1 │ -1 │ -2 ║ +║ 1 │ 9 │ 2 ║ ╟───┼───────────────────┼───────────────────╢ -║ 2 │ -15 │ 0 ║ +║ 2 │ 25 │ 2 ║ ╟───┼───────────────────┼───────────────────╢ -║ 3 │ -10 │ 2 ║ +║ 3 │ 10 │ 6 ║ ╚═══╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Subtraction of ****JavaScript Array from Array +### Addition of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs") +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - let df = new dfd.DataFrame(data) -let val = [2,2] +let val = [2, 2, 2, 2] -let df_new = df.sub(val, axis=1) +let df_new = df.add(val, { axis: 0 }) df_new.print() ``` @@ -173,28 +175,72 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} +### Addition works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.add(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} From 6a7dcc08b500038419e14995d5b7e4f5d94a8a8e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:41:47 +0000 Subject: [PATCH 111/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sub.md | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index bfa7be7..bc11145 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** Series to **DataFrame along axis 0 +### Subtraction of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -90,22 +90,23 @@ df_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 8 │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 9 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ -3 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ -3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ -5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -3 │ -1 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Addition of** **DataFrame to a DataFrame +### Subtraction of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -121,7 +122,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.add(df2) +let df_new = df.sub(df2) df_new.print() @@ -137,22 +138,23 @@ df_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 2 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 9 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 25 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ -18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ -1 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ -15 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -10 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Addition of** ** Array to DataFrame along axis 0 +### Subtract of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} From 06246fb0caa6b5d547dccbd1a2c327c01413498b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:42:52 +0000 Subject: [PATCH 112/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.sub.md | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index bc11145..e595e57 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -154,7 +154,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtract of** ** Array to DataFrame along axis 0 +### Subtraction of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -169,7 +169,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -let df_new = df.add(val, { axis: 0 }) +let df_new = df.sub(val, { axis: 0 }) df_new.print() ``` @@ -187,20 +187,21 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ +║ 0 │ 8 │ 21 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ +║ 1 │ 43 │ 18 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ +║ 2 │ 54 │ 8 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ +║ 3 │ 8 │ 22 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Addition works inplace +### Subtraction works inplace {% tabs %} {% tab title="Node" %} @@ -215,7 +216,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -df.add(val, { axis: 0, inplace: true }) +df.sub(val, { axis: 0, inplace: true }) df.print() ``` @@ -233,15 +234,16 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ +║ 0 │ 8 │ 21 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ +║ 1 │ 43 │ 18 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ +║ 2 │ 54 │ 8 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ +║ 3 │ 8 │ 22 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From 3697da58771c916f9477aaba591de4259f648c6a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:43:17 +0000 Subject: [PATCH 113/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mul.md | 207 +++++++++++------- 1 file changed, 129 insertions(+), 78 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 6f042d0..32ffdb2 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -1,34 +1,36 @@ --- -description: 'Get Multiplication of dataframe and other, element-wise (binary operator mul).' +description: Get Multiplication of dataframe and other, element-wise (binary operator mul). --- # DataFrame.mul -danfo.DataFrame.**mul**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L383)\] +danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Multiplication of ****DataFrame with a scalar value: +### Subtraction of** scalar to **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let df_new = df.mul(2) +let df_new = df.sub(2) df_new.print() ``` @@ -36,44 +38,44 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Multiplication of ****DataFrame with a Series along the column axis: +### Subtraction of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } - let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.mul(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` @@ -81,36 +83,37 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 4 │ 15 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 16 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ -3 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ -3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ -5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -3 │ -1 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Multiplication of ****DataFrame with a DataFrame +### Subtraction of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") -let data = {"Col1": [1, 4, 5, 0], +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], "Col2": [2, 0, 1, 4]} let data2 = {"new_col1": [1, 5, 20, 10], @@ -119,7 +122,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.mul(df2) +let df_new = df.sub(df2) df_new.print() @@ -128,43 +131,45 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 100 │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ -18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ -1 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ -15 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -10 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Multiplication of ****DataFrame with a JavaScript Array +### Subtraction of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + let df = new dfd.DataFrame(data) -let val = [2,2] +let val = [2, 2, 2, 2] -let df_new = df.mul(val, axis=1) +let df_new = df.sub(val, { axis: 0 }) df_new.print() ``` @@ -172,28 +177,74 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Subtraction works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.sub(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` ``` {% endtab %} {% endtabs %} +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} From a655a2b60d644ea7a0469a605758124a7709ab03 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:44:47 +0000 Subject: [PATCH 114/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mul.md | 20 +++++++++---------- .../dataframe/danfo.dataframe.sub.md | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 32ffdb2..869a938 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -17,7 +17,7 @@ danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/d ## **Examples** -### Subtraction of** scalar to **DataFrame along default axis 1 +### Multiplication of** scalar to **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -30,7 +30,7 @@ let data = { } let df = new dfd.DataFrame(data) -let df_new = df.sub(2) +let df_new = df.mul(2) df_new.print() ``` @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** Series to **DataFrame along axis 0 +### Multiplication of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -75,7 +75,7 @@ let data = { let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, { axis: 1 }) +let df_new = df.mul(sf, { axis: 1 }) df_new.print() ``` @@ -106,7 +106,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** **DataFrame to a DataFrame +### Multiplication of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -122,7 +122,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.sub(df2) +let df_new = df.mul(df2) df_new.print() @@ -154,7 +154,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** ** Array to DataFrame along axis 0 +### Multiplication of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -169,7 +169,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -let df_new = df.sub(val, { axis: 0 }) +let df_new = df.mul(val, { axis: 0 }) df_new.print() ``` @@ -201,7 +201,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction works inplace +### Multiplication works inplace {% tabs %} {% tab title="Node" %} @@ -216,7 +216,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -df.sub(val, { axis: 0, inplace: true }) +df.mul(val, { axis: 0, inplace: true }) df.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index e595e57..aded5cb 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -4,7 +4,7 @@ description: Get Subtraction of dataframe and other, element-wise (binary operat # DataFrame.sub -danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] | Parameters | Type | Description | Default | | ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | From 29ea830cf35c1db9e2aff4e9307c08df2091ffc0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:45:38 +0000 Subject: [PATCH 115/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mul.md | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 869a938..380ccef 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -48,13 +48,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ +║ 0 │ 20 │ 46 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ +║ 1 │ 90 │ 40 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ +║ 2 │ 112 │ 20 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ +║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} @@ -93,13 +93,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ -3 │ -2 ║ +║ 0 │ 4 │ 15 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ -3 ║ +║ 1 │ 16 │ 10 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ -5 ║ +║ 2 │ 20 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -3 │ -1 ║ +║ 3 │ 4 │ 20 ║ ╚════════════╧═══════════════════╧═══════════════════╝ ``` @@ -141,15 +141,16 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ -18 ║ +║ 0 │ 1 │ 40 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ -1 │ -2 ║ +║ 1 │ 20 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ -15 │ 0 ║ +║ 2 │ 100 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -10 │ 2 ║ +║ 3 │ 0 │ 8 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From 0644568bc677b0cf227dcfd17f4c1564d5bd9451 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:46:00 +0000 Subject: [PATCH 116/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.mul.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 380ccef..3627b59 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -188,16 +188,17 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ +║ 0 │ 20 │ 46 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ +║ 1 │ 90 │ 40 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ +║ 2 │ 112 │ 20 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ +║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} @@ -235,13 +236,13 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ +║ 0 │ 20 │ 46 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ +║ 1 │ 90 │ 40 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ +║ 2 │ 112 │ 20 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ +║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ From db6fe88d02c648cc053a683418070b300f11c142 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:47:05 +0000 Subject: [PATCH 117/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.div.md | 202 +++++++++++------- 1 file changed, 126 insertions(+), 76 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index e6977b7..ae9df76 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -6,29 +6,30 @@ description: >- # DataFrame.div -danfo.DataFrame.**div**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L401)\] +danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Division of ****DataFrame with a scalar value: +### Division of** scalar to **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) let df_new = df.div(2) @@ -39,44 +40,44 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Division of ****DataFrame with a Series along the column axis: +### Division of** Series to **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } - let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.div(sf, axis = 1) +let df_new = df.div(sf, { axis: 1 }) df_new.print() ``` @@ -84,38 +85,37 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0.25 │ 0.60000002384... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0.40000000596... ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 1.25 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0.25 │ 0.80000001192... ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 4 │ 15 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 16 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 4 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Division of ****DataFrame with a DataFrame +### Division of** **DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") +const dfd = require("danfojs") -let data = {"Col1": [1, 4, 5, 0], +let data = {"Col1": [1, 4, 5, 0], "Col2": [2, 0, 1, 4]} let data2 = {"new_col1": [1, 5, 20, 10], @@ -133,43 +133,46 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0.10000000149... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 0.80000001192... │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 0.25 │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 100 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 8 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + ``` {% endtab %} {% endtabs %} -### Division of ****DataFrame with a JavaScript Array +### Division of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + let df = new dfd.DataFrame(data) -let val = [2,2] +let val = [2, 2, 2, 2] -let df_new = df.div(val, axis=1) +let df_new = df.div(val, { axis: 0 }) df_new.print() ``` @@ -177,28 +180,75 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Division works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.div(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` ``` {% endtab %} {% endtabs %} +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} From 4a23b0a95a8f86b992fe26a3c61e9d8d3ba24566 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:48:09 +0000 Subject: [PATCH 118/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.div.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index ae9df76..8ba7875 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -50,14 +50,15 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ +║ 0 │ 5 │ 11.5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ +║ 1 │ 22.5 │ 10 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ +║ 2 │ 28 │ 5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ +║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} @@ -95,15 +96,16 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 4 │ 15 ║ +║ 0 │ 0.25 │ 0.6000000238418… ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 16 │ 10 ║ +║ 1 │ 1 │ 0.4000000059604… ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 0 ║ +║ 2 │ 1.25 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 20 ║ +║ 3 │ 0.25 │ 0.8000000119209… ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From 46e46a731025325830b0b0b606009bda45142b98 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:48:57 +0000 Subject: [PATCH 119/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.div.md | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index 8ba7875..226c4d1 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -145,13 +145,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 40 ║ +║ 0 │ 1 │ 0.1000000014901… ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 0 ║ +║ 1 │ 0.8000000119209… │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 100 │ 1 ║ +║ 2 │ 0.25 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 8 ║ +║ 3 │ 0 │ 2 ║ ╚════════════╧═══════════════════╧═══════════════════╝ @@ -192,17 +192,15 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ +║ 0 │ 5 │ 11.5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ +║ 1 │ 22.5 │ 10 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ +║ 2 │ 28 │ 5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ +║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - - ``` {% endtab %} {% endtabs %} @@ -240,13 +238,13 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ +║ 0 │ 5 │ 11.5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ +║ 1 │ 22.5 │ 10 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ +║ 2 │ 28 │ 5 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ +║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ From f8c5ad0cba8d934555cb424afe631b232c8f8544 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:49:55 +0000 Subject: [PATCH 120/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.pow.md | 210 +++++++++++------- 1 file changed, 133 insertions(+), 77 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index aa7a15e..923b5e0 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -6,32 +6,33 @@ description: >- # DataFrame.pow -danfo.DataFrame.**pow**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L418)\] +danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Exponent of ****DataFrame with a scalar value: +### Exponential of** scalar with **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let df_new = df.pow(2) +let df_new = df.div(2) df_new.print() ``` @@ -39,43 +40,45 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} -### Exponent of ****DataFrame with a Series along the column axis: +### Exponential of** Series with **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.pow(sf, axis = 1) +let df_new = df.div(sf, { axis: 1 }) df_new.print() ``` @@ -83,44 +86,47 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 243 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 256 │ 32 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 625 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 1024 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0.25 │ 0.6000000238418… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0.4000000059604… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1.25 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0.25 │ 0.8000000119209… ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + ``` {% endtab %} {% endtabs %} -### Exponent of ****DataFrame with a DataFrame +### Exponential of** **DataFrame wi a DataFrame {% tabs %} {% tab title="Node" %} ```javascript -let data = { "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] } - +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + let data2 = {"new_col1": [1, 5, 20, 10], "new_Col2": [20, 2, 1, 2]} let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.pow(df2) +let df_new = df.div(df2) df_new.print() @@ -129,43 +135,46 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1048576 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1024 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 95367433551872 │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 16 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0.1000000014901… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0.8000000119209… │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0.25 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + ``` {% endtab %} {% endtabs %} -### Exponent of ****DataFrame with a JavaScript Array +### Division of** ** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + let df = new dfd.DataFrame(data) -let val = [2,2] +let val = [2, 2, 2, 2] -let df_new = df.pow(val, axis=1) +let df_new = df.div(val, { axis: 0 }) df_new.print() ``` @@ -173,25 +182,72 @@ df_new.print() {% tab title="Browser" %} ``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} +### Division works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.div(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 12167 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 8000 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 1000 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 13824 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + ``` {% endtab %} {% endtabs %} From 5f54c1ac8717f2fc0cb59716431d3e6c41f56e64 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:50:35 +0000 Subject: [PATCH 121/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.pow.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index 923b5e0..a86ba93 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -32,7 +32,7 @@ let data = { } let df = new dfd.DataFrame(data) -let df_new = df.div(2) +let df_new = df.pow(2) df_new.print() ``` @@ -78,7 +78,7 @@ let data = { let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.div(sf, { axis: 1 }) +let df_new = df.pow(sf, { axis: 1 }) df_new.print() ``` @@ -110,7 +110,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** **DataFrame wi a DataFrame +### Exponential of** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -126,7 +126,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.div(df2) +let df_new = df.pow(df2) df_new.print() @@ -159,7 +159,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** ** Array to DataFrame along axis 0 +### Exponential of** ** Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -174,7 +174,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -let df_new = df.div(val, { axis: 0 }) +let df_new = df.pow(val, { axis: 0 }) df_new.print() ``` @@ -205,7 +205,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division works inplace +### Exponential works inplace {% tabs %} {% tab title="Node" %} @@ -220,7 +220,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -df.div(val, { axis: 0, inplace: true }) +df.pow(val, { axis: 0, inplace: true }) df.print() ``` From 4c89dbf6263341f8a79d3c40bb64db74d64c8fa0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:50:59 +0000 Subject: [PATCH 122/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.div.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index 226c4d1..54123d9 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -19,7 +19,7 @@ danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/d ## **Examples** -### Division of** scalar to **DataFrame along default axis 1 +### Division of** scalar with **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -63,7 +63,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** Series to **DataFrame along axis 0 +### Division of** Series with **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -110,7 +110,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** **DataFrame to a DataFrame +### Division of** **DataFrame **with** a DataFrame {% tabs %} {% tab title="Node" %} @@ -159,7 +159,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** ** Array to DataFrame along axis 0 +### Division of** ** Array **with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} From ebd4027b14678db07458514ca64c153f68956239 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:52:06 +0000 Subject: [PATCH 123/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.pow.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index a86ba93..4bf90e6 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -50,15 +50,17 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ +║ 0 │ 100 │ 529 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ +║ 1 │ 2025 │ 400 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ +║ 2 │ 3136 │ 100 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ +║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + + ``` {% endtab %} {% endtabs %} @@ -96,16 +98,17 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0.25 │ 0.6000000238418… ║ +║ 0 │ 1 │ 243 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0.4000000059604… ║ +║ 1 │ 256 │ 32 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1.25 │ 0 ║ +║ 2 │ 625 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0.25 │ 0.8000000119209… ║ +║ 3 │ 1 │ 1024 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From fede734851fa58fda1172623da7042c5a0c3f29d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:52:44 +0000 Subject: [PATCH 124/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.pow.md | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index 4bf90e6..634e6e2 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -148,16 +148,17 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0.1000000014901… ║ +║ 0 │ 1 │ 1048576 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.8000000119209… │ 0 ║ +║ 1 │ 1024 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0.25 │ 1 ║ +║ 2 │ 95367433551872 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 2 ║ +║ 3 │ 0 │ 16 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} @@ -195,15 +196,16 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ +║ 0 │ 100 │ 529 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ +║ 1 │ 2025 │ 400 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ +║ 2 │ 3136 │ 100 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ +║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} @@ -241,16 +243,17 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ +║ 0 │ 100 │ 529 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ +║ 1 │ 2025 │ 400 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ +║ 2 │ 3136 │ 100 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ +║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ + ``` {% endtab %} {% endtabs %} From ad2f2451dfd95b03a8488fbce16e62a210307cd2 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:53:50 +0000 Subject: [PATCH 125/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mod.md | 225 +++++++++++------- 1 file changed, 142 insertions(+), 83 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index 1f66ce1..1a04b2f 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -1,35 +1,36 @@ --- -description: 'Get Modulo of DataFrame and other, element-wise (binary operator mod).' +description: Get Modulo of DataFrame and other, element-wise (binary operator mod). --- # DataFrame.mod -danfo.DataFrame.**mod**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L436)\] +danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array or Scalar | Object to modulo with | | -| axis | Int | 0 for row, 1 for column | 0 | +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Modulo of ****DataFrame with a scalar value: +### Modulo of** scalar with **DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let df_new = df.mod(2) +let df_new = df.pow(2) df_new.print() ``` @@ -37,44 +38,47 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + ``` {% endtab %} {% endtabs %} -### Modulo of ****DataFrame with a Series along the column axis: +### Modulo of** Series with **DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs") +const dfd = require("danfojs-node") +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]}] - let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) +let sf = new dfd.Series([4, 5]) -let df_new = df.mod(sf, axis=1) +let df_new = df.pow(sf, { axis: 1 }) df_new.print() ``` @@ -82,46 +86,48 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 6 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 243 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 256 │ 32 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 625 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 1024 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + ``` {% endtab %} {% endtabs %} -### Modulo of ****DataFrame with a DataFrame +### Exponential of** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") +const dfd = require("danfojs") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.mod(df2) +let df_new = df.pow(df2) df_new.print() @@ -130,43 +136,47 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 56 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 1048576 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1024 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 95367433551872 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 16 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + ``` {% endtab %} {% endtabs %} -### Modulo of ****DataFrame with a JavaScript Array +### Exponential of** ** Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + let df = new dfd.DataFrame(data) -let val = [10,40] +let val = [2, 2, 2, 2] -let df_new = df.mod(val, axis=1) +let df_new = df.pow(val, { axis: 0 }) df_new.print() ``` @@ -174,25 +184,74 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Exponential works inplace + +{% tabs %} +{% tab title="Node" %} ```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 6 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.pow(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + ``` {% endtab %} {% endtabs %} From b5140dfc7f7129b99f9b0ec8f95250c601480524 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:55:03 +0000 Subject: [PATCH 126/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mod.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index 1a04b2f..2e38bed 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -30,7 +30,7 @@ let data = { } let df = new dfd.DataFrame(data) -let df_new = df.pow(2) +let df_new = df.mod(2) df_new.print() ``` @@ -48,13 +48,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ +║ 0 │ 0 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ +║ 1 │ 1 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ +║ 2 │ 0 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ +║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ @@ -78,7 +78,7 @@ let data = { let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.pow(sf, { axis: 1 }) +let df_new = df.mod(sf, { axis: 1 }) df_new.print() ``` @@ -111,7 +111,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** **DataFrame with a DataFrame +### Modulo of** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -127,7 +127,7 @@ let data2 = {"new_col1": [1, 5, 20, 10], let df = new dfd.DataFrame(data) let df2 = new dfd.DataFrame(data2) -let df_new = df.pow(df2) +let df_new = df.mod(df2) df_new.print() @@ -161,7 +161,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** ** Array with DataFrame along axis 0 +### Modulo of** ** Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -176,7 +176,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -let df_new = df.pow(val, { axis: 0 }) +let df_new = df.mod(val, { axis: 0 }) df_new.print() ``` @@ -208,7 +208,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential works inplace +### Modulo works inplace {% tabs %} {% tab title="Node" %} @@ -223,7 +223,7 @@ let data = { let df = new dfd.DataFrame(data) let val = [2, 2, 2, 2] -df.pow(val, { axis: 0, inplace: true }) +df.mod(val, { axis: 0, inplace: true }) df.print() ``` From b6865c09cbf0f410be4f2013c77d5da2c787a9fb Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:55:57 +0000 Subject: [PATCH 127/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mod.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index 2e38bed..8cd7e9f 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -96,13 +96,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 243 ║ +║ 0 │ 1 │ 3 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 256 │ 32 ║ +║ 1 │ 0 │ 2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 625 │ 0 ║ +║ 2 │ 1 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 1024 ║ +║ 3 │ 1 │ 4 ║ ╚════════════╧═══════════════════╧═══════════════════╝ @@ -146,13 +146,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1048576 ║ +║ 0 │ 0 │ 2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1024 │ 0 ║ +║ 1 │ 4 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 95367433551872 │ 1 ║ +║ 2 │ 5 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 16 ║ +║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ @@ -194,13 +194,13 @@ df_new.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ +║ 0 │ 0 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ +║ 1 │ 1 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ +║ 2 │ 0 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ +║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ @@ -241,13 +241,13 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ +║ 0 │ 0 │ 1 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ +║ 1 │ 1 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ +║ 2 │ 0 │ 0 ║ ╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ +║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ From 2bf7978c4abb98dcb20ec6bc6bdb3a6b840996b4 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:57:24 +0000 Subject: [PATCH 128/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.mean.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mean.md b/api-reference/dataframe/danfo.dataframe.mean.md index 754ed57..a7d4202 100644 --- a/api-reference/dataframe/danfo.dataframe.mean.md +++ b/api-reference/dataframe/danfo.dataframe.mean.md @@ -4,19 +4,19 @@ description: Return the mean of the values for the requested axis. # DataFrame.mean -danfo.DataFrame.**mean**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)\] +danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Calculates the mean of values along default axis 1 \(column\) +## Calculates the mean of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ df.mean().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -68,7 +67,7 @@ df.mean().print() {% endtab %} {% endtabs %} -## Calculates the mean of values along row axis \(0\) +## Calculates the mean of values along row axis (0) {% tabs %} {% tab title="Node" %} @@ -86,14 +85,13 @@ df.mean(axis=0).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -120,4 +118,3 @@ df.mean(axis=0).print() ``` {% endtab %} {% endtabs %} - From 19edbd70ba279287f369eb6f8aac418a7286f9a8 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:58:11 +0000 Subject: [PATCH 129/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.mean.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mean.md b/api-reference/dataframe/danfo.dataframe.mean.md index a7d4202..c22a8e2 100644 --- a/api-reference/dataframe/danfo.dataframe.mean.md +++ b/api-reference/dataframe/danfo.dataframe.mean.md @@ -16,7 +16,7 @@ danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/da ## **Examples** -## Calculates the mean of values along default axis 1 (column) +## Computes the mean of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -67,7 +67,7 @@ df.mean().print() {% endtab %} {% endtabs %} -## Calculates the mean of values along row axis (0) +## Computes the mean of values along row axis (0) {% tabs %} {% tab title="Node" %} From e450ad05d5bd20305753dd5ad5f7d9a1eed6a72c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:58:39 +0000 Subject: [PATCH 130/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.mean.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.mean.md b/api-reference/dataframe/danfo.dataframe.mean.md index c22a8e2..fbc005e 100644 --- a/api-reference/dataframe/danfo.dataframe.mean.md +++ b/api-reference/dataframe/danfo.dataframe.mean.md @@ -74,12 +74,12 @@ df.mean().print() ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] df.print() let df = new dfd.DataFrame(data) -df.mean(axis=0).print() +df.mean({ axis: 0 }).print() ``` {% endtab %} From d6817fa22d1128733055490f37a1e2673c427eb4 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 17:59:35 +0000 Subject: [PATCH 131/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.median.md | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.median.md b/api-reference/dataframe/danfo.dataframe.median.md index 7b5e45e..e75519f 100644 --- a/api-reference/dataframe/danfo.dataframe.median.md +++ b/api-reference/dataframe/danfo.dataframe.median.md @@ -4,19 +4,19 @@ description: Return the median of the values for the requested axis. # DataFrame.median -danfo.DataFrame.**median**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L474)\] +danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Calculates the median of values along default axis 1 \(column\) +## Calculates the median of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ df.median().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -68,7 +67,7 @@ df.median().print() {% endtab %} {% endtabs %} -## Calculates the median of values along row axis \(0\) +## Calculates the median of values along row axis (0) {% tabs %} {% tab title="Node" %} @@ -80,20 +79,19 @@ cols = ["A", "B", "C"] df.print() let df = new dfd.DataFrame(data) -df.median(axis=0).print() +df.median({axis:0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -120,4 +118,3 @@ df.median(axis=0).print() ``` {% endtab %} {% endtabs %} - From ab90e10e405e33c0560ea515d2e6a8e9e558ac30 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:00:16 +0000 Subject: [PATCH 132/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.min.md | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.min.md b/api-reference/dataframe/danfo.dataframe.min.md index 3a65ec4..93b9bf8 100644 --- a/api-reference/dataframe/danfo.dataframe.min.md +++ b/api-reference/dataframe/danfo.dataframe.min.md @@ -4,19 +4,19 @@ description: Return the minimum of the values for the requested axis. # DataFrame.min -danfo.DataFrame.**min**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L499)\] +danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Returns the minimum value along default axis 1 \(column\) +## Returns the minimum value along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ df.min().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -68,7 +67,7 @@ df.min().print() {% endtab %} {% endtabs %} -## Return the minimum value along row axis \(0\) +## Return the minimum value along row axis (0) {% tabs %} {% tab title="Node" %} @@ -80,20 +79,19 @@ cols = ["A", "B", "C"] df.print() let df = new dfd.DataFrame(data) -df.min(axis=0).print() +df.min({axis: 0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -120,4 +118,3 @@ df.min(axis=0).print() ``` {% endtab %} {% endtabs %} - From a2e800b471c0115c3fe6bb37f455158633da74ab Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:00:36 +0000 Subject: [PATCH 133/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.max.md | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.max.md b/api-reference/dataframe/danfo.dataframe.max.md index bb8b088..f8e9124 100644 --- a/api-reference/dataframe/danfo.dataframe.max.md +++ b/api-reference/dataframe/danfo.dataframe.max.md @@ -4,19 +4,19 @@ description: Return the maximum of the values for the requested axis. # DataFrame.max -danfo.DataFrame.**max**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L519)\] +danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Return the maximum value along default axis 1 \(column\) +## Return the maximum value along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -34,14 +34,13 @@ df.max().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -67,7 +66,7 @@ df.max().print() {% endtab %} {% endtabs %} -## Return the maximum value along row axis \(0\) +## Return the maximum value along row axis (0) {% tabs %} {% tab title="Node" %} @@ -78,20 +77,19 @@ cols = ["A", "B", "C"] df.print() let df = new dfd.DataFrame(data) -df.max(axis=0).print() +df.max({axis:0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,4 +116,3 @@ df.max(axis=0).print() ``` {% endtab %} {% endtabs %} - From f9ca3ba701fd6035ae1c0c627c4c811b6636be51 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:01:03 +0000 Subject: [PATCH 134/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.std.md | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.std.md b/api-reference/dataframe/danfo.dataframe.std.md index 0a93231..b94372e 100644 --- a/api-reference/dataframe/danfo.dataframe.std.md +++ b/api-reference/dataframe/danfo.dataframe.std.md @@ -4,19 +4,19 @@ description: Return sample standard deviation over requested axis. # DataFrame.std -danfo.DataFrame.**var**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L563)\] +danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Calculates the standard deviation of values along default axis 1 \(column\) +## Calculates the standard deviation of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -32,14 +32,13 @@ df.std().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -53,7 +52,7 @@ df.std().print() {% endtab %} {% endtabs %} -## Calculates the standard deviation of values along row axis \(0\) +## Calculates the standard deviation of values along row axis (0) {% tabs %} {% tab title="Node" %} @@ -63,20 +62,19 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] let df = new dfd.DataFrame(data) -df.std(axis=0).print() +df.std({axis:0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -92,7 +90,5 @@ df.std(axis=0).print() {% endtab %} {% endtabs %} -## - - +## From a6679dda7bc674dd20f8173616c3ea4744964465 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:01:30 +0000 Subject: [PATCH 135/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.var.md | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.var.md b/api-reference/dataframe/danfo.dataframe.var.md index 6b88002..b95bb1a 100644 --- a/api-reference/dataframe/danfo.dataframe.var.md +++ b/api-reference/dataframe/danfo.dataframe.var.md @@ -4,19 +4,19 @@ description: Return unbiased variance over requested axis. # DataFrame.var -danfo.DataFrame.**var**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L563)\] +danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Calculate variance of values along default axis 1 \(column\) +## Calculate variance of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -32,14 +32,13 @@ df.var().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -53,7 +52,7 @@ df.var().print() {% endtab %} {% endtabs %} -## Calculate variance of values along row axis \(0\) +## Calculate variance of values along row axis (0) {% tabs %} {% tab title="Node" %} @@ -63,20 +62,19 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] let df = new dfd.DataFrame(data) -df.var(axis=0).print() +df.var({axis:0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -94,5 +92,3 @@ df.var(axis=0).print() - - From 26aab84c5ff9f37d0ade4aeef7645febab6226d6 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:02:33 +0000 Subject: [PATCH 136/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.count.md | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.count.md b/api-reference/dataframe/danfo.dataframe.count.md index 23c6948..9e9916e 100644 --- a/api-reference/dataframe/danfo.dataframe.count.md +++ b/api-reference/dataframe/danfo.dataframe.count.md @@ -6,19 +6,19 @@ description: >- # DataFrame.count -danfo.DataFrame.**count**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L587)\] +danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row and 1 for columns | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -## Count Non-NaN values along default axis 1 \(column\) +## Count Non-NaN values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df.count().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══════╤══════════════════════╗ ║ │ 0 ║ ╟───────┼──────────────────────╢ @@ -57,7 +56,7 @@ df.count().print() {% endtab %} {% endtabs %} -## Count Non-NaN values along row axis \(0\) +## Count Non-NaN values along row axis (0) {% tabs %} {% tab title="Node" %} @@ -66,23 +65,22 @@ const dfd = require("danfojs-node") let data = { "Name": ["Apples", "Mango", "Banana", undefined], "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] }] + "Price": [200, 300, 40, 250] } let df = new dfd.DataFrame(data) -df.count({axis: 0).print() +df.count({axis: 0}).print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -98,7 +96,5 @@ df.count({axis: 0).print() {% endtab %} {% endtabs %} -## - - +## From a3217b50636ddebe682a528f6a17c6014f8a1135 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:04:06 +0000 Subject: [PATCH 137/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.round.md | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.round.md b/api-reference/dataframe/danfo.dataframe.round.md index b85c27e..39bb719 100644 --- a/api-reference/dataframe/danfo.dataframe.round.md +++ b/api-reference/dataframe/danfo.dataframe.round.md @@ -4,19 +4,20 @@ description: Round elements in a DataFrame to a specified number of decimal plac # DataFrame.round -danfo.DataFrame.**round**\(dp\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)\] +danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| dp | Int | Number of decimal places to round to | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | --------------- | +| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { inplace: fa } | **Returns:** - ****return **DataFrame** +** **return** Series** ## **Examples** -## Round elements to 1dp \(Default\) +## Round elements to 1dp (Default) {% tabs %} {% tab title="Node" %} @@ -37,14 +38,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -92,14 +92,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -126,5 +125,4 @@ new_df.print() {% endtab %} {% endtabs %} -## - +## From b145c5e9adec6cce5bdca148373c16720cbfa02a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:05:09 +0000 Subject: [PATCH 138/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.round.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.round.md b/api-reference/dataframe/danfo.dataframe.round.md index 39bb719..32e7c8a 100644 --- a/api-reference/dataframe/danfo.dataframe.round.md +++ b/api-reference/dataframe/danfo.dataframe.round.md @@ -6,14 +6,14 @@ description: Round elements in a DataFrame to a specified number of decimal plac danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | --------------- | -| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { inplace: fa } | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | **Returns:** -** **return** Series** +** **return** DataFrame** ## **Examples** From a9b433ef35498bb9fcaa9188067aedd6f7023e8e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:06:27 +0000 Subject: [PATCH 139/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.cumsum.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.cumsum.md b/api-reference/dataframe/danfo.dataframe.cumsum.md index b1e91f1..02b64df 100644 --- a/api-reference/dataframe/danfo.dataframe.cumsum.md +++ b/api-reference/dataframe/danfo.dataframe.cumsum.md @@ -4,19 +4,19 @@ description: Return cumulative sum over a DataFrame or Series axis. # DataFrame.cumsum -danfo.DataFrame.**cumsum**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)\] +danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------ | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace:

| {axis: 1, inplace: false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -## Cumulative sum of elements along default axis \(row\) +## Cumulative sum of elements along default axis (row) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -58,7 +57,7 @@ new_df.print() {% endtab %} {% endtabs %} -## Cumulative sum of elements along column axis \(1\) +## Cumulative sum of elements along column axis (1) {% tabs %} {% tab title="Node" %} @@ -77,14 +76,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -99,4 +97,3 @@ new_df.print() ``` {% endtab %} {% endtabs %} - From 38f71de734d8ef8abfeb1464ecb61b941ccba4fa Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:06:58 +0000 Subject: [PATCH 140/202] GitBook: No commit message --- api-reference/dataframe/danfo.dataframe.cumsum.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.cumsum.md b/api-reference/dataframe/danfo.dataframe.cumsum.md index 02b64df..4863805 100644 --- a/api-reference/dataframe/danfo.dataframe.cumsum.md +++ b/api-reference/dataframe/danfo.dataframe.cumsum.md @@ -6,9 +6,9 @@ description: Return cumulative sum over a DataFrame or Series axis. danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------ | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace:

| {axis: 1, inplace: false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | **Returns:** From 90aa3adabe2791c4a708f684c7721811c52550be Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:07:35 +0000 Subject: [PATCH 141/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.cummin.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.cummin.md b/api-reference/dataframe/danfo.dataframe.cummin.md index 69b6dea..53f4045 100644 --- a/api-reference/dataframe/danfo.dataframe.cummin.md +++ b/api-reference/dataframe/danfo.dataframe.cummin.md @@ -4,19 +4,19 @@ description: Return cumulative minimum over a DataFrame or Series axis. # DataFrame.cummin -danfo.DataFrame.**cummin**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L717)\] +danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -## Cumulative minimum of elements along default axis \(row\) +## Cumulative minimum of elements along default axis (row) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -58,7 +57,7 @@ new_df.print() {% endtab %} {% endtabs %} -## Cumulative minimum of elements along column axis \(1\) +## Cumulative minimum of elements along column axis (1) {% tabs %} {% tab title="Node" %} @@ -77,14 +76,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -99,4 +97,3 @@ new_df.print() ``` {% endtab %} {% endtabs %} - From cc4b1775c3ef708e899c1ef4dd93f5fc0b602310 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:08:13 +0000 Subject: [PATCH 142/202] GitBook: No commit message --- .../dataframe/danfo.dataframe.cummax.md | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.cummax.md b/api-reference/dataframe/danfo.dataframe.cummax.md index 561b794..c46ae7b 100644 --- a/api-reference/dataframe/danfo.dataframe.cummax.md +++ b/api-reference/dataframe/danfo.dataframe.cummax.md @@ -4,19 +4,19 @@ description: Return cumulative maximum over a DataFrame or Series axis. # DataFrame.cummax -danfo.DataFrame.**cummax**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L739)\] +danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -## Cumulative maximum of elements along default axis \(row\) +## Cumulative maximum of elements along default axis (row) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -58,7 +57,7 @@ new_df.print() {% endtab %} {% endtabs %} -## Cumulative maximum of elements along column axis \(1\) +## Cumulative maximum of elements along column axis (1) {% tabs %} {% tab title="Node" %} @@ -77,14 +76,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -99,4 +97,3 @@ new_df.print() ``` {% endtab %} {% endtabs %} - From 212f04e06965bf92eacd11860fd956dba90b9695 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:17:32 +0000 Subject: [PATCH 143/202] GitBook: [#198] Update API --- README.md | 42 +- SUMMARY.md | 4 +- api-reference/README.md | 4 +- api-reference/configuration-options.md | 13 +- api-reference/dataframe/README.md | 193 ++--- .../dataframe/danfo.dataframe.abs.md | 8 +- .../dataframe/danfo.dataframe.addcolumn.md | 42 +- .../dataframe/danfo.dataframe.apply.md | 47 +- .../dataframe/danfo.dataframe.column.md | 14 +- .../dataframe/danfo.dataframe.copy.md | 9 +- .../dataframe/danfo.dataframe.cumprod.md | 21 +- .../dataframe/danfo.dataframe.describe.md | 10 +- .../dataframe/danfo.dataframe.dropna.md | 49 +- api-reference/dataframe/danfo.dataframe.eq.md | 29 +- .../dataframe/danfo.dataframe.fillna.md | 44 +- api-reference/dataframe/danfo.dataframe.ge.md | 27 +- .../dataframe/danfo.dataframe.groupby.md | 14 +- api-reference/dataframe/danfo.dataframe.gt.md | 35 +- .../dataframe/danfo.dataframe.head.md | 14 +- .../dataframe/danfo.dataframe.isna.md | 8 +- api-reference/dataframe/danfo.dataframe.it.md | 35 +- api-reference/dataframe/danfo.dataframe.le.md | 29 +- api-reference/dataframe/danfo.dataframe.ne.md | 35 +- .../dataframe/danfo.dataframe.query.md | 50 +- .../dataframe/danfo.dataframe.replace.md | 42 +- .../dataframe/danfo.dataframe.sum.md | 21 +- .../dataframe/danfo.dataframe.tail.md | 14 +- api-reference/dataframe/dataframe.dtypes.md | 13 +- api-reference/dataframe/dataframe.ndim.md | 10 +- api-reference/dataframe/dataframe.nunique.md | 96 --- .../dataframe/dataframe.select_dtypes.md | 16 +- api-reference/dataframe/dataframe.shape.md | 8 +- api-reference/dataframe/dataframe.size.md | 48 -- api-reference/dataframe/dataframe.values.md | 10 +- api-reference/general-functions/README.md | 25 +- .../general-functions/danfo.concat.md | 50 +- .../general-functions/danfo.date_range.md | 47 +- .../general-functions/danfo.get_dummies.md | 84 +-- .../general-functions/danfo.labelencoder.md | 13 +- .../general-functions/danfo.merge.md | 53 +- .../general-functions/danfo.minmaxscaler.md | 9 +- .../general-functions/danfo.onehotencoder.md | 13 +- .../general-functions/danfo.standardscaler.md | 13 +- .../general-functions/danfo.to_datetime.md | 200 +++--- api-reference/groupby/groupby.agg.md | 15 +- api-reference/groupby/groupby.count.md | 13 +- api-reference/groupby/groupby.cumsum.md | 13 +- api-reference/groupby/groupby.max.md | 13 +- api-reference/groupby/groupby.mean.md | 13 +- api-reference/groupby/groupby.min.md | 13 +- api-reference/groupby/groupby.std.md | 13 +- api-reference/groupby/groupby.sum.md | 13 +- api-reference/groupby/groupby.var.md | 13 +- api-reference/input-output/README.md | 20 +- api-reference/input-output/danfo.read_csv.md | 212 +----- .../input-output/danfo.read_excel.md | 55 +- api-reference/input-output/danfo.read_json.md | 103 ++- api-reference/plotting/line-charts.md | 7 +- api-reference/plotting/timeseries-plots.md | 8 +- api-reference/series/README.md | 240 ++++--- api-reference/series/series.abs.md | 11 +- api-reference/series/series.add.md | 17 +- api-reference/series/series.append.md | 57 +- api-reference/series/series.apply.md | 26 +- api-reference/series/series.argsort.md | 36 +- api-reference/series/series.copy.md | 7 +- api-reference/series/series.count.md | 7 +- api-reference/series/series.cummax.md | 11 +- api-reference/series/series.cummin.md | 11 +- api-reference/series/series.cumprod.md | 11 +- api-reference/series/series.cumsum.md | 11 +- api-reference/series/series.describe.md | 8 +- api-reference/series/series.div.md | 17 +- .../series/series.drop_duplicates.md | 26 +- api-reference/series/series.dropna.md | 17 +- api-reference/series/series.dt.day.md | 52 +- api-reference/series/series.dt.hour.md | 28 +- api-reference/series/series.dt.minute.md | 8 +- api-reference/series/series.dt.month.md | 36 +- api-reference/series/series.dt.month_name.md | 29 +- api-reference/series/series.dt.monthday.md | 29 +- api-reference/series/series.dt.second.md | 29 +- api-reference/series/series.dt.weekdays.md | 93 ++- api-reference/series/series.dt.year.md | 26 +- api-reference/series/series.dtype.md | 7 +- api-reference/series/series.eq.md | 15 +- api-reference/series/series.fillna.md | 20 +- api-reference/series/series.ge.md | 15 +- api-reference/series/series.gt.md | 15 +- api-reference/series/series.iloc.md | 48 +- api-reference/series/series.le.md | 16 +- api-reference/series/series.lt.md | 15 +- api-reference/series/series.map.md | 22 +- api-reference/series/series.max.md | 7 +- api-reference/series/series.mean.md | 7 +- api-reference/series/series.median.md | 7 +- api-reference/series/series.min.md | 7 +- api-reference/series/series.mod.md | 16 +- api-reference/series/series.mode.md | 7 +- api-reference/series/series.mul.md | 17 +- api-reference/series/series.ndim.md | 9 +- api-reference/series/series.ne.md | 15 +- api-reference/series/series.nunique.md | 9 +- api-reference/series/series.pow.md | 14 +- api-reference/series/series.replace.md | 87 ++- api-reference/series/series.reset_index.md | 152 ++-- api-reference/series/series.round.md | 15 +- api-reference/series/series.sample.md | 51 +- api-reference/series/series.set_index.md | 86 +-- api-reference/series/series.sort_values.md | 151 ++-- api-reference/series/series.str.capitalize.md | 12 +- api-reference/series/series.str.charat.md | 15 +- api-reference/series/series.str.concat.md | 26 +- api-reference/series/series.str.endswith.md | 15 +- api-reference/series/series.str.includes.md | 15 +- api-reference/series/series.str.indexof.md | 15 +- api-reference/series/series.str.join.md | 37 +- .../series/series.str.lastindexof.md | 14 +- api-reference/series/series.str.len.md | 44 +- api-reference/series/series.str.repeat.md | 15 +- api-reference/series/series.str.replace.md | 17 +- api-reference/series/series.str.search.md | 18 +- api-reference/series/series.str.slice.md | 17 +- api-reference/series/series.str.split.md | 16 +- api-reference/series/series.str.startswith.md | 15 +- api-reference/series/series.str.substr.md | 16 +- api-reference/series/series.str.substring.md | 17 +- .../series/series.str.tolowercase.md | 12 +- .../series/series.str.touppercase.md | 12 +- api-reference/series/series.str.trim.md | 12 +- api-reference/series/series.sub.md | 17 +- api-reference/series/series.sum.md | 7 +- api-reference/series/series.value_counts.md | 11 +- ...-driven-applications-with-danfo.js-book.md | 6 +- contributing-guide.md | 61 +- ...iction-using-danfo.js-and-tensorflow.js.md | 77 +- examples/using-danfojs-in-react.md | 3 +- getting-started.md | 666 ++++++++++-------- release-notes.md | 60 +- 139 files changed, 2173 insertions(+), 2853 deletions(-) delete mode 100644 api-reference/dataframe/dataframe.nunique.md delete mode 100644 api-reference/dataframe/dataframe.size.md diff --git a/README.md b/README.md index 92e7da5..0c09b3c 100644 --- a/README.md +++ b/README.md @@ -7,52 +7,62 @@ description: >- # Danfo.js Documentation -D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js.** +D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js. ** ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org/), and supports tensors out of the box. This means you can [convert danfo data structure](api-reference/dataframe/) to Tensors. -* Easy handling of missing ****data \(represented as `NaN`\) in floating point as well as non-floating point data +* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Easy handling of missing** **data (represented as `NaN`) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations -* Powerful, flexible [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data -* Make it easy to convert Arrays, JSONs, List or Objects, Tensors and differently-indexed data structures into DataFrame objects +* Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data +* Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) \(CSV and delimited\) and JSON data format. -* Powerful, flexible and intutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MESZnq3_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) (CSV and delimited), Excel, and JSON data format. +* Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MESZnq3\_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to danfo? Check out the getting started guides. They contain an introduction to _danfo's_ main concepts and links to additional contents. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's _main concepts and links to additional content. -{% page-ref page="getting-started.md" %} +{% content-ref url="getting-started.md" %} +[getting-started.md](getting-started.md) +{% endcontent-ref %} ## **API Reference** The reference guide contains a detailed description of the **danfo** API. The reference describes how each function works and which parameters can be used. -{% page-ref page="api-reference/" %} +{% content-ref url="api-reference/" %} +[api-reference](api-reference/) +{% endcontent-ref %} ## User Guides/Tutorials -{% page-ref page="examples/" %} +{% content-ref url="examples/" %} +[examples](examples/) +{% endcontent-ref %} ## Building Data Driven Applications with Danfo.js - Book -{% page-ref page="building-data-driven-applications-with-danfo.js-book.md" %} +{% content-ref url="building-data-driven-applications-with-danfo.js-book.md" %} +[building-data-driven-applications-with-danfo.js-book.md](building-data-driven-applications-with-danfo.js-book.md) +{% endcontent-ref %} ## Contributing Guide Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. -{% page-ref page="contributing-guide.md" %} +{% content-ref url="contributing-guide.md" %} +[contributing-guide.md](contributing-guide.md) +{% endcontent-ref %} ## Release Notes -{% page-ref page="release-notes.md" %} - - +{% content-ref url="release-notes.md" %} +[release-notes.md](release-notes.md) +{% endcontent-ref %} diff --git a/SUMMARY.md b/SUMMARY.md index 268ee82..fd962ba 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -127,11 +127,9 @@ * [DataFrame.reset_index](api-reference/dataframe/dataframe.reset_index.md) * [DataFrame.rename](api-reference/dataframe/dataframe.rename.md) * [DataFrame.drop](api-reference/dataframe/dataframe.drop.md) - * [DataFrame.unique](api-reference/dataframe/dataframe.nunique.md) * [DataFrame.astype](api-reference/dataframe/dataframe.astype.md) * [DataFrame.shape](api-reference/dataframe/dataframe.shape.md) - * [DataFrame.size](api-reference/dataframe/dataframe.size.md) - * [DataFrame.axes](api-reference/dataframe/dataframe.axes.md) + * [DataFrame.axis](api-reference/dataframe/dataframe.axes.md) * [DataFrame.ndim](api-reference/dataframe/dataframe.ndim.md) * [DataFrame.values](api-reference/dataframe/dataframe.values.md) * [DataFrame.select_dtypes](api-reference/dataframe/dataframe.select_dtypes.md) diff --git a/api-reference/README.md b/api-reference/README.md index 70dff34..b5d5d28 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -9,7 +9,7 @@ description: >- * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetimelike](general-functions/#top-level-dealing-with-datetime) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) * [Input/output](input-output/) * [CSV](input-output/#csv) * [JSON](input-output/#json) @@ -52,5 +52,3 @@ description: >- * [Function application](groupby/#function-application) * [Computations / descriptive stats](groupby/#computations-descriptive-stats) - - diff --git a/api-reference/configuration-options.md b/api-reference/configuration-options.md index d1ea96b..f4c2136 100644 --- a/api-reference/configuration-options.md +++ b/api-reference/configuration-options.md @@ -8,12 +8,12 @@ description: >- On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. -| Parameter | Description | -| :--- | :--- | +| Parameter | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | -| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | -| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | -| lowMemoryMode | **Boolean**, whether to use minimal memory or not. Defaults to false. **Note:** There's a slight decrease in speed when low memory mode is set to true. | +| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | +| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | +| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| > See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) @@ -119,11 +119,10 @@ const df = new DataFrame(data, { df.print() ``` -```text +``` ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 0 │ Apples │ 21 │ 200 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` - diff --git a/api-reference/dataframe/README.md b/api-reference/dataframe/README.md index 4b14800..a45aabd 100644 --- a/api-reference/dataframe/README.md +++ b/api-reference/dataframe/README.md @@ -1,142 +1,145 @@ --- -description: 'Two-dimensional, size-mutable, potentially heterogeneous tabular data.' +description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. --- # Dataframe -> [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame)\(data, {**columns:** \[ Array \], **dtypes:** \[ Array \], **index:** \[Array\]}\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L20)\] +> `DataFrame`(data, {\ +> **columns:** \[ Array ],\ +> **dtypes:** \[ Array ],** **\ +> ** index: **\[Array], \ +> **options**: Object}) ### Attributes -| [`DataFrame.index`](dataframe.index.md) | The index \(row labels\) of the DataFrame. | -| :--- | :--- | -| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | +| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | +| ------------------------------------------------ | ---------------------------------------- | +| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| :--- | :--- | +| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | +| ------------------------------------------------------- | ---------------------------------------------------------------------- | | [`DataFrame.select_dtypes`](dataframe.select_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](dataframe.size.md) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | +| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | +| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | +| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | +| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | +| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | ### Conversion -| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | -| :--- | :--- | -| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | +| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | +| ------------------------------------------- | -------------------------------------------------- | +| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | ### Indexing, iteration -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | -| :--- | :--- | -| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label\(s\) or a boolean array. | -| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | -| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | +| --------------------------------------------- | ------------------------------------------------------------------ | +| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | +| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | ### Binary operator functions -| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise \(binary operator add\). | -| :--- | :--- | -| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise \(binary operator sub\). | -| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise \(binary operator mul\). | -| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise \(binary operator truediv\). | -| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise \(binary operator mod\). | -| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise \(binary operator pow\). | -| [`DataFrame.lt`]() | Get Less than of dataframe and other, element-wise \(binary operator lt\). | -| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise \(binary operator gt\). | -| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise \(binary operator le\). | -| [`DataFrame.ge`]() | Get Greater than or equal to of dataframe and other, element-wise \(binary operator ge\). | -| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise \(binary operator ne\). | -| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise \(binary operator eq\). | +| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | +| ----------------------------------------- | --------------------------------------------------------------------------------------- | +| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | +| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | +| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | +| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | +| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | +| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | +| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | +| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | +| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | +| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | +| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | ### Function application & GroupBy -| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | -| :--- | :--- | -| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | -| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | +| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | +| --------------------------------------------- | --------------------------------------------------------- | +| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | +| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | ### Computations / descriptive stats -| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | -| :--- | :--- | -| [`DataFrame.corr`]() | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | -| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | -| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | -| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | -| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | -| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | -| [`DataFrame.mode`](../series/series.mode.md) | Get the mode\(s\) of each element along the selected axis. | -| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | -| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | -| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | -| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | -| [`DataFrame.nunique`](dataframe.nunique.md) | Count distinct observations over requested axis. | +| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | +| --------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | +| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | +| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | +| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | +| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | +| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | +| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | +| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | +| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | +| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | +| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | +| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | ### Reindexing / selection / label manipulation -| | | -| :--- | :--- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| | | +| --------------------------------------------------- | ------------------------------------------------------- | +| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | +| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | +| [`DataFrame.reset_index`](dataframe.reset_index.md) | Reset the index of a DataFrame | +| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | +| [`DataFrame.set_index`](dataframe.set_index.md) | Set the DataFrame index using existing columns. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | ### Missing data handling -| | | -| :--- | :--- | -| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | -| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | -| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | +| | | +| ------------------------------------------------- | ------------------------------------------- | +| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | +| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | +| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | | [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | ### Sorting & transposing -| | | -| :--- | :--- | -| [`DataFrame.sort_values`](dataframe.sort_values.md) | Sort by the values along either axis. | -| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | +| | | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| [`DataFrame.sort_values`](dataframe.sort_values.md) | Sort by the values along either axis. | +| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | ### Combining / comparing / joining / merging -| | | -| :--- | :--- | -| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | -| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | -| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | +| | | +| ---------------------------------------------------------- | ------------------------------------------------------------------- | +| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | +| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | +| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | ### Plotting `Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. -| | | -| :--- | :--- | -| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | -| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| | | +| -------------------------------------------------------- | ------------------------------------------------------------- | +| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | +| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | | [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | +| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | ### Serialization / IO / conversion -| | | -| :--- | :--- | -| [`DataFrame.to_csv`](dataframe.to_csv.md) | Write object to a comma-separated values \(csv\) file. | -| [`DataFrame.to_json`](dataframe.to_json.md) | Convert the object to a JSON string. | - +| | | +| ------------------------------------------- | ---------------------------------------------------- | +| [`DataFrame.to_csv`](dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | +| [`DataFrame.to_json`](dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference/dataframe/danfo.dataframe.abs.md b/api-reference/dataframe/danfo.dataframe.abs.md index 291487e..303a649 100644 --- a/api-reference/dataframe/danfo.dataframe.abs.md +++ b/api-reference/dataframe/danfo.dataframe.abs.md @@ -4,11 +4,11 @@ description: Return a DataFrame with the absolute numeric value of each element. # DataFrame.abs -danfo.DataFrame.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L973)\] +danfo.DataFrame.**abs**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L973)] **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -33,14 +33,13 @@ df_abs.abs().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -69,4 +68,3 @@ df_abs.abs().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 3e20f6a..2ba2b93 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -4,39 +4,19 @@ description: Add new column to a DataFrame # DataFrame.addColumn -danfo.DataFrame.**addColumn**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{column : str, name of the column to add

-

value: Series, Array. New values to add }

-
+danfo.DataFrame.**addColumn**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] -**Returns:** +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| kwargs | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | - ****return **Null** +**Returns:** ## **Examples** ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame, and this happens so returns nothing, {% tabs %} {% tab title="Node" %} @@ -53,20 +33,18 @@ let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -112,21 +90,18 @@ let s = new dfd.Series([1, 2, 3, 4]) df.addColumn({ "column": "D", "values": s, inplace: true }); df.print() - ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text - +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -141,4 +116,3 @@ df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.apply.md b/api-reference/dataframe/danfo.dataframe.apply.md index 2812b5c..1d664dd 100644 --- a/api-reference/dataframe/danfo.dataframe.apply.md +++ b/api-reference/dataframe/danfo.dataframe.apply.md @@ -7,37 +7,15 @@ description: >- # DataFrame.apply -danfo.DataFrame.**apply**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{callable: Function to call on each element,

-

axis: undefined: if undefined, then any JavaScript function

-

is accepted and will be applied element-wise.

-

0: Apply along row/index axis

-

1: Apply across columns axis

-

}

-
undefined
+danfo.DataFrame.**apply**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | +| kwargs | Object |

{callable: Function to call on each element,

axis: undefined: if undefined, then any JavaScript function

is accepted and will be applied element-wise.

0: Apply along row/index axis

1: Apply across columns axis

}

| undefined | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -65,14 +43,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -110,14 +87,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ short_name │ long_name ║ ╟───┼───────────────────┼───────────────────╢ @@ -158,14 +134,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -203,14 +178,13 @@ df_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -223,4 +197,3 @@ df_new.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.column.md b/api-reference/dataframe/danfo.dataframe.column.md index a937fc6..eabb06d 100644 --- a/api-reference/dataframe/danfo.dataframe.column.md +++ b/api-reference/dataframe/danfo.dataframe.column.md @@ -4,15 +4,15 @@ description: Return the elements of the specified column in the DataFrame # DataFrame.column -danfo.DataFrame.**column**\(col\_name\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)\] +danfo.DataFrame.**column**(col_name) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| col\_name | Str | The name of a column in the DataFrame | | +| Parameters | Type | Description | Default | +| ---------- | ---- | ------------------------------------- | ------- | +| col_name | Str | The name of a column in the DataFrame | | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** @@ -38,14 +38,13 @@ df['Name'].print() //produces the same result as above {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ Name ║ ╟───┼──────────────────────╢ @@ -74,4 +73,3 @@ df['Name'].print() //produces the same result as above {% endtabs %} To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) - diff --git a/api-reference/dataframe/danfo.dataframe.copy.md b/api-reference/dataframe/danfo.dataframe.copy.md index d149d12..ef705ed 100644 --- a/api-reference/dataframe/danfo.dataframe.copy.md +++ b/api-reference/dataframe/danfo.dataframe.copy.md @@ -4,11 +4,11 @@ description: Makes a new copy of the DataFrame # DataFrame.copy -danfo.DataFrame.**copy**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)\] +danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] **Returns:** - ****return **new DataFrame** +** **return** new DataFrame** ## **Examples** @@ -27,14 +27,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -52,5 +51,3 @@ new_df.print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/dataframe/danfo.dataframe.cumprod.md b/api-reference/dataframe/danfo.dataframe.cumprod.md index 60fab0d..b780cd2 100644 --- a/api-reference/dataframe/danfo.dataframe.cumprod.md +++ b/api-reference/dataframe/danfo.dataframe.cumprod.md @@ -4,19 +4,19 @@ description: Return cumulative product over a DataFrame or Series axis. # DataFrame.cumprod -danfo.DataFrame.**cumprod**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L739)\] +danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -## Cumulative product of elements along default axis \(row\) +## Cumulative product of elements along default axis (row) {% tabs %} {% tab title="Node" %} @@ -35,14 +35,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -58,7 +57,7 @@ new_df.print() {% endtab %} {% endtabs %} -## Cumulative product of elements along column axis \(1\) +## Cumulative product of elements along column axis (1) {% tabs %} {% tab title="Node" %} @@ -77,14 +76,13 @@ new_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -99,4 +97,3 @@ new_df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.describe.md b/api-reference/dataframe/danfo.dataframe.describe.md index 7c5b2c1..525c51f 100644 --- a/api-reference/dataframe/danfo.dataframe.describe.md +++ b/api-reference/dataframe/danfo.dataframe.describe.md @@ -6,11 +6,11 @@ description: >- # DataFrame.describe -danfo.DataFrame.**describe**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)\] +danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -30,14 +30,13 @@ df.describe().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔══════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ col1 │ col2 │ col3 ║ ╟──────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -59,5 +58,4 @@ df.describe().print() {% endtab %} {% endtabs %} -## - +## diff --git a/api-reference/dataframe/danfo.dataframe.dropna.md b/api-reference/dataframe/danfo.dataframe.dropna.md index 08bc41e..cb0d5a4 100644 --- a/api-reference/dataframe/danfo.dataframe.dropna.md +++ b/api-reference/dataframe/danfo.dataframe.dropna.md @@ -1,46 +1,22 @@ --- -description: 'Remove missing values (NaNs, undefined) for DataFrame' +description: Remove missing values (NaNs, undefined) for DataFrame --- # DataFrame.dropna -danfo.DataFrame.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{axis: 0: Apply along row/index axis

-

1: Apply across columns axis

-

inplace:If true, perform operation inplace

-

and return None.

-

}

-
-

{axis: 0,

-

inplace: false}

-
+danfo.DataFrame.**dropna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| kwargs | Object |

{axis: 0: Apply along row/index axis

1: Apply across columns axis

inplace:If true, perform operation inplace

and return None.

}

|

{axis: 0,

inplace: false}

| **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Drop rows \(axis=0\) with missing values +### Drop rows (axis=0) with missing values {% tabs %} {% tab title="Node" %} @@ -60,14 +36,13 @@ df_drop.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -77,7 +52,7 @@ df_drop.print() {% endtab %} {% endtabs %} -### Drop columns \(axis=1\) with missing values +### Drop columns (axis=1) with missing values {% tabs %} {% tab title="Node" %} @@ -97,14 +72,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╗ ║ │ C ║ ╟───┼───────────────────╢ @@ -119,4 +93,3 @@ df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.eq.md b/api-reference/dataframe/danfo.dataframe.eq.md index 957c7a5..be1f7ff 100644 --- a/api-reference/dataframe/danfo.dataframe.eq.md +++ b/api-reference/dataframe/danfo.dataframe.eq.md @@ -1,23 +1,23 @@ --- -description: 'Get Equal to of DataFrame and other, element-wise (binary operator eq).' +description: Get Equal to of DataFrame and other, element-wise (binary operator eq). --- # DataFrame.eq -danfo.DataFrame.**eq**\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] +danfo.DataFrame.**eq**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -59,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -81,7 +80,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -104,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -127,7 +125,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -150,7 +147,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -170,7 +167,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -192,4 +188,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.fillna.md b/api-reference/dataframe/danfo.dataframe.fillna.md index f019e6e..ac7cc79 100644 --- a/api-reference/dataframe/danfo.dataframe.fillna.md +++ b/api-reference/dataframe/danfo.dataframe.fillna.md @@ -6,37 +6,15 @@ description: >- # DataFrame.fillna -danfo.DataFrame.**fillna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{columns:Array of column name(s) to fill. If undefined fill all - columns

-

values: Array | Scalar of value(s) to fill with.

-

inplace: boolean. true | false. Whether to perform operation to - the original Object or create a new one.

-

}

-
+danfo.DataFrame.**fillna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | +| kwargs | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

values: Array | Scalar of value(s) to fill with.

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -62,14 +40,13 @@ df_filled.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //Before filling ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -122,14 +99,13 @@ df_filled.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -171,14 +147,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -194,4 +169,3 @@ df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.ge.md b/api-reference/dataframe/danfo.dataframe.ge.md index bc1efbc..ab0ea5c 100644 --- a/api-reference/dataframe/danfo.dataframe.ge.md +++ b/api-reference/dataframe/danfo.dataframe.ge.md @@ -6,20 +6,20 @@ description: >- # DataFrame.ge -danfo.DataFrame.**ge**\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1616)\] +danfo.DataFrame.**ge**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1616)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -39,14 +39,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -62,7 +61,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -85,7 +84,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -108,7 +106,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -132,7 +130,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -155,7 +152,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -175,7 +172,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -197,4 +193,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.groupby.md b/api-reference/dataframe/danfo.dataframe.groupby.md index 5f187bd..0b9dad9 100644 --- a/api-reference/dataframe/danfo.dataframe.groupby.md +++ b/api-reference/dataframe/danfo.dataframe.groupby.md @@ -4,15 +4,15 @@ description: Group DataFrame using a mapper or by a Series of columns. # DataFrame.groupby -danfo.DataFrame.**groupby**\(columns\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)\] +danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| columns | Array | The names of a column\(s\) in the DataFrame to group by | | +| Parameters | Type | Description | Default | +| ---------- | ----- | ----------------------------------------------------- | ------- | +| columns | Array | The names of a column(s) in the DataFrame to group by | | **Returns:** - ****return **DataFrame.groups** +** **return** DataFrame.groups** ## **Examples** @@ -33,14 +33,13 @@ group_df.col_dict {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ Name ║ ╟───┼──────────────────────╢ @@ -69,4 +68,3 @@ group_df.col_dict {% endtabs %} To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) - diff --git a/api-reference/dataframe/danfo.dataframe.gt.md b/api-reference/dataframe/danfo.dataframe.gt.md index 7243088..0d6cb3c 100644 --- a/api-reference/dataframe/danfo.dataframe.gt.md +++ b/api-reference/dataframe/danfo.dataframe.gt.md @@ -1,23 +1,23 @@ --- -description: 'Get Greater than of DataFrame and other, element-wise (binary operator eq).' +description: Get Greater than of DataFrame and other, element-wise (binary operator eq). --- # DataFrame.gt -danfo.DataFrame.**gt**\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1583)\] +danfo.DataFrame.**gt**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1583)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -59,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -81,14 +80,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -104,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -128,14 +126,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -151,7 +148,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -171,14 +168,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -193,4 +189,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.head.md b/api-reference/dataframe/danfo.dataframe.head.md index 3fec50c..10ae0f2 100644 --- a/api-reference/dataframe/danfo.dataframe.head.md +++ b/api-reference/dataframe/danfo.dataframe.head.md @@ -4,15 +4,15 @@ description: Returns the first n rows of the DataFrame based on position. # DataFrame.head -danfo.DataFrame.**head**\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)\] +danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | The number of rows to return | 5 | +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -34,14 +34,13 @@ s_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -52,4 +51,3 @@ s_df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.isna.md b/api-reference/dataframe/danfo.dataframe.isna.md index 5e8e811..b919db5 100644 --- a/api-reference/dataframe/danfo.dataframe.isna.md +++ b/api-reference/dataframe/danfo.dataframe.isna.md @@ -7,11 +7,11 @@ description: >- # DataFrame.isna -danfo.DataFrame.**isna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)\] +danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -31,14 +31,13 @@ df.isna().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -53,4 +52,3 @@ df.isna().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.it.md b/api-reference/dataframe/danfo.dataframe.it.md index 7dbc6eb..5d5d67b 100644 --- a/api-reference/dataframe/danfo.dataframe.it.md +++ b/api-reference/dataframe/danfo.dataframe.it.md @@ -1,23 +1,23 @@ --- -description: 'Get Less than of DataFrame and other, element-wise (binary operator eq).' +description: Get Less than of DataFrame and other, element-wise (binary operator eq). --- # DataFrame.It -danfo.DataFrame.l**t**\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)\] +danfo.DataFrame.l**t**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -59,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -81,14 +80,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -104,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -128,14 +126,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -151,7 +148,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -172,14 +169,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -194,4 +190,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.le.md b/api-reference/dataframe/danfo.dataframe.le.md index b6e33b9..9b86440 100644 --- a/api-reference/dataframe/danfo.dataframe.le.md +++ b/api-reference/dataframe/danfo.dataframe.le.md @@ -6,20 +6,20 @@ description: >- # DataFrame.le -danfo.DataFrame.le\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] +danfo.DataFrame.le(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -39,14 +39,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -62,7 +61,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -85,14 +84,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -108,7 +106,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -131,7 +129,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -154,7 +151,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -174,7 +171,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -196,4 +192,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.ne.md b/api-reference/dataframe/danfo.dataframe.ne.md index 4a807f7..8dfddc9 100644 --- a/api-reference/dataframe/danfo.dataframe.ne.md +++ b/api-reference/dataframe/danfo.dataframe.ne.md @@ -1,23 +1,23 @@ --- -description: 'Get Not Equal to of DataFrame and other, element-wise (binary operator eq).' +description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). --- # DataFrame.ne -danfo.DataFrame.ne\(other, axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1633)\] +danfo.DataFrame.ne(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1633)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index \(0\) or columns \(1\). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### Comparing ****DataFrame with a scalar value: +### Comparing** **DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -59,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a Series along the column axis: +### Comparing** **DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -81,14 +80,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -104,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a DataFrame +### Comparing** **DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -128,14 +126,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -151,7 +148,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing ****DataFrame with a JavaScript Array +### Comparing** **DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} @@ -171,14 +168,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -189,4 +185,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.query.md b/api-reference/dataframe/danfo.dataframe.query.md index 902230c..141b642 100644 --- a/api-reference/dataframe/danfo.dataframe.query.md +++ b/api-reference/dataframe/danfo.dataframe.query.md @@ -6,44 +6,21 @@ description: >- # DataFrame.query -danfo.DataFrame.**query**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{column : str, name of the column

-

is: Logical operator, one of ">", "<", - ">=", "<=", and. "=="

-

to: Int, Float, Str. Value to compare against,

-

inplace: boolean. true | false. Whether to perform operation to - the original Object or create a new one.

-

}

-
{inplace: false}
+danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| kwargs | Object |

{column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | **Returns:** - ****return **new DataFrame** +** **return** new DataFrame** ## **Examples** ## **Query a DataFrame using logical operators** -To query a DataFrame, you can specify the column to use, the logical operator \(">", "<", ">=", "<=", and. "=="\), and the value to compare against. +To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. {% tabs %} {% tab title="Node" %} @@ -65,14 +42,13 @@ query_df.print() //after query {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //before query ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -118,14 +94,13 @@ query_df.print() //after query {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -173,14 +148,13 @@ query_df.print() //after query {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -234,14 +208,13 @@ df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -252,4 +225,3 @@ df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.replace.md b/api-reference/dataframe/danfo.dataframe.replace.md index 91e21f1..e4dae64 100644 --- a/api-reference/dataframe/danfo.dataframe.replace.md +++ b/api-reference/dataframe/danfo.dataframe.replace.md @@ -4,38 +4,17 @@ description: Replaces values in a DataFrame with specified values # DataFrame.replace -> danfo.DataFrame.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargsObject -

{replace: int, float, str. The value to replace.

-

with: Int, float, str. The new value to replace with.

-

in: Array. An array of column names to replace, If not specified, - replace all columns.

-

}

-
+> danfo.DataFrame.**replace**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | +| kwargs | Object |

{replace: int, float, str. The value to replace.

with: Int, float, str. The new value to replace with.

in: Array. An array of column names to replace, If not specified, replace all columns.

}

| | **Returns:** - ****return **DataFrame** +** **return** DataFrame** -\*\*\*\* +**** ## **Examples** @@ -58,14 +37,13 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -81,7 +59,7 @@ df_rep.print() {% endtab %} {% endtabs %} -By not specifying a ****column**,** the ****replace works on all columns **** +By not specifying a** **column**, **the** **replace works on all columns ** ** {% tabs %} {% tab title="Node" %} @@ -101,7 +79,6 @@ df_rep.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} @@ -120,4 +97,3 @@ df_rep.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.sum.md b/api-reference/dataframe/danfo.dataframe.sum.md index d8d1e96..6a8125c 100644 --- a/api-reference/dataframe/danfo.dataframe.sum.md +++ b/api-reference/dataframe/danfo.dataframe.sum.md @@ -4,19 +4,19 @@ description: Return the sum of the values for the requested axis. # DataFrame.sum -danfo.DataFrame.**sum**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)\] +danfo.DataFrame.**sum**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------- | --------- | +| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -## Sum elements along default axis \(column\) +## Sum elements along default axis (column) {% tabs %} {% tab title="Node" %} @@ -36,14 +36,13 @@ df_sum.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -69,7 +68,7 @@ df_sum.print() {% endtab %} {% endtabs %} -## Sum elements along row axis \(0\) +## Sum elements along row axis (0) {% tabs %} {% tab title="Node" %} @@ -89,14 +88,13 @@ df_sum.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -123,4 +121,3 @@ df_sum.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.tail.md b/api-reference/dataframe/danfo.dataframe.tail.md index a69fa3e..f317ba2 100644 --- a/api-reference/dataframe/danfo.dataframe.tail.md +++ b/api-reference/dataframe/danfo.dataframe.tail.md @@ -4,15 +4,15 @@ description: Returns the last n rows from the DataFrame based on position. # DataFrame.tail -danfo.DataFrame.**tail**\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)\] +danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | The number of rows to return | 5 | +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -34,14 +34,13 @@ s_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -52,4 +51,3 @@ s_df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/dataframe.dtypes.md b/api-reference/dataframe/dataframe.dtypes.md index b59af75..6e856d5 100644 --- a/api-reference/dataframe/dataframe.dtypes.md +++ b/api-reference/dataframe/dataframe.dtypes.md @@ -7,15 +7,15 @@ description: >- # DataFrame.ctypes -danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)\] +danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -Returns auto-generated ****index of a ****DataFrame +Returns auto-generated** **index of a** **DataFrame {% tabs %} {% tab title="Node" %} @@ -34,14 +34,13 @@ df.ctypes.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -76,14 +75,13 @@ df.ctypes.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -100,4 +98,3 @@ df.ctypes.print() {% endtabs %} **Note**: To cast a type, use the [astype](dataframe.astype.md) method. - diff --git a/api-reference/dataframe/dataframe.ndim.md b/api-reference/dataframe/dataframe.ndim.md index a163ac4..002da15 100644 --- a/api-reference/dataframe/dataframe.ndim.md +++ b/api-reference/dataframe/dataframe.ndim.md @@ -6,13 +6,13 @@ description: >- # DataFrame.ndim -danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] +danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** - ****return **Int** +** **return** Int** -**Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. +**Note:** To get the **shape **of the DataFrame use the .[shape](dataframe.shape.md) property. ## **Examples** @@ -33,16 +33,14 @@ console.log(df.ndim) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` 2 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/dataframe.nunique.md b/api-reference/dataframe/dataframe.nunique.md deleted file mode 100644 index 53b88fd..0000000 --- a/api-reference/dataframe/dataframe.nunique.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: >- - Return unique values of DataFrame along an axis. Uniques are returned in order - of appearance. Set-based unique, therefore does NOT sort. ---- - -# DataFrame.unique - -danfo.DataFrame.**unique**\(axis\) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1945)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | - -**Returns:** - - ****return **Object** - -## **Examples** - -### Return unique values along column axis \(axis=1\) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -console.log(df.unique()) //defaults to axis 1 -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -{ - A: [ -20, 30, 47.3 ], - B: [ 34, -4, 5, 6 ], - C: [ 20, 30 ], - D: [ 'a', 'b', 'c' ] -} -``` -{% endtab %} -{% endtabs %} - -### Return unique values in row axis \(axis=0\) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -console.log(df.unique(axis=0)); -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -{ - '0': [ -20, 34, 20, 'a' ], - '1': [ 30, -4, 20, 'b' ], - '2': [ 47.3, 5, 30, 'c' ], - '3': [ -20, 6, 30, 'c' ] -} -``` -{% endtab %} -{% endtabs %} - -**Note:** To get the number of unique elements along an axis, use ****[DataFrame.nunique.](dataframe.nunique-1.md) - diff --git a/api-reference/dataframe/dataframe.select_dtypes.md b/api-reference/dataframe/dataframe.select_dtypes.md index f145e92..127b433 100644 --- a/api-reference/dataframe/dataframe.select_dtypes.md +++ b/api-reference/dataframe/dataframe.select_dtypes.md @@ -2,17 +2,17 @@ description: Return a subset of the DataFrame’s columns based on the column dtypes. --- -# DataFrame.select\_dtypes +# DataFrame.select_dtypes -danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)\] +danfo.DataFrame.**select_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| include | Array | List of column dtypes to return | | +| Parameters | Type | Description | Default | +| ---------- | ----- | -------------------------------- | ------- | +| include | Array | List of column dtypes to return | | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -42,14 +42,13 @@ str_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //select float column(s) ╔═══╤══════════════════════╗ ║ │ A ║ @@ -93,4 +92,3 @@ str_df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/dataframe.shape.md b/api-reference/dataframe/dataframe.shape.md index ef0b4ca..3e8486f 100644 --- a/api-reference/dataframe/dataframe.shape.md +++ b/api-reference/dataframe/dataframe.shape.md @@ -4,11 +4,11 @@ description: Returns an Array representing the dimensionality of the DataFrame. # DataFrame.shape -danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] +danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** - ****return **Int** +** **return** Int** ## **Examples** @@ -30,16 +30,14 @@ console.log(df.shape) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` [4,3] ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/dataframe.size.md b/api-reference/dataframe/dataframe.size.md deleted file mode 100644 index a1cece6..0000000 --- a/api-reference/dataframe/dataframe.size.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: >- - Return an int representing the number of elements in this object. Return the - number of rows if Series. Otherwise return the number of rows times number of - columns if DataFrame. ---- - -# DataFrame.size - -danfo.DataFrame.**size** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] - -**Returns:** - - ****return **Int** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.size) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -12 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference/dataframe/dataframe.values.md b/api-reference/dataframe/dataframe.values.md index 0f87f7f..6b7ea1d 100644 --- a/api-reference/dataframe/dataframe.values.md +++ b/api-reference/dataframe/dataframe.values.md @@ -4,13 +4,13 @@ description: Return a the JavaScript array representation of the DataFrame. # DataFrame.values -danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)\] +danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** - ****return **Array** +** **return** Array** -**Note:** To get the [Tensorflow](https://js.tensorflow.org/) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. +**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. ## **Examples** @@ -32,14 +32,13 @@ console.log(df.values) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` [ [ -20.1, 34, 20 ], [ 30, -4, -20 ], @@ -49,4 +48,3 @@ console.log(df.values) ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index b74b5da..07815b0 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -6,23 +6,22 @@ description: Top level functions that can be called from the Danfo namespace ### Data manipulations -| | | -| :--- | :--- | -| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | -| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | -| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | +| | | +| ------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | +| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | +| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | ### Data Processing/Normalization -| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n\_classes-1. | -| :--- | :--- | -| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | +| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | +| ----------------------------------------- | ---------------------------------------------------------------------- | +| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | | [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | -| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | +| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | ### Top-level dealing with datetime -| [`to_datetime`](danfo.to_datetime.md) | Convert argument to datetime. | -| :--- | :--- | -| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | - +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| ------------------------------------ | --------------------------------------- | +| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.concat.md b/api-reference/general-functions/danfo.concat.md index 3422f83..19c3d8e 100644 --- a/api-reference/general-functions/danfo.concat.md +++ b/api-reference/general-functions/danfo.concat.md @@ -4,41 +4,19 @@ description: Concatenate DataFrames and Series along an axis # danfo.concat -danfo.**concat**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargs - Object -

{

-

df_list: List of DataFrames or Series to concatenate together.

-

axis: One of 0 or 1. The axis on which to perform concatenation. - Specified axis must align in both Objects

-

}

-
{axis: 1}
+danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | +| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### **Concatenate two DataFrames along column axis \(1\)** +### **Concatenate two DataFrames along column axis (1) ** {% tabs %} {% tab title="Node" %} @@ -66,14 +44,13 @@ com_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -89,7 +66,7 @@ com_df.print() {% endtab %} {% endtabs %} -### **Concatenate two DataFrames along row axis \(0\)** +### **Concatenate two DataFrames along row axis (0) ** {% tabs %} {% tab title="Node" %} @@ -117,14 +94,13 @@ com_df.print(10) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B │ D ║ @@ -149,7 +125,7 @@ com_df.print(10) {% endtab %} {% endtabs %} -### **Concatenate two Series along row axis \(0\)** +### **Concatenate two Series along row axis (0) ** {% tabs %} {% tab title="Node" %} @@ -177,14 +153,13 @@ com_df.print(10) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B │ D ║ @@ -210,4 +185,3 @@ com_df.print(10) {% endtabs %} See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. - diff --git a/api-reference/general-functions/danfo.date_range.md b/api-reference/general-functions/danfo.date_range.md index c172783..32d18b8 100644 --- a/api-reference/general-functions/danfo.date_range.md +++ b/api-reference/general-functions/danfo.date_range.md @@ -2,40 +2,17 @@ description: Return a fixed frequency Dates spread between start and end parameters. --- -# danfo.date\_range - -danfo.**date\_range**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargs - Object -

{

-

start: str or datetime-like. Left bound for generating dates.

-

end: str or datetime-like. Right bound for generating dates.

-

period : int. Number of periods to generate.

-

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

-

}

-
{freq: 'D'}
+# danfo.date_range + +danfo.**date_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -80,7 +57,7 @@ console.log(data); {% tabs %} {% tab title="Output" %} -```text +``` [ '1/1/2018, 12:00:00 AM', '2/1/2018, 12:00:00 AM', @@ -104,14 +81,13 @@ console.log(data); {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` [ '1/1/2018, 12:00:00 AM', '1/1/2019, 12:00:00 AM', @@ -131,6 +107,5 @@ console.log(data); {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} - diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 1cb3b8f..793aa58 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -2,40 +2,18 @@ description: Convert categorical variable into dummy/indicator variables. --- -# danfo.get\_dummies - -danfo.**get\_dummies**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargs - Object -

{

-

data: Array | Series | DataFrame

-

prefix_sep: String separator for created columns e.g "_",

-

prefix: String | Array of String, of column names

-

columns: [Array] columns to be encoded in DataFrame.

-

}

-
{prefix_sep: "_"}
+# danfo.get_dummies + +danfo.**get_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| data | Series or Dataframe | The data to dummify | | +| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -49,35 +27,34 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies({data: sf1, prefix:"fruit"}) +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) dum_df.print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -96,21 +73,20 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df }) +let dum_df = dfd.get_dummies(df) dum_df.print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ fruits │ Count │ Country ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,21 +135,20 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies({ data: df, columns: ['fruits']}) +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) dum_df.print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ fruits │ Count │ Country ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -211,4 +186,3 @@ dum_df.print() {% hint style="info" %} See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) {% endhint %} - diff --git a/api-reference/general-functions/danfo.labelencoder.md b/api-reference/general-functions/danfo.labelencoder.md index 1951475..12d57ee 100644 --- a/api-reference/general-functions/danfo.labelencoder.md +++ b/api-reference/general-functions/danfo.labelencoder.md @@ -4,9 +4,9 @@ description: Encode target labels with value between 0 and n_classes-1. # danfo.LabelEncoder -class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**LabelEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. +danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. @@ -35,14 +35,13 @@ new_sf.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` LabelEncoder { label: [ 'dog', 'cat', 'man' ] } ╔═══╤══════════════════════╗ ║ │ 0 ║ @@ -105,14 +104,13 @@ new_sf.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } ╔═══╤══════════════════════╗ ║ │ 0 ║ @@ -139,5 +137,4 @@ LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } {% endtab %} {% endtabs %} -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get_dummies.md) - +See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference/general-functions/danfo.merge.md b/api-reference/general-functions/danfo.merge.md index 54b3330..82a9a3d 100644 --- a/api-reference/general-functions/danfo.merge.md +++ b/api-reference/general-functions/danfo.merge.md @@ -6,40 +6,15 @@ description: >- # danfo.merge -danfo.**merge**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargs - Object -

{

-

left: A DataFrame or named Series object.

-

right: Another DataFrame or named Series object.

-

on: Column names to join on. Must be found in both the left and - right DataFrame and/or Series objects.

-

how: One of 'left','right','outer', 'inner'. - Defaults to 'inner'

-

}

-
{how: inner}
+danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** @@ -80,14 +55,13 @@ merge_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -169,14 +143,13 @@ merge_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -254,14 +227,13 @@ merge_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //First DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -339,14 +311,13 @@ merge_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -424,14 +395,13 @@ merge_df.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -481,4 +451,3 @@ merge_df.print() {% hint style="info" %} See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. {% endhint %} - diff --git a/api-reference/general-functions/danfo.minmaxscaler.md b/api-reference/general-functions/danfo.minmaxscaler.md index b0c4310..06add63 100644 --- a/api-reference/general-functions/danfo.minmaxscaler.md +++ b/api-reference/general-functions/danfo.minmaxscaler.md @@ -4,7 +4,7 @@ description: Transform features by scaling each feature to a range of max and mi # danfo.MinMaxScaler -class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**MinMaxScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. @@ -40,14 +40,13 @@ df_enc.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ @@ -100,14 +99,13 @@ df_enc.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` Shape: (3,1) @@ -125,4 +123,3 @@ df_enc.print() {% endtabs %} See also [MinMaxScaler](danfo.minmaxscaler.md) - diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 752a196..fdb8d4a 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**OneHotEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** @@ -40,14 +40,13 @@ new_sf.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ pear │ mango │ pawpaw │ bean ║ @@ -108,14 +107,13 @@ new_sf.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ pear │ mango │ pawpaw │ bean ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -147,5 +145,4 @@ new_sf.print() {% endtab %} {% endtabs %} -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get_dummies.md) - +See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 5e66567..298d86e 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -4,11 +4,11 @@ description: Standardize features by removing the mean and scaling to unit varia # danfo.StandardScaler -class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +class danfo.**StandScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] -danfo.js provides the StandardScaler class for standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: -> z = \(x - u\) / s +> z = (x - u) / s where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. @@ -37,14 +37,13 @@ sf_enc.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -97,14 +96,13 @@ df_enc.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -132,4 +130,3 @@ df_enc.print() {% endtabs %} See also [MinMaxScaler](danfo.minmaxscaler.md) - diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 2e7c0a3..6112004 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,51 +1,31 @@ --- -description: Convert Object to datetime format +description: Converts an array of Date time string to Date object. --- -# danfo.to\_datetime - -danfo.**to\_datetime**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
kwargs - Object -

{

-

data: Array | Series, the object to convert.

-

format: The strftime to parse time, eg "%Y-m-d%", "%m-d-Y%", - and "%m-d-Y H%M%S%"

-

}

-
+# danfo.to_datetime + +danfo.**to_datetime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | +| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | **Returns:** - ****return **DataFrame** +** **return** DataFrame** ## **Examples** -### **Convert Series to Dummy codes** +Converts a **Series** of Date strings to Date time and get time properties {% tabs %} {% tab title="Node" %} ```javascript let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) -let dt = dfd.to_datetime({data:sf}) +sf.print() + +let dt = dfd.toDateTime({data:sf}) dt.month().print() dt.month_name().print() @@ -57,93 +37,105 @@ dt.seconds().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + //Int representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╚═══╧══════════════════════╝ + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 //string representation for month -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╟───┼──────────────────────╢ -║ 3 │ Apr ║ -╟───┼──────────────────────╢ -║ 4 │ May ║ -╚═══╧══════════════════════╝ +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec //string representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Mon ║ -╟───┼──────────────────────╢ -║ 1 │ Thu ║ -╟───┼──────────────────────╢ -║ 2 │ Thu ║ -╟───┼──────────────────────╢ -║ 3 │ Sun ║ -╟───┼──────────────────────╢ -║ 4 │ Tue ║ -╚═══╧══════════════════════╝ - -//Int representation for day of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 2 ║ -╚═══╧══════════════════════╝ +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + //Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 0 ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} - diff --git a/api-reference/groupby/groupby.agg.md b/api-reference/groupby/groupby.agg.md index 45c844a..f9d6a5f 100644 --- a/api-reference/groupby/groupby.agg.md +++ b/api-reference/groupby/groupby.agg.md @@ -4,13 +4,13 @@ description: Obtain data aggregate per groups for each column # Groupby.agg -> danfo.Groupby.**agg**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)\] +> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | +| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | -**Return:** DataFrame +**Return: **DataFrame **Examples** @@ -38,7 +38,7 @@ grp.agg({"C":"mean","D":"sum"}).print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -74,7 +74,7 @@ grp.agg({"C":"mean","D":"sum"}).print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -91,4 +91,3 @@ grp.agg({"C":"mean","D":"sum"}).print() ║ 4 │ bar │ two │ 2 │ 6 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` - diff --git a/api-reference/groupby/groupby.count.md b/api-reference/groupby/groupby.count.md index 13a36d1..36733be 100644 --- a/api-reference/groupby/groupby.count.md +++ b/api-reference/groupby/groupby.count.md @@ -4,7 +4,7 @@ description: Count the occurrence of values in columns per groups # Groupby.count -> danfo.Groupby.count\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)\] +> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] **Parameters**: None @@ -37,7 +37,7 @@ grp.col(["C"]).count().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) @@ -74,7 +74,7 @@ grp.col(["C","D"]).count().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -111,7 +111,7 @@ grp.col(["C"]).count().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -153,7 +153,7 @@ grp.col(["C","D"]).count().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) @@ -172,5 +172,4 @@ grp.col(["C","D"]).count().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.cumsum.md b/api-reference/groupby/groupby.cumsum.md index e9ccab8..3b2b0e6 100644 --- a/api-reference/groupby/groupby.cumsum.md +++ b/api-reference/groupby/groupby.cumsum.md @@ -4,7 +4,7 @@ description: Obtain the cumulative sum per groups for each column # Groupby.cumsum -> danfo.Groupby.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)\] +> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] **Parameters**: None @@ -37,7 +37,7 @@ grp.col(["C"]).cumsum().tail().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,2) @@ -98,7 +98,7 @@ grp.col(["C","D"]).cumsum().tail().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) @@ -160,7 +160,7 @@ grp.col(["C"]).cumsum().tail().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -220,7 +220,7 @@ grp.col(["C","D"]).cumsum().tail().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) @@ -256,5 +256,4 @@ grp.col(["C","D"]).cumsum().tail().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.max.md b/api-reference/groupby/groupby.max.md index 1de767f..6bebae5 100644 --- a/api-reference/groupby/groupby.max.md +++ b/api-reference/groupby/groupby.max.md @@ -4,9 +4,9 @@ description: Obtain the maximum value of columns per groups # Groupby.max -> danfo.Groupby.max\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)\] +> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] -**Parameters:** None +**Parameters: **None **Returns**: DataFrame @@ -36,7 +36,7 @@ grp.col(["C"]).max().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) ╔═══╤═══════════════════╤═══════════════════╗ @@ -73,7 +73,7 @@ grp.col(["C","D"]).max().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -109,7 +109,7 @@ grp.col(["C"]).max().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -151,7 +151,7 @@ grp.col(["C","D"]).max().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -168,4 +168,3 @@ grp.col(["C","D"]).max().print() ║ 4 │ bar │ two │ 2 │ 6 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` - diff --git a/api-reference/groupby/groupby.mean.md b/api-reference/groupby/groupby.mean.md index bfb0ad0..add6958 100644 --- a/api-reference/groupby/groupby.mean.md +++ b/api-reference/groupby/groupby.mean.md @@ -4,7 +4,7 @@ description: Obtain the mean per groups for each column(s) # Groupby.mean -> danfo.Series.mean\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)\] +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] **Parameters**: None @@ -36,7 +36,7 @@ grp.col(["C"]).mean().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) @@ -74,7 +74,7 @@ grp.col(["C","D"]).mean().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -110,7 +110,7 @@ grp.col(["C"]).mean().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -152,7 +152,7 @@ grp.col(["C","D"]).mean().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -170,5 +170,4 @@ grp.col(["C","D"]).mean().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.min.md b/api-reference/groupby/groupby.min.md index 75e1b60..0151e64 100644 --- a/api-reference/groupby/groupby.min.md +++ b/api-reference/groupby/groupby.min.md @@ -4,7 +4,7 @@ description: Obtain the minimum value per groups for a coumn(s) # Groupby.min -> danfo.Groupby.min\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)\] +> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] **Parameters**: None @@ -36,7 +36,7 @@ grp.col(["C"]).min().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) ╔═══╤═══════════════════╤═══════════════════╗ @@ -72,7 +72,7 @@ grp.col(["C","D"]).min().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -108,7 +108,7 @@ grp.col(["C"]).min().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -150,7 +150,7 @@ grp.col(["C","D"]).min().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -168,5 +168,4 @@ grp.col(["C","D"]).min().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.std.md b/api-reference/groupby/groupby.std.md index 30b22f1..c792a8e 100644 --- a/api-reference/groupby/groupby.std.md +++ b/api-reference/groupby/groupby.std.md @@ -4,7 +4,7 @@ description: Obtain the standard deviation per groups for specified columns # Groupby.std -> danfo.Groupby.**std**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)\] +> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] **Parameters**: None @@ -37,7 +37,7 @@ grp.col(["C"]).std().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) @@ -74,7 +74,7 @@ grp.col(["C","D"]).std().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -111,7 +111,7 @@ grp.col(["C"]).std().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -153,7 +153,7 @@ grp.col(["C","D"]).std().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) @@ -172,5 +172,4 @@ grp.col(["C","D"]).std().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.sum.md b/api-reference/groupby/groupby.sum.md index 8e46a98..f6f2900 100644 --- a/api-reference/groupby/groupby.sum.md +++ b/api-reference/groupby/groupby.sum.md @@ -4,7 +4,7 @@ description: Obtain the sum per groups for columns # Groupby.sum -> danfo.Groupby.sum\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)\] +> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] **Parameters**: None @@ -36,7 +36,7 @@ grp.col(["C"]).sum().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) @@ -73,7 +73,7 @@ grp.col(["C","D"]).sum().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -109,7 +109,7 @@ grp.col(["C"]).sum().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -151,7 +151,7 @@ grp.col(["C","D"]).sum().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -169,5 +169,4 @@ grp.col(["C","D"]).sum().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/groupby/groupby.var.md b/api-reference/groupby/groupby.var.md index 20a3ca8..373109f 100644 --- a/api-reference/groupby/groupby.var.md +++ b/api-reference/groupby/groupby.var.md @@ -4,7 +4,7 @@ description: Obtain the variance per groups for a specified column # Groupby.var -> danfo.Groupby.**var**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)\] +> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] **Parameters**: None @@ -37,7 +37,7 @@ grp.col(["C"]).var().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,2) @@ -74,7 +74,7 @@ grp.col(["C","D"]).var().print() {% endtab %} {% endtabs %} -```text +``` Shape: (2,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -111,7 +111,7 @@ grp.col(["C"]).var().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -153,7 +153,7 @@ grp.col(["C","D"]).var().print() {% endtab %} {% endtabs %} -```text +``` Shape: (5,4) @@ -172,5 +172,4 @@ grp.col(["C","D"]).var().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -\*\*\*\* - +**** diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index f071ac9..e86d5de 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -1,18 +1,18 @@ --- -description: >- - Functions and methods to easily read tabular/structured data into DataFrame - and Series Objects +description: Functions for reading tabular/structured data into DataFrame/Series Objects --- # Input/Output ## CSV -| \`\` | | -| :--- | :--- | -| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values \(csv\) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values \(xls\) file into DataFrame. | -| [`read_json`](danfo.read_json.md) | Read a JSON values \(json\) file into DataFrame. | - -Writing `CSV` and `JSON` is done directly from structured types \(e.g. `DataFrame.to_csv`\) +| \`\` | | +| ----------------------------------- | -------------------------------------------------------- | +| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | +| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | +| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d1ab8f8..030ccb7 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -4,61 +4,31 @@ description: >- reading of CSV files in chunks. --- -# danfo.read\_csv +# danfo.read_csv -> danfo.**read\_csv**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] +> danfo.**read_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source:str, path or URLAny valid string path is acceptable. The string could be a URL. Valid - URL schemes include https, http, ftp, s3, gs, and file. Local file paths - are only accepted in Nodejs environment.
configs:object, optional -

-

A CSV Config object that contains configurations for reading and decoding - from CSV file(s). Supported params are:

-

start: The index position to start from when reading the CSV file.

-

end: The end position to stop at when reading the CSV file.

-

... csvConfigs: other supported Tensorflow csvConfig parameters. - See https://js.tensorflow.org/api/latest/#data.csv -

-
+| **Parameters** | Type | Description | Default | +| -------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | +| **configs**: | object, optional |

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

|

{

dynamicTyping: true,

header: true

}

| **Returns:** - ****_**Promise**_. Resolves to DataFrame +** **_**Promise**_. Resolves to DataFrame -### Example +The **read_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. -The **read\_csv** method can read a csv file from local disk, or over the internet \(URL\). Reading of local files are only supported in danfojs-node. +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_csv("user_names.csv") //assumes file is in CWD +dfd.read_csv("./user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -68,45 +38,9 @@ dfd.read_csv("user_names.csv") //assumes file is in CWD }) ``` {% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - - -``` -{% endtab %} {% endtabs %} -**Loading Files from URL** +### **Reading files from a URL** By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: @@ -134,8 +68,8 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - - + + Document @@ -163,29 +97,11 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c {% endtab %} {% endtabs %} -**Reading Large Files** - -For extremely large files, that cannot be fit in memory at once, you can load them in chunks. For instance, this [dataset](http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.7z) has over 1.5 million rows and will throw a memory error if you try to load everything at once. To read these type of files, you can load them in chunks and perform preprocessing to each chunk: +### **Reading an input file object in the browser** -**Note**: The dataset used in the following example cannot be downloaded over the internet as it is a zip file. So we download locally, unzip and load it in a danfojs-node environment. +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series {% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_process_data() { - let df_chunk1 = await dfd.read_csv("1500000 Sales Records.csv", {start: 0, end: 10}) - let df_chunk2 = await dfd.read_csv("1500000 Sales Records.csv", {start: 10, end: 20}) - - df_chunk1.head().print() - df_chunk2.head().print() -} - -load_process_data() -``` -{% endtab %} - {% tab title="Browser" %} ```markup @@ -194,100 +110,26 @@ load_process_data() - + Document - -
+ - - ``` {% endtab %} {% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Sub-Saharan A... │ South Africa │ Fruits │ Offline │ ... │ 6.92 │ 14862.69 │ 11023.56 │ 3839.13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Morocco │ Clothes │ Online │ ... │ 35.84 │ 503890.08 │ 165258.24 │ 338631.84 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Australia and... │ Papua New Guinea │ Meat │ Offline │ ... │ 364.69 │ 151880.4 │ 131288.4 │ 20592 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Sub-Saharan A... │ Djibouti │ Clothes │ Offline │ ... │ 35.84 │ 61415.36 │ 20142.08 │ 41273.28 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Europe │ Slovakia │ Beverages │ Offline │ ... │ 31.79 │ 188518.85 │ 126301.67 │ 62217.18 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Region │ Country │ Item Type │ Sales Channel │ ... │ Unit Cost │ Total Revenue │ Total Cost │ Total Profit ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Asia │ Taiwan │ Fruits │ Offline │ ... │ 6.92 │ 74957.22 │ 55595.28 │ 19361.94 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Middle East a... │ Algeria │ Cosmetics │ Online │ ... │ 263.33 │ 4227286.8 │ 2546137.77 │ 1681149.03 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Asia │ Singapore │ Snacks │ Online │ ... │ 97.44 │ 1171204.08 │ 747949.44 │ 423254.64 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Australia and... │ Papua New Guinea │ Clothes │ Offline │ ... │ 35.84 │ 993573.76 │ 325857.28 │ 667716.48 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ Asia │ Vietnam │ Personal Care │ Online │ ... │ 56.67 │ 652532.32 │ 452453.28 │ 200079.04 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index d8e3d9e..fe3453a 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -2,58 +2,30 @@ description: Reads an excel file into DataFrame. --- -# danfo.read\_excel - -> danfo.**read\_excel**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)\] - -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> ->
ParametersTypeDescription
sourcestringsource : string, URL or local file path to retreive Excel file.
configsObject ->

{

->

sheet : string, (Optional) Name of the sheet which u want to parse. -> Default will be the first sheet.

->

header_index : int, (Optional) Only used in browser environment. -> The Index of the row which represents the header(columns) of the data. -> Default will be the first non empty row.

->

data_index : int, (Optional) Only used in browser environment. The -> index of the row from which actual data(content) starts. Default will be -> the next row of header_index ->

->

}

->
-> +# danfo.read_excel + +> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] + +| Parameters | Type | Description | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| source | string | **source** : string, URL or local file path to retreive Excel file. | +| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| + > **Returns:** > -> ****return ****{**Promise**} DataFrame structure of parsed Excel data +> ** **return** **{**Promise**} DataFrame structure of parsed Excel data ### Example -The **read\_excel** method can read excel files saved from local disk, or over the internet. +The **read_excel** method can read excel files saved on a local disk, or over the internet. {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") +const path = require("path") -local_xcel = 'testexcel.xls' +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") async function load_process_data() { let df = await dfd.read_excel(local_xcel) @@ -94,4 +66,3 @@ load_process_data() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 49528d0..6566efe 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -2,28 +2,50 @@ description: Reads a JSON file into DataFrame. --- -# danfo.read\_json +# danfo.read_json -> danfo.**read\_json**\(source,\) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)\] +> danfo.**read_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] -| **Parameters** | Type | Description | -| :--- | :--- | :--- | -| _**source**_: | **string**, path or URL | Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported | +| **Parameters** | Type | Description | Default | +| -------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| _**source**_ | Input file object, string file** **path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | +| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| **Returns:** - ****_**Promise**_. Resolves to DataFrame +** **_**Promise**_. Resolves to DataFrame -### Example +The **read_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. -The **read\_json** method can read JSON file from local disk, or over the internet. For instance, in the example below, _**user\_names.json**_ is a JSON file in this same directory as our script. To read it into DataFrame, you can specify the relative path: +### **Reading JSON files from local disk** {% tabs %} {% tab title="Node.js" %} ```javascript const dfd = require("danfojs-node") -dfd.read_json("user_names.json") +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") .then(df => { df.head().print() @@ -36,8 +58,71 @@ dfd.read_json("user_names.json") {% tab title="Browser" %} ```markup + + + + + + + + Document + + + + + + + + ``` {% endtab %} {% endtabs %} +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index e412af9..073e173 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -10,7 +10,7 @@ description: >- ### Basic Line plot on Series -The **line** plot is exposed by the .**plot\(\)** function called on a Series or DataFrame. The **.plot\(\)** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. +The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. ```markup @@ -43,7 +43,7 @@ The **line** plot is exposed by the .**plot\(\)** function called on a Series or ### Line plots on DataFrame -The example below shows the plot of column values against a common x-axis \(index\) +The example below shows the plot of column values against a common x-axis (index) ```markup @@ -73,7 +73,7 @@ The example below shows the plot of column values against a common x-axis \(inde ``` -![](../../.gitbook/assets/newplot-2-%20%281%29%20%281%29%20%282%29.png) +![](<../../.gitbook/assets/newplot-2- (1) (1) (2) (2).png>) The example below shows how to plot two columns in a DataFrame against each other. @@ -110,4 +110,3 @@ The example below shows how to plot two columns in a DataFrame against each othe {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 397b480..e910f57 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -6,7 +6,7 @@ description: Timeseries plot are based on date index ## Examples -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. ```markup @@ -44,17 +44,15 @@ In the example below, we plot the yearly trend of a financial dataset. First, we }).catch(err => { console.log(err); }) - + - ``` -![](../../.gitbook/assets/newplot-29-%20%282%29%20%281%29.png) +![](<../../.gitbook/assets/newplot-29- (2) (1).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/series/README.md b/api-reference/series/README.md index cc25049..7eefaa7 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -4,117 +4,116 @@ description: One-dimensional ndarray with axis labels (including time series). # Series -> `Series`\(data, {**columns:** \[ Array \], **dtypes:** \[ Array \], **index:** \[Array\]}\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)\] +> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ],** index: **\[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] ### Attributes -| [`Series.index`](series.index.md) | The index \(axis labels\) of the Series. | -| :--- | :--- | +| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | +| --------------------------------- | ------------------------------------------- | - -| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | -| :--- | :--- | +| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | +| ----------------------------------- | ---------------------------------------------------------------- | | [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | -| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | -| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | -| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](series.size.md) | Return the number of elements in the underlying data. | +| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | +| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | +| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | +| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | ### Conversion -| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | -| :--- | :--- | -| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | +| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | +| --------------------------------------------------- | ---------------------------------------------- | +| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | ### Indexing, iteration -| | | -| :--- | :--- | -| \`\`[`Series.loc`](../dataframe/danfo.dataframe.loc.md)\`\` | Access a group of rows and columns by label\(s\) or a boolean array. | -| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | +| | | +| ------------------------------------------------------- | ------------------------------------------------------------------ | +| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | +| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | ### Binary operator functions -| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise \(binary operator add\). | -| :--- | :--- | -| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise \(binary operator sub\). | -| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise \(binary operator mul\). | -| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise \(binary operator truediv\). | -| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise \(binary operator mod\). | -| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise \(binary operator pow\). | -| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | -| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise \(binary operator lt\). | -| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise \(binary operator gt\). | -| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise \(binary operator le\). | -| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise \(binary operator ge\). | -| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise \(binary operator ne\). | -| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise \(binary operator eq\). | -| [`Series.dot`](series.dot.md) | Compute the dot product between the Series and the columns of other. | +| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | +| --------------------------------- | --------------------------------------------------------------------------------------- | +| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | +| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | +| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | +| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | +| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | +| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | +| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | +| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | +| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | +| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | +| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | +| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | +| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | ### Function application & GroupBy -| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | -| :--- | :--- | -| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | +| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | +| --------------------------------- | ------------------------------------------------------- | +| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | ### Computations / descriptive stats -| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | -| :--- | :--- | -| [`Series.corr`](series.corr.md) | Compute correlation with other Series, excluding missing values. | -| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | -| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | -| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | -| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | -| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | -| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | -| [`Series.mode`](series.mode.md) | Return the mode\(s\) of the dataset. | -| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | -| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | -| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | -| [`Series.unique`](series.unique.md) | Return unique values of Series object. | -| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value_counts.md) | Return a Series containing counts of unique values. | +| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | +| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | +| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | +| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | +| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | +| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | +| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | +| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | +| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | +| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | +| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | +| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | +| [`Series.unique`](series.unique.md) | Return unique values of Series object. | +| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | +| [`Series.value_counts`](series.value_counts.md) | Return a Series containing counts of unique values. | ### Reindexing / selection / label manipulation -| | | -| :--- | :--- | -| [`Series.drop_duplicates`](series.drop_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | +| | | +| ----------------------------------------------------- | -------------------------------------------------------- | +| [`Series.drop_duplicates`](series.drop_duplicates.md) | Return Series with duplicate values removed. | +| [`Series.head`](series.head.md) | Return the first n rows. | +| [`Series.reset_index`](series.reset_index.md) | Generate a new DataFrame or Series with the index reset. | +| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | +| [`Series.tail`](series.tail.md) | Return the last n rows. | ### Missing data handling -| | | -| :--- | :--- | -| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | -| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | -| [`Series.isna`](series.isna.md) | Detect missing values. | -| [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | +| | | +| ------------------------------------- | ------------------------------------------------ | +| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | +| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | +| [`Series.isna`](series.isna.md) | Detect missing values. | +| [`Series.replace`](series.replace.md) | Replace values given in to_replace with value. | ### Reshaping, sorting -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| :--- | :--- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort_values.md) | Sort by the values. | +| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | +| --------------------------------------------- | ------------------------------------------------------------- | +| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | +| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | +| [`Series.sort_values`](series.sort_values.md) | Sort by the values. | ### Accessors Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. | Data Type | Accessor | -| :--- | :--- | -| Datetime | dt | -| String | str | +| --------- | -------- | +| Datetime | dt | +| String | str | #### Datetimelike properties @@ -122,63 +121,62 @@ Danfo provides dtype-specific methods under various accessors. These are separat **Datetime methods** -| | | -| :--- | :--- | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | +| | | +| ------------------------------------------------- | ------------------------------------------------------------------ | +| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | +| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | +| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | +| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | +| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | +| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | +| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | | [`Series.dt.month_name`](series.dt.month_name.md) | Return the month names of the DateTimeIndex with specified locale. | #### String handling `Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. -| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | -| :--- | :--- | -| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | -| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | -| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index \(position\). | -| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | -| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | -| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | -| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | -| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | -| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | -| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | -| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | -| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | -| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | -| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | -| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | -| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | -| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | -| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | -| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | +| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | +| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | +| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | +| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | +| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | +| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | +| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | +| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | +| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | +| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | +| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | +| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | +| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | +| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | +| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | +| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | +| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | +| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | +| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | ### Plotting `Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. -| | | -| :--- | :--- | -| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | -| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| | | +| ----------------------------------------------------- | ------------------------------------------------------------- | +| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | +| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | | [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | +| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | ### Serialization / IO / conversion -| | | -| :--- | :--- | -| [`Series.to_csv`](../dataframe/dataframe.to_csv.md) | Write object to a comma-separated values \(csv\) file. | -| [`Series.to_json`](../dataframe/dataframe.to_json.md) | Convert the object to a JSON string. | - +| | | +| ----------------------------------------------------- | ---------------------------------------------------- | +| [`Series.to_csv`](../dataframe/dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | +| [`Series.to_json`](../dataframe/dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index db9a8b4..3c9f46a 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,11 +4,13 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)\] +> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] -**Parameters**: None +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Example** @@ -27,7 +29,7 @@ sf.abs().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -48,4 +50,3 @@ sf.abs().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.add.md b/api-reference/series/series.add.md index edde21c..e55b1b8 100644 --- a/api-reference/series/series.add.md +++ b/api-reference/series/series.add.md @@ -1,14 +1,15 @@ --- -description: 'Return Addition of series and other, element-wise (binary operator add).' +description: Return Addition of series and other, element-wise (binary operator add). --- # Series.add -> danfo.Series.add\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)\] +> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -32,7 +33,7 @@ sf1.add(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -65,7 +66,7 @@ sf1.add(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -83,5 +84,3 @@ sf1.add(2).print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.append.md b/api-reference/series/series.append.md index c2e69a8..9c84620 100644 --- a/api-reference/series/series.append.md +++ b/api-reference/series/series.append.md @@ -4,50 +4,19 @@ description: Add a new value or values to the end of a Series. # Series.append -danfo.Series.**append**\(newValue, index, options\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)\] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescriptionDefault
newValueArray, SeriesObject to append
indexArrayThe new index value(s) to append to the Series. Must contain the same - number of values as newValues as they map 1 - 1.
optionsObject -

{ -
inplace: Whether to perform operation in-place or not.

-

}

-
false
+danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | +| newValue | Array, Series | Object to append | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | +| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | **Returns:** - ****return **Series** +** **return** Series** -\*\*\*\* +**** ### **Append new Series to the end of a Series** @@ -67,7 +36,7 @@ new_sf.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔════╤═══╗ ║ f1 │ 1 ║ ╟────┼───╢ @@ -104,7 +73,7 @@ sf1.print() {% endtab %} {% endtabs %} -```text +``` ╔════╤═══╗ ║ f1 │ 1 ║ ╟────┼───╢ @@ -138,14 +107,13 @@ new_sf.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔════╤═══╗ ║ f1 │ 1 ║ ╟────┼───╢ @@ -165,4 +133,3 @@ new_sf.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.apply.md b/api-reference/series/series.apply.md index f32717f..d5feb72 100644 --- a/api-reference/series/series.apply.md +++ b/api-reference/series/series.apply.md @@ -1,20 +1,21 @@ --- -description: invoke a function on Series Value +description: Invoke a function on each value in a Series. --- # Series.apply -> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] +> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function | Function \(can be anonymous\) to apply | | +| Parameters | Type | Description | Default | +| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function | Function (can be anonymous) to apply | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Returns:** - ****return **Series** +** **return** Series** -\*\*\*\* +**** **Example** @@ -34,14 +35,13 @@ sf.apply(apply_func).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -78,14 +78,13 @@ sf.apply(Math.log).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -124,14 +123,13 @@ sf.apply((x)=>{ {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -149,5 +147,3 @@ sf.apply((x)=>{ {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 29c19e3..443935e 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -4,13 +4,13 @@ description: Return the integer indices that would sort the Series values # Series.argsort -> danfo.Series.**argsort**\(ascending\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\)\] +> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| ascending | boolean | How to sort the indices. either **True** or **False** | true | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | +| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| -**Returns:** Series \(int element\) +**Returns: ** Series (int element) **Example** @@ -22,14 +22,16 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() +sf.argsort().print() //defaults to ascending order +sf.argsort({ ascending: false }).print() + ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,7 +51,25 @@ sf.argsort().print() ╟───┼──────────────────────╢ ║ 7 │ 1 ║ ╚═══╧══════════════════════╝ + +//sorted in descending order +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 6 ║ +╟───┼───╢ +║ 2 │ 4 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.copy.md b/api-reference/series/series.copy.md index 323fb47..9bbdb47 100644 --- a/api-reference/series/series.copy.md +++ b/api-reference/series/series.copy.md @@ -1,10 +1,10 @@ --- -description: Make a new copy of a Series +description: Makes a deep copy of a Series --- # Series.copy -> danfo.Series.copy\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)\] +> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] **parameter:** @@ -28,7 +28,7 @@ sf2.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -43,4 +43,3 @@ sf2.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.count.md b/api-reference/series/series.count.md index 222ef23..832c794 100644 --- a/api-reference/series/series.count.md +++ b/api-reference/series/series.count.md @@ -4,7 +4,7 @@ description: Obtain the total number of values in a series # Series.count -> danfo.Series.count\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)\] +> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.count()) {% tabs %} {% tab title="Output" %} -```text +``` 9 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 201ae11..8aded1a 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -4,11 +4,11 @@ description: Returns cumulative maximum over a series # Series.cummax -> danfo.Series.**cummax**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L825)\] +> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] -**Parameters:** None - -**Return**: Series +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -28,7 +28,7 @@ sf1.cummax().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf1.cummax().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index f2337a8..736cee5 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -4,11 +4,11 @@ description: Returns the cumulative min of a Series # Series.cummin -> danfo.Series.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L816)\] +> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] -**Parameters:** None - -**Return**: Series +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -28,7 +28,7 @@ sf1.cummin().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf1.cummin().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 6b72547..84ec0e7 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -4,11 +4,11 @@ description: Return the cumulative product of a series # Series.cumprod -> danfo.Series.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L834)\] +> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] -**Parameters:** None - -**Return**: Series +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -28,7 +28,7 @@ sf1.cumprod().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf1.cumprod().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index 205d777..7b7a19a 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -4,11 +4,11 @@ description: Return a cumulative sum of a series # Series.cumsum -> danfo.Series.**cumsum**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L807)\] +> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] -**Parameters:** None - -**Return**: Series +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -53,7 +53,7 @@ sf1.cumsum().print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,4 +72,3 @@ sf1.cumsum().print() ║ 6 │ 189 ║ ╚═══╧══════════════════════╝ ``` - diff --git a/api-reference/series/series.describe.md b/api-reference/series/series.describe.md index 020cbb1..f532bac 100644 --- a/api-reference/series/series.describe.md +++ b/api-reference/series/series.describe.md @@ -7,9 +7,9 @@ description: >- # Series.describe -> danfo.Series.describe\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)\] +> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] -**Parameters:** No parameter +**Parameters: **No parameter **return:** Series @@ -28,14 +28,13 @@ sf.describe().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔══════════╤══════════════════════╗ ║ │ 0 ║ ╟──────────┼──────────────────────╢ @@ -56,4 +55,3 @@ sf.describe().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.div.md b/api-reference/series/series.div.md index 4dd4fd0..656a796 100644 --- a/api-reference/series/series.div.md +++ b/api-reference/series/series.div.md @@ -6,12 +6,12 @@ description: >- # Series.div -> danfo.Series.div\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)\] +> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | -| round | bool | specify if to round off the floating number | true | +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -35,7 +35,7 @@ sf1.div(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -51,7 +51,7 @@ sf1.div(sf2).print() {% endtab %} {% endtabs %} -divide with a value +### divide with a value {% tabs %} {% tab title="Node" %} @@ -68,7 +68,7 @@ sf1.div(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -85,4 +85,3 @@ sf1.div(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index d5fd7e2..c169043 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -2,20 +2,19 @@ description: Remove duplicate rows --- -# Series.drop\_duplicates +# Series.drop_duplicates -> danfo.Series.**drop\_duplicates**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)\] +> danfo.Series.**drop_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | -| kwargs\["**keep**"\] | String | {"**first**"or "**last**"}. Specify if to keep the last or the first duplicate value | first | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | +| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Examples** -Drop duplicate by keeping the first value of the duplicate value +### Drop duplicate by keeping the first occurrence of the duplicate value {% tabs %} {% tab title="Node" %} @@ -33,7 +32,7 @@ sf_drop.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -51,7 +50,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Drop duplicate and keep only the last duplicated value +### Drop duplicate and keep only the last duplicated value {% tabs %} {% tab title="Node" %} @@ -69,7 +68,7 @@ sf_drop.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -87,7 +86,7 @@ sf_drop.print() {% endtab %} {% endtabs %} -Remove duplicate value in series without returning a new series +### Remove duplicate value in-place {% tabs %} {% tab title="Node" %} @@ -105,7 +104,7 @@ sf.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -120,4 +119,3 @@ sf.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 6fa1100..2fab716 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -4,17 +4,17 @@ description: Remove missing values from Series # Series.dropna -> danfo.Series.**dropna**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)\] +> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| **Returns**: Series **Examples** -Drop all nan value and then return New Series. +### Drop all nan value and then return New Series. {% tabs %} {% tab title="Node" %} @@ -32,7 +32,7 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -52,7 +52,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Drop nan values without returning new series +### Drop nan values in-place {% tabs %} {% tab title="Node" %} @@ -70,7 +70,7 @@ sf.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -89,4 +89,3 @@ sf.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 09334c1..d3722c4 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -4,11 +4,11 @@ description: Obtain the numerical representation of the week day. # Series.dt.day -> danfo.Series.dt.**day**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)\] +> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] **Parameters**: None -**Returns:** Series \(int elements\) +**Returns: **Series (int elements) **Examples** @@ -17,7 +17,7 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) let sf = new dfd.Series(data) sf.dt.day().print() @@ -26,32 +26,30 @@ sf.dt.day().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 0 ║ -╚═══╧══════════════════════╝ ``` - +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ +``` diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 1243049..9656aff 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -4,11 +4,11 @@ description: Obtain the hours in a time series # Series.dt.hour -> danfo.Series.dt.**hour**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)\] +> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] -**Parameters:** None +**Parameters: **None -**Returns:** Series \(int elements\) +**Returns: **Series (int elements) **Examples** @@ -22,37 +22,31 @@ let sf = new dfd.Series(data) // print series sf.print() // print hour series -sf.dt.hour().print() +sf.dt.hours().print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 2:00:00 AM ║ ╚═══╧══════════════════════╝ -//print hour series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╚═══╧═══╝ + ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.minute.md b/api-reference/series/series.dt.minute.md index 4fec5c6..97baa73 100644 --- a/api-reference/series/series.dt.minute.md +++ b/api-reference/series/series.dt.minute.md @@ -4,11 +4,11 @@ description: Obtain the minutes in a Time Series # Series.dt.minutes -> danfo.Series.dt.**minutes**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)\] +> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] **Parameters**: None -**Returns:** Series \(int Elements\) +**Returns: **Series (int Elements) **Example** @@ -28,14 +28,13 @@ sf.dt.minutes().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -59,4 +58,3 @@ sf.dt.minutes().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index 0e6dedb..09841bc 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -4,11 +4,11 @@ description: Obtain the month in a date time series # Series.dt.month -> danfo.Series.dt.**month**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)\] +> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] **Parameters**: None -**Returns:** Series \(int elements\) +**Returns: **Series (int elements) **Examples** @@ -26,26 +26,22 @@ sf.dt.month().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 7 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╟───┼──────────────────────╢ -║ 4 │ 11 ║ -╟───┼──────────────────────╢ -║ 5 │ 11 ║ -╚═══╧══════════════════════╝ ``` - +╔═══╤════╗ +║ 0 │ 6 ║ +╟───┼────╢ +║ 1 │ 7 ║ +╟───┼────╢ +║ 2 │ 9 ║ +╟───┼────╢ +║ 3 │ 9 ║ +╟───┼────╢ +║ 4 │ 11 ║ +╟───┼────╢ +║ 5 │ 11 ║ +╚═══╧════╝ +``` diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index 82a7d3c..2deb259 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -2,13 +2,13 @@ description: obtain the month name in a Time Series --- -# Series.dt.month\_name +# Series.dt.month_name -> danfo.Series.dt.month\_name\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)\] +> danfo.Series.dt.month_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] **Parameters**: None -**Returns:** Series \(String elements\) +**Returns: **Series (String elements) **Examples** @@ -28,17 +28,14 @@ sf.dt.month_name().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2018, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 2/1/2018, 1:00:00 AM ║ @@ -46,17 +43,13 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print month name series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ Jan ║ +╟───┼─────╢ +║ 1 │ Feb ║ +╟───┼─────╢ +║ 2 │ Mar ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index 1c7e556..70026a5 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -4,11 +4,11 @@ description: Obtain the day of the month # Series.dt.monthday -> danfo.Series.dt.**monthday**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)\] +> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] -**Parameters:** None +**Parameters: **None -**Returns**: Series \(Int elements\) +**Returns**: Series (Int elements) **Examples** @@ -28,17 +28,14 @@ sf.dt.monthday().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/2/2000, 1:00:00 AM ║ @@ -46,17 +43,13 @@ sf.dt.monthday().print() ║ 2 │ 1/3/2000, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print monthdays -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index e6fd771..68d63b3 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -4,11 +4,11 @@ description: Obtain the seconds in Date series # Series.dt.seconds -> danfo.Series.dt.**seconds**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)\] +> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] **Parameters**: None -**Returns:** Series \(Int elements\) +**Returns: **Series (Int elements) **Example** @@ -25,24 +25,21 @@ let sf = new dfd.Series(data) sf.print() //print the seconds obtained -sf.seconds().print() +sf.dt.seconds().print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2000, 1:00:01 AM ║ @@ -50,18 +47,14 @@ sf.seconds().print() ║ 2 │ 1/1/2000, 1:00:02 AM ║ ╚═══╧══════════════════════╝ -//the seconds obtained -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index dc79e6c..101bd50 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -4,11 +4,11 @@ description: Obtain the days of the weeks # Series.dt.weekdays -> danfo.Series.dt.**weekdays**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)\] +> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] **Parameters**: None -**Returns:** Series \(String elements\) +**Returns: **Series (String elements) **Examples** @@ -28,55 +28,52 @@ sf.dt.weekdays().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12/31/2016, 1:00:... ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -//print days of the week -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Sat ║ -╟───┼──────────────────────╢ -║ 1 │ Sun ║ -╟───┼──────────────────────╢ -║ 2 │ Mon ║ -╟───┼──────────────────────╢ -║ 3 │ Tue ║ -╟───┼──────────────────────╢ -║ 4 │ Wed ║ -╟───┼──────────────────────╢ -║ 5 │ Thu ║ -╟───┼──────────────────────╢ -║ 6 │ Fri ║ -╟───┼──────────────────────╢ -║ 7 │ Sat ║ -╟───┼──────────────────────╢ -║ 8 │ Sun ║ -╚═══╧══════════════════════╝ ``` +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ +╔═══╤══════╗ +║ 0 │ Sat ║ +╟───┼──────╢ +║ 1 │ Sun ║ +╟───┼──────╢ +║ 2 │ Mon ║ +╟───┼──────╢ +║ 3 │ Tue ║ +╟───┼──────╢ +║ 4 │ Wed ║ +╟───┼──────╢ +║ 5 │ Thur ║ +╟───┼──────╢ +║ 6 │ Fri ║ +╟───┼──────╢ +║ 7 │ Sat ║ +╟───┼──────╢ +║ 8 │ Sun ║ +╟───┼──────╢ +║ 9 │ Mon ║ +╚═══╧══════╝ +``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index a594255..db495d9 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -4,11 +4,11 @@ description: Obtain the year in a date time series # Series.dt.year -> danfo.Series.dt.**year**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)\] +> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] **Parameters**: None -**Returns:** Series \(int elements\) +**Returns: **Series (int elements) **Examples** @@ -25,11 +25,9 @@ sf.dt.year().print() {% endtab %} {% endtabs %} -```text +``` //print date time series ╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ ║ 1 │ 1/1/2001, 1:00:00 AM ║ @@ -37,15 +35,11 @@ sf.dt.year().print() ║ 2 │ 1/1/2002, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -//print the year series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2000 ║ -╟───┼──────────────────────╢ -║ 1 │ 2001 ║ -╟───┼──────────────────────╢ -║ 2 │ 2002 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ 2000 ║ +╟───┼──────╢ +║ 1 │ 2001 ║ +╟───┼──────╢ +║ 2 │ 2002 ║ +╚═══╧══════╝ ``` - diff --git a/api-reference/series/series.dtype.md b/api-reference/series/series.dtype.md index b59170e..c4634cb 100644 --- a/api-reference/series/series.dtype.md +++ b/api-reference/series/series.dtype.md @@ -4,11 +4,11 @@ description: Obtain the dtype of a series # Series.dtype -> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)\] +> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] **Parameters**: None -**Returns:** String +**Returns: **String **Example** @@ -27,9 +27,8 @@ console.log(sf1.dtype) {% tabs %} {% tab title="Output" %} -```text +``` float32 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 341dbb9..43a3ece 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -4,13 +4,13 @@ description: Check all the values in a series is equal to another value # Series.eq -> danfo.Series.eq\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)\] +> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | -**Returns**: Series \(Boolean element\) +**Returns**: Series (Boolean element) **Examples** @@ -33,7 +33,7 @@ sf1.eq(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.eq(10).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -93,4 +93,3 @@ sf1.eq(10).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index b1bea1b..a1db3a8 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -4,18 +4,15 @@ description: Replace all NaN value with specified value # Series.fillna -> danfo.Series.**fillna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)\] +> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**value**"\] | int \| String\| bool | value to replace the NaN values | | -| kwargs\["**inplace**"\] | bool | return a new series or not. | false | - -**Returns:** Series +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| **Examples** -Fill nan value and then return new series +### Fill nan value and then return new series {% tabs %} {% tab title="Node" %} @@ -34,7 +31,7 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -62,7 +59,7 @@ sf_rep.print() {% endtab %} {% endtabs %} -Fill nan value without returning new Series +### Fill nan value in-place {% tabs %} {% tab title="Node" %} @@ -80,7 +77,7 @@ sf.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -107,4 +104,3 @@ sf.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index b3d8b69..ec83ef9 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -4,13 +4,13 @@ description: Check if all the values in a series is greater than or equal a valu # Series.ge -> danfo.Series.ge\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)\] +> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | -**Returns:** Series \(Boolean element\) +**Returns: **Series (Boolean element) **Example** @@ -33,7 +33,7 @@ sf1.ge(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.ge(20).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -93,4 +93,3 @@ sf1.ge(20).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index a98f618..184ca28 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -4,13 +4,13 @@ description: Check if all the value in a series is greater than a value # Series.gt -> danfo.Series.gt\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)\] +> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | -**Returns**: Series \(boolean element\) +**Returns**: Series (boolean element) **Example** @@ -31,7 +31,7 @@ sf1.gt(20).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.gt(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -93,4 +93,3 @@ sf1.gt(sf2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index e580803..ab578cf 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -1,26 +1,27 @@ # Series.iloc -danfo.Series.**iloc**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)\] +danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Array | Array, slice or index of row position to return | | +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | **Returns:** - ****return **Series** +** **return** Series** ## **Examples** -`.iloc()` is primarily integer position based \(from `0` to `length-1` of the axis\). +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). Allowed inputs are: * An integer, e.g. `5`. * A list or array of integers, e.g. `[4, 3, 0]`. +* A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only ****the start label is included._ +_**Note: **only** **the start label is included, and the end label is ignored. _ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -30,7 +31,6 @@ _**Note:** only ****the start label is included._ {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -// const tf = require("@tensorflow/tfjs-node") let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) @@ -41,14 +41,13 @@ s.iloc([0,5]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -62,7 +61,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end\], e.g "\[1: 4\]". This will return all values between index position 1 and 3. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. {% tabs %} {% tab title="Node" %} @@ -76,14 +75,13 @@ s.iloc(["0:5"]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -115,14 +113,13 @@ s.iloc(["5:"]).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -136,5 +133,26 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index e9056d7..4571b72 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -4,13 +4,13 @@ description: Check if all the values in a series is less than or equal to a valu # Series.le -> danfo.Series.le\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)\] +> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | -**Returns:** Series \(Boolean Element\) +**Returns: **Series (Boolean Element) **Example** @@ -31,7 +31,7 @@ sf1.le(20).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.le(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -94,5 +94,3 @@ sf1.le(sf2).print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index bb18486..7af18bc 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -4,13 +4,13 @@ description: Check if all values in a Series are less than a value. # Series.lt -> danfo.Series.lt\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)\] +> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|float | value\(s\) to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | -**Returns**: Series \(boolean element\) +**Returns**: Series (boolean element) **Example** @@ -31,7 +31,7 @@ sf1.lt(20).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.lt(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -94,4 +94,3 @@ sf1.lt(sf2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.map.md b/api-reference/series/series.map.md index 1071a1f..0e0850a 100644 --- a/api-reference/series/series.map.md +++ b/api-reference/series/series.map.md @@ -1,25 +1,26 @@ --- -description: Map the value of a series to it representation +description: Map the value of a series to a function or Object --- # Series.map -> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] +> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] -| Parameter | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function or Object | callable can either be a function or an object\({}\) | | +| Parameter | Type | Description | Default | +| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function or Object | A function or object({}) | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Example** -Mapping the element in a Series to a word +Mapping the element in a Series words in an Object {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let sf = new dfd.Series([1,2,3,4]) +let sf = new dfd.Series([1, 2, 3, 4]) let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } sf.map(map).print() @@ -28,14 +29,13 @@ sf.map(map).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -69,14 +69,13 @@ sf.map((x)=>{ {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -91,4 +90,3 @@ sf.map((x)=>{ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.max.md b/api-reference/series/series.max.md index 34195a2..4f7193a 100644 --- a/api-reference/series/series.max.md +++ b/api-reference/series/series.max.md @@ -4,7 +4,7 @@ description: Obtain the maximum value in a Series # Series.max -> danfo.Series.max\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)\] +> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.max()) {% tabs %} {% tab title="Output" %} -```text +``` 89 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.mean.md b/api-reference/series/series.mean.md index ace7e71..17d97e6 100644 --- a/api-reference/series/series.mean.md +++ b/api-reference/series/series.mean.md @@ -4,7 +4,7 @@ description: Obtain the mean of a series # Series.mean -> danfo.Series.mean\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)\] +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.mean()) {% tabs %} {% tab title="Output" %} -```text +``` 23.000001907348633 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.median.md b/api-reference/series/series.median.md index 280a565..d1cde75 100644 --- a/api-reference/series/series.median.md +++ b/api-reference/series/series.median.md @@ -4,7 +4,7 @@ description: Obtain the median of a series # Series.median -> danfo.Series.median\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)\] +> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.median()) {% tabs %} {% tab title="Output" %} -```text +``` 4 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.min.md b/api-reference/series/series.min.md index 3f57bd1..6e11a67 100644 --- a/api-reference/series/series.min.md +++ b/api-reference/series/series.min.md @@ -4,7 +4,7 @@ description: Obtain the minimum value in a series # Series.min -> danfo.Series.min\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)\] +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.min()) {% tabs %} {% tab title="Output" %} -```text +``` 0 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.mod.md b/api-reference/series/series.mod.md index 59a0320..fdf0555 100644 --- a/api-reference/series/series.mod.md +++ b/api-reference/series/series.mod.md @@ -1,14 +1,15 @@ --- -description: 'Return Modulo of series and other, element-wise (binary operator mod).' +description: Return Modulo of series and other, element-wise (binary operator mod). --- # Series.mod -> danfo.Series.mod\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)\] +> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\|float | values | | +| Parameters | Type | Description | Default | +| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\|float | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -32,7 +33,7 @@ sf1.mod(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -65,7 +66,7 @@ sf1.mod(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -82,4 +83,3 @@ sf1.mod(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.mode.md b/api-reference/series/series.mode.md index 5c93091..6077686 100644 --- a/api-reference/series/series.mode.md +++ b/api-reference/series/series.mode.md @@ -4,7 +4,7 @@ description: Obtain the center value in a series # Series.mode -> danfo.Series.min\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)\] +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.mode()) {% tabs %} {% tab title="Output" %} -```text +``` [ 4 ] ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.mul.md b/api-reference/series/series.mul.md index 855173b..d5d33de 100644 --- a/api-reference/series/series.mul.md +++ b/api-reference/series/series.mul.md @@ -1,14 +1,15 @@ --- -description: 'Return Multiplication of series and other, element-wise (binary operator mul).' +description: Return Multiplication of series and other, element-wise (binary operator mul). --- # Series.mul -> danfo.Series.mul\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)\] +> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -32,7 +33,7 @@ sf1.mul(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -65,7 +66,7 @@ sf1.mul(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -83,5 +84,3 @@ sf1.mul(2).print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.ndim.md b/api-reference/series/series.ndim.md index f7f466e..8258e46 100644 --- a/api-reference/series/series.ndim.md +++ b/api-reference/series/series.ndim.md @@ -4,11 +4,11 @@ description: Obtain the dimension of a series # Series.ndim -> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)\] +> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] -**Parameters:** None +**Parameters: **None -**Returns:** int +**Returns: **int **Example** @@ -27,9 +27,8 @@ console.log(sf1.ndim) {% tabs %} {% tab title="Output" %} -```text +``` 1 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index 9901dcd..16cf1dc 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -4,13 +4,13 @@ description: Check if all values in a series is not equal to a value(s) # Series.ne -> danfo.Series.ne\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)\] +> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series**\|** int\|String\|float | value to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | -**Returns**: Series \(Boolean element\) +**Returns**: Series (Boolean element) **Example** @@ -33,7 +33,7 @@ sf1.ne(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -72,7 +72,7 @@ sf1.ne(10).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -93,4 +93,3 @@ sf1.ne(10).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 8ddafe4..1adfe98 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -1,14 +1,14 @@ --- -description: Obtain the number of unique values in a series +description: Returns the number of unique values in a series --- # Series.nunique -> danfo.Series.**nunique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)\] +> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] **Parameters**: None -**Returns:** int +**Returns: **int **Example** @@ -27,9 +27,8 @@ console.log(sf.nunique()) {% tabs %} {% tab title="Ouptut" %} -```text +``` 9 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.pow.md b/api-reference/series/series.pow.md index 6a67b3b..2fbe542 100644 --- a/api-reference/series/series.pow.md +++ b/api-reference/series/series.pow.md @@ -6,11 +6,12 @@ description: >- # Series.pow -> danfo.Series.pow\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)\] +> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -34,7 +35,7 @@ sf1.pow(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -67,7 +68,7 @@ sf1.pow(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -84,4 +85,3 @@ sf1.pow(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index 4b49fa2..8a1f48b 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,19 +4,17 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)\] +> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["**replace**"\] | int \| String\| bool | value to be replaced | | -| kwargs\["**with**"\] | int \| String \| bool | value to replace the previous value | | -| kwargs\["**inplace**"\] | Bool | mutate the series or create the new series | false | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| **Returns**: Series **Examples** -Replace a value in a series and return a new series +### Replace a value in a series and return a new series {% tabs %} {% tab title="Node" %} @@ -25,7 +23,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ replace: 10, with: -50 }) +let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) sf_rep.print() ``` @@ -34,29 +32,28 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + ``` {% endtab %} {% endtabs %} -Replace a value in a series , with out returning a new series +### Replace a value in-place {% tabs %} {% tab title="Node" %} @@ -65,30 +62,28 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ replace: 10, with: -50, inplace:true }) +sf.replace({ oldValue: 10, newValue: -50, inplace: true}) sf.print() ``` {% endtab %} {% endtabs %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -50 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ -50 ║ -╚═══╧══════════════════════╝ ``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ +``` diff --git a/api-reference/series/series.reset_index.md b/api-reference/series/series.reset_index.md index e03ea87..7ff93af 100644 --- a/api-reference/series/series.reset_index.md +++ b/api-reference/series/series.reset_index.md @@ -2,142 +2,112 @@ description: Reset the index of a series. --- -# Series.reset\_index +# Series.reset_index -> danfo.series.reset\_index\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] +> danfo.series.reset_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] -Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object | **inplace: **Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object | kwargs is an object {} with key **inplace** with a boolean value. e.g {inplace: false} | inplace:false | +**Returns : **Series -**Returns :** Series +`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. -**Example** +### **Reset index to default values** {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") +let data = [20, 30, 40] +let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) +sf.print() -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) -let sf_reset = sf_new.reset_index() -sf_reset.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ {"alpha":"A","cou... ║ -╟───┼──────────────────────╢ -║ 1 │ {"alpha":"B","cou... ║ -╟───┼──────────────────────╢ -║ 2 │ {"alpha":"C","cou... ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) - -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) let sf_reset = sf.reset_index() sf_reset.print() - ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ a │ 20 ║ +╟───┼────╢ +║ b │ 30 ║ +╟───┼────╢ +║ c │ 40 ║ +╚═══╧════╝ + +╔═══╤════╗ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 2 │ 40 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} -Reset index without returning a new Series +### Reset index to new values in-place {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) +sf.print() -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -sf.reset_index({"inplace":true}) +sf.reset_index({ inplace: true }) sf.print() + ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╟───┼───╢ +║ f │ 6 ║ +╚═══╧═══╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 4 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 6 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.round.md b/api-reference/series/series.round.md index 3dcc39f..7b7ed7c 100644 --- a/api-reference/series/series.round.md +++ b/api-reference/series/series.round.md @@ -4,13 +4,14 @@ description: round off floating values in series # Series.round -> danfo.Series.round\(dp\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)\] +> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| dp | int | decimal place to round off to | | +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| dp | int | decimal place to round off to | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Example** @@ -29,7 +30,7 @@ sf1.round(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -45,5 +46,3 @@ sf1.round(2).print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.sample.md b/api-reference/series/series.sample.md index 4ab195e..762e635 100644 --- a/api-reference/series/series.sample.md +++ b/api-reference/series/series.sample.md @@ -4,16 +4,16 @@ description: Return a random sample of items from an axis of object. # Series.sample -> danfo.Series.sample\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)\] +> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| num | Int | The number of rows to return. | | +| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| **Returns:** - ****return **{Promies} resolves to Series** +** **return** {Promies} resolves to Series** **Example** @@ -33,20 +33,33 @@ load_data() {% tabs %} {% tab title="Output" %} ```javascript -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 7 │ 40 ║ -╟───┼──────────────────────╢ -║ 6 │ 30 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 2 │ 3 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 0 │ 1 ║ +╟───┼────╢ +║ 7 │ 40 ║ +╟───┼────╢ +║ 6 │ 30 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} +### Specify a seed when sampling + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5, { seed: 2 }) + sample.print() + +} +load_data() + +``` diff --git a/api-reference/series/series.set_index.md b/api-reference/series/series.set_index.md index 91adf23..0b9cad9 100644 --- a/api-reference/series/series.set_index.md +++ b/api-reference/series/series.set_index.md @@ -2,16 +2,16 @@ description: Assign new Index to Series --- -# Series.set\_index +# Series.set_index -> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)\] +> danfo.series.**set_index(**options**) **\[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["index"\] | Array | index to replace the former index | | -| kwargs\["inplace"\] | Boolean | return new series or not | false | +| Parameter | Type | Description | Default | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| index | Array | new index values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Example** @@ -19,9 +19,10 @@ description: Assign new Index to Series {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") - let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] let sf = new dfd.Series(data) +sf.print() + let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) sf_new.print() ``` @@ -29,23 +30,28 @@ sf_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ one │ {"alpha":"A","cou... ║ -╟───────┼──────────────────────╢ -║ two │ {"alpha":"B","cou... ║ -╟───────┼──────────────────────╢ -║ three │ {"alpha":"C","cou... ║ -╚═══════╧══════════════════════╝ +``` +╔═══╤═════════════════════════╗ +║ 0 │ {"alpha":"A","count":1} ║ +╟───┼─────────────────────────╢ +║ 1 │ {"alpha":"B","count":2} ║ +╟───┼─────────────────────────╢ +║ 2 │ {"alpha":"C","count":3} ║ +╚═══╧═════════════════════════╝ + +╔═══════╤═════════════════════════╗ +║ one │ {"alpha":"A","count":1} ║ +╟───────┼─────────────────────────╢ +║ two │ {"alpha":"B","count":2} ║ +╟───────┼─────────────────────────╢ +║ three │ {"alpha":"C","count":3} ║ +╚═══════╧═════════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -64,14 +70,13 @@ sf_new.print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -89,46 +94,43 @@ sf_new.print() {% endtab %} {% endtabs %} -set index without creating a new series by using `inplace = true` +### Set index in-place {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs") -let data = [1,2,3,4,5,6] +let data = [1, 2, 3, 4, 5, 6] let sf = new dfd.Series(data) -sf.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) sf.print() ``` {% endtab %} {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ one │ 1 ║ -╟───────┼──────────────────────╢ -║ two │ 2 ║ -╟───────┼──────────────────────╢ -║ three │ 3 ║ -╟───────┼──────────────────────╢ -║ four │ 4 ║ -╟───────┼──────────────────────╢ -║ five │ 5 ║ -╟───────┼──────────────────────╢ -║ six │ 6 ║ -╚═══════╧══════════════════════╝ +``` +╔═══════╤═══╗ +║ one │ 1 ║ +╟───────┼───╢ +║ two │ 2 ║ +╟───────┼───╢ +║ three │ 3 ║ +╟───────┼───╢ +║ four │ 4 ║ +╟───────┼───╢ +║ five │ 5 ║ +╟───────┼───╢ +║ six │ 6 ║ +╚═══════╧═══╝ + ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.sort_values.md b/api-reference/series/series.sort_values.md index 54966ac..5c7e5fa 100644 --- a/api-reference/series/series.sort_values.md +++ b/api-reference/series/series.sort_values.md @@ -1,21 +1,18 @@ --- -description: Sort a Series in ascending or descending order +description: Sorts a Series in ascending or descending order --- -# Series.sort\_values +# Series.sort_values -> danfo.Series.sort\_values\(kwargs\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)\] +> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs\["inplace"\] | Boolean | return new series or not | false | -| kwargs\["ascending"\] | Boolean | select if to sort by ascending or descending | true | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| **Return:** Series -**Examples** - -Sort series values using the default settings +### Sort values in a Series {% tabs %} {% tab title="Node" %} @@ -33,33 +30,31 @@ sf2.print() {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} -Sort series value without returning a new series +### Sort Series in-place {% tabs %} {% tab title="Node" %} @@ -68,7 +63,7 @@ const dfd = require("danfojs-node") let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] let sf1 = new dfd.Series(data1) -sf1.sort_values({ "inplace": true }) +sf1.sort_values({ inplace: true }) sf1.print() ``` @@ -77,33 +72,32 @@ sf1.print() {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ + ``` {% endtab %} {% endtabs %} -Sort series value in descending order +Sort Series values in descending order {% tabs %} {% tab title="Node" %} @@ -121,29 +115,26 @@ sf1.print() {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 6 │ 89 ║ -╟───┼──────────────────────╢ -║ 5 │ 57 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 8 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 7 │ 0 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 6 │ 89 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 7 │ 0 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.capitalize.md b/api-reference/series/series.str.capitalize.md index 5df261a..aea9e91 100644 --- a/api-reference/series/series.str.capitalize.md +++ b/api-reference/series/series.str.capitalize.md @@ -4,11 +4,13 @@ description: Capitalize the first character of each string # Series.str.capitalize -> danfo.Series.str.**capitalize**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)\] +> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] -**Parameters:** None +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns**: Series \(String element\) +**Returns**: Series (String element) **Example** @@ -27,14 +29,13 @@ sf.str.capitalize().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +50,3 @@ sf.str.capitalize().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.charat.md b/api-reference/series/series.str.charat.md index 3df2bbc..931bb48 100644 --- a/api-reference/series/series.str.charat.md +++ b/api-reference/series/series.str.charat.md @@ -4,13 +4,14 @@ description: Obtain the character at the specified index (position) # Series.str.charAt -> danfo.Series.str.**charAt**\(index\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)\] +> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| index | int | the index at which to obtain the character | 0 | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| index | int | the index at which to obtain the character | 0 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns**: Series \(Character element\) +**Returns**: Series (Character element) **Example** @@ -29,14 +30,13 @@ sf.str.charAt(2).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -51,4 +51,3 @@ sf.str.charAt(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index 0a24597..2fa49d4 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -4,14 +4,15 @@ description: Joins two or more strings/arrays # Series.str.concat -> danfo.Series.str.**concat**\(other, position\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)\] +> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other** \(string or array\) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| other | string or Array | string or list of strings to add to each string element of the series | "" | +| position | Int | The position to add the **other **(string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns:** Series \(String element\) +**Returns: **Series (String element) **Examples** @@ -31,14 +32,13 @@ sf.str.concat(data2,0).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -70,14 +70,13 @@ sf.str.concat(data2,1).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -109,14 +108,13 @@ sf.str.concat("pre",0).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -148,12 +146,11 @@ sf.str.concat("post",1).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -166,4 +163,3 @@ sf.str.concat("post",1).print() ║ 3 │ SwApCaSepost ║ ╚═══╧══════════════════════╝ ``` - diff --git a/api-reference/series/series.str.endswith.md b/api-reference/series/series.str.endswith.md index 645294d..2fb44cc 100644 --- a/api-reference/series/series.str.endswith.md +++ b/api-reference/series/series.str.endswith.md @@ -4,13 +4,14 @@ description: Checks whether a string ends with specified characters # Series.str.endsWith -> danfo.Series.str.**endsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)\] +> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns**: Series \(Boolean element\) +**Returns**: Series (Boolean element) **Example** @@ -27,14 +28,13 @@ sf.str.endsWith("e").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf.str.endsWith("e").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.includes.md b/api-reference/series/series.str.includes.md index c2cb4af..8918773 100644 --- a/api-reference/series/series.str.includes.md +++ b/api-reference/series/series.str.includes.md @@ -4,13 +4,14 @@ description: Checks whether a string contains the specified string/characters # Series.str.includes -> danfo.Series.str.includes\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)\] +> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns**: Series \(boolean element\) +**Returns**: Series (boolean element) **Example** @@ -27,14 +28,13 @@ sf.str.includes("C").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf.str.includes("C").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index a823d20..8328d8b 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -4,13 +4,14 @@ description: the position of the first found occurrence of a specified value in # Series.str.indexOf -> danfo.Series.str.indexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)\] +> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to obtain its index | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to obtain its index | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Example** @@ -27,14 +28,13 @@ sf.str.indexOf("C").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf.str.indexOf("C").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index 4c17295..386da02 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -4,16 +4,17 @@ description: Join a new string value to all string elements in a Series. # Series.str.join -> danfo.Series.str.**join**\(valToJoin,joinChar\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)\] +> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| valToJoin | String | the string value you want to | "" | +| joinChar | String | The delimiter to specify the joining | " " | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns:** - ****return **Series** +** **return **Series** **Examples** @@ -30,26 +31,22 @@ sf.str.join("new", "_").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part_new ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentenc... ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════════════════════════╗ +║ 0 │ lower part_new ║ +╟───┼────────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼────────────────────────╢ +║ 2 │ this is a sentence_new ║ +╟───┼────────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧════════════════════════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.lastindexof.md b/api-reference/series/series.str.lastindexof.md index 130c50c..889a1f4 100644 --- a/api-reference/series/series.str.lastindexof.md +++ b/api-reference/series/series.str.lastindexof.md @@ -6,11 +6,12 @@ description: >- # Series.str.lastIndexOf -danfo.Series.str.lastIndexOf\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)\] +danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the string to search for | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns**: Series @@ -29,14 +30,13 @@ sf.str.lastIndexOf("r").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -52,5 +52,3 @@ sf.str.lastIndexOf("r").print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.str.len.md b/api-reference/series/series.str.len.md index 60153e8..0ef06b2 100644 --- a/api-reference/series/series.str.len.md +++ b/api-reference/series/series.str.len.md @@ -4,24 +4,22 @@ description: Obtain the length of each string element in a Series # Series.str.len -> danfo.Series.str.**len**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)\] +> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] -**Parameters**: None - -**Returns:** - - return Series +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Examples** -Returns the length \(number of character\) of a string, and also return the length \(number of elements\) of Array +Returns the length (number of character) of a string, and also return the length (number of elements) of Array {% tabs %} {% tab title="JavaScript" %} ```javascript const dfd = require("danfojs-node") -let data = ["dog", 5,"cat",["fog","mug"],"animals"] +let data = ["dog", 5,"cat","fog","mug","animals"] let sf = new dfd.Series(data) sf.str.len().print() ``` @@ -29,28 +27,26 @@ sf.str.len().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ NaN ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index e6c1f32..76f9073 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -4,13 +4,14 @@ description: Repeat the the character(s) in a string for a specified number of t # Series.str.repeat -> danfo.Series.str.**repeat**\(num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)\] +> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| num | integer | the string to search for | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | +| num | integer | the string to search for | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series **Example** @@ -27,14 +28,13 @@ sf.str.repeat(4).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf.str.repeat(4).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index c96137c..da02575 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,14 +4,15 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace\(searchValue, replaceValue\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)\] +> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| searchValue | string | the string to search for | "" | -| replaceValue | String | string to replace the searched string | "" | +| Parameters | Type | Description | Default | +| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| searchValue | string | String \| Character value to replace. Supports regex. | "" | +| replaceValue | String | string to replace the searched string | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns:** Series +**Returns: **Series {% tabs %} {% tab title="Node" %} @@ -26,14 +27,13 @@ sf.str.replace("A", "XXX").print() {% tab title="Browse" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -48,4 +48,3 @@ sf.str.replace("A", "XXX").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 8824095..9dc48e0 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -4,17 +4,18 @@ description: Obtain the index position of a searched character in a String # Series.str.search -> danfo.Series.str.**search**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)\] +> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | String | the string to search for | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | String | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns:** - ****return Series: Series of index position +** **return Series: Series of index position **Example** @@ -33,14 +34,13 @@ sf.str.search("S").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -71,14 +71,13 @@ sf.str.search("city").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -93,4 +92,3 @@ sf.str.search("city").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index d314066..a807a36 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -4,16 +4,17 @@ description: Obtain the substring of each element in a series # Series.str.slice -> danfo.Series.str.slice\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)\] +> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns:** - ****return Series. +** **return Series. **Example** @@ -30,14 +31,13 @@ sf.str.slice(2, 4).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -52,4 +52,3 @@ sf.str.slice(2, 4).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 65a82c7..8ba84b6 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,11 +6,12 @@ description: >- # Series.str.split -> danfo.Series.str.**split**\(splitVal\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L250)\] +> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| splitVal | String | separator or delimiter used to split the string | " " | +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | +| splitVal | String | separator or delimiter used to split the string | " " | +| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| **Returns** @@ -33,12 +34,11 @@ console.log(sf.str.split().values) {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} -**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` +**OUTPUT: **`[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` {% tabs %} {% tab title="JavaScript" %} @@ -53,14 +53,13 @@ sf.str.split("_").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -73,4 +72,3 @@ sf.str.split("_").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index 311bb2f..6290122 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -4,13 +4,14 @@ description: Test whether a string begins with specified characters # Series.str.startsWith -> danfo.Series.str.**startsWith**\(str\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)\] +> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| str | string | the character\(s\) to check | "" | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns:** Series \(Boolean element\) +**Returns: **Series (Boolean element) **Examples** @@ -27,14 +28,13 @@ sf.str.startsWith("S").print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +49,3 @@ sf.str.startsWith("S").print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index 1512f02..bb58cfd 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -6,20 +6,21 @@ description: >- # Series.str.substr -> danfo.Series.str.substr\(startIndex, num\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)\] +> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| num | Number | The number of character to obtain starting from the startIndex | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns:** - ****return Series +** **return Series **Example** -Obtain substring\( containing 4 characters\) starting from the third character \(2nd index\). +Obtain substring( containing 4 characters) starting from the third character (2nd index). ```javascript const dfd = require("danfojs-node") @@ -47,4 +48,3 @@ sf.str.substr(2, 4).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 73ab3a8..39bd460 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -4,16 +4,17 @@ description: Obtain the substring of each element in a series # Series.str.substring -> danfo.Series.str.**substring**\(startIndex, endIndex\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)\] +> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns** - ****return **Series** +** **return **Series** **Example** @@ -32,14 +33,13 @@ sf.str.substring(2, 4).print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -54,4 +54,3 @@ sf.str.substring(2, 4).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.tolowercase.md b/api-reference/series/series.str.tolowercase.md index ada457b..9abe0f5 100644 --- a/api-reference/series/series.str.tolowercase.md +++ b/api-reference/series/series.str.tolowercase.md @@ -4,11 +4,11 @@ description: Converts all characters to lower case. # Series.str.toLowerCase -> danfo.Series.str.toLowerCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)\] +> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] -**Parameters:** None - -**Returns**: Series \(String element\) +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -27,14 +27,13 @@ sf.str.toLowerCase().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +48,3 @@ sf.str.toLowerCase().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.touppercase.md b/api-reference/series/series.str.touppercase.md index 7e23c08..f484390 100644 --- a/api-reference/series/series.str.touppercase.md +++ b/api-reference/series/series.str.touppercase.md @@ -4,11 +4,13 @@ description: Converts all characters to uppercase. # Series.str.toUpperCase -> danfo.Series.str.toUpperCase\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)\] +> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] -**Parameters:** None +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns**: Series \(String element\) +**Returns**: Series (String element) **Example** @@ -27,14 +29,13 @@ sf.str.toUpperCase().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -49,4 +50,3 @@ sf.str.toUpperCase().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index 7e30db5..c5df92a 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -4,13 +4,15 @@ description: Remove leading and trailing Whitespace from a String element # Series.str.trim -> danfo.Series.str.**trim**\(\) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**\]** +> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** -**Parameters:** None +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Returns:** - ****return Series +** **return Series {% tabs %} {% tab title="Node" %} @@ -25,14 +27,13 @@ sf.str.trim().print() {% tab title="Browser" %} ``` - ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -47,4 +48,3 @@ sf.str.trim().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.sub.md b/api-reference/series/series.sub.md index 95da267..e281d06 100644 --- a/api-reference/series/series.sub.md +++ b/api-reference/series/series.sub.md @@ -1,14 +1,15 @@ --- -description: 'Return Subtraction of series and other, element-wise (binary operator sub).' +description: Return Subtraction of series and other, element-wise (binary operator sub). --- # Series.sub -> danfo.Series.sub\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)\] +> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series\|int\| | values | | +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Return:** Series @@ -32,7 +33,7 @@ sf1.sub(sf2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -65,7 +66,7 @@ sf1.sub(2).print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -83,5 +84,3 @@ sf1.sub(2).print() {% endtab %} {% endtabs %} - - diff --git a/api-reference/series/series.sum.md b/api-reference/series/series.sum.md index 838283c..fabcba7 100644 --- a/api-reference/series/series.sum.md +++ b/api-reference/series/series.sum.md @@ -4,7 +4,7 @@ description: Return the sum of the values in a series. # Series.sum -> danfo.Series.sum\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)\] +> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] **Parameter:** None @@ -27,11 +27,10 @@ console.log(sf1.sum()) {% tabs %} {% tab title="Output" %} -```text +``` 207 ``` {% endtab %} {% endtabs %} -\*\*\*\* - +**** diff --git a/api-reference/series/series.value_counts.md b/api-reference/series/series.value_counts.md index 7d99ff2..e8d0ad7 100644 --- a/api-reference/series/series.value_counts.md +++ b/api-reference/series/series.value_counts.md @@ -2,13 +2,13 @@ description: Count the number of occurrence for each element in a Series --- -# Series.value\_counts +# Series.value_counts -> danfo.Series.value\_counts\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)\] +> danfo.Series.value_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] -**Parameters:** None +**Parameters: **None -**Returns:** Series \(int element\) +**Returns: **Series (int element) **Example** @@ -27,7 +27,7 @@ sf.value_counts().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔════╤══════════════════════╗ ║ │ 0 ║ ╟────┼──────────────────────╢ @@ -52,4 +52,3 @@ sf.value_counts().print() ``` {% endtab %} {% endtabs %} - diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index ea67970..0bfd0a3 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -1,6 +1,6 @@ # Building Data Driven Applications with Danfo.js - Book -## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo_ code before 31st December 2020 and get 25% discount. +## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo _ code before 31st December 2020 and get 25% discount. ## What this book is about @@ -8,7 +8,7 @@ The book then shows you how to load different datasets, combine and analyze them By the end of this app development book, you'll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser. -![Danfo.js book cover](.gitbook/assets/b17076_cover.jpg) +![Danfo.js book cover](.gitbook/assets/b17076\_cover.jpg) ## **What you will learn** @@ -39,5 +39,3 @@ This book is for data analysts, data scientists, and JavaScript developers who w 12. Building a Twitter Analysis Dashboard 13. Appendix: Essential JavaScript Concepts - - diff --git a/contributing-guide.md b/contributing-guide.md index 878a606..05d635b 100644 --- a/contributing-guide.md +++ b/contributing-guide.md @@ -25,7 +25,7 @@ description: >- * Committing your code * Pushing your changes * Review your code and finally, make the pull request -* Danfojs internal \(Brief\) +* Danfojs internal (Brief) ## TL:DR @@ -33,7 +33,7 @@ All contributions, bug reports, bug fixes, documentation improvements, enhanceme For contributors familiar with open-source, below is a quick guide to setting up danfojs locally. -```text +``` git clone https://github.com/opensource9ja/danfojs.git cd danfojs git checkout -b @@ -43,14 +43,14 @@ There are two folders, **danfojs-browser** and **danfojs-node**. If you are cont For instance, if I want to do some bug fixes in danfojs-node. I can do the following: -```text +``` cd danfojs-node yarn ##install all packages ``` Add my bug fixes and ensure test passes: -```text +``` yarn test ## run test ``` @@ -80,14 +80,14 @@ You will need your own fork to work on the code. Go to the danfojs [project page Next, you will clone your fork to your local machine: -```text +``` git clone https://github.com/opensource9ja/danfojs.git cd danfojs ``` -This creates the directory danfojs and connects your repository to the upstream \(main project\) repository. +This creates the directory danfojs and connects your repository to the upstream (main project) repository. -> **All development are done in two folders--**[**danfojs-browser**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-browser) **and** [**danfojs-node**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-node) **folders. The two folders are similar and it is always recommended to pull latest changes from master before development in any of the folder.** +> **All development are done in two folders--**[**danfojs-browser**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-browser)** and **[**danfojs-node**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-node)** folders. The two folders are similar and it is always recommended to pull latest changes from master before development in any of the folder. ** Some Javascript features are supported both in the browser and node environment, and it is recommended to add these to both versions. @@ -205,7 +205,7 @@ describe("Name of the class|module", function(){ }); ``` -**Example**: Let write a test, to test if the values in a dataframe are off a certain length. Assuming the method to obtain length is values\_len\(\) +**Example**: Let write a test, to test if the values in a dataframe are off a certain length. Assuming the method to obtain length is values_len() ```javascript import { assert } from "chai" @@ -236,22 +236,22 @@ describe("DataFrame", function(){ To run the test for the module you created, -**1\)** Open the package.json +**1)** Open the package.json -**2\)** change the name of the test file to the file name you want. and don't forget the file is in the test folder +**2)** change the name of the test file to the file name you want. and don't forget the file is in the test folder ```python "scripts": { "test": "....... danfojs/tests/sub_directory_name/filename", ``` -**3\)** run the test, in the danfojs directory terminal +**3) **run the test, in the danfojs directory terminal ```python yarn test ``` -Learn more about mocha [here](https://mochajs.org/) +Learn more about mocha [here](https://mochajs.org) ## Contributing your changes to danfojs @@ -259,19 +259,19 @@ Learn more about mocha [here](https://mochajs.org/) Once you’ve made changes, you can see them by typing: -```text +``` git status ``` Next, you can track your changes using -```text +``` git add . ``` Next, you commit changes using: -```text +``` git commit -m "Enter any commit message here" ``` @@ -279,7 +279,7 @@ git commit -m "Enter any commit message here" When you want your changes to appear publicly on your GitHub page, you can push to your forked repo with: -```text +``` git push ``` @@ -300,31 +300,30 @@ This request then goes to the repository maintainers, and they will review the c In other to contribute to the code base of danfojs, there are some functions and properties provided to make implementation easy. -The main exposed modules are the **Frame** and **Series** module. This module inherits from the **Generic** module. +The main exposed modules are the **Frame** and **Series** module. This module inherits from the **Generic **module. The **Generic** module consists of the following methods and properties -* `.dtypes` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L213)\] is used to obtain the dtype for each column -* `.index` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L250)\] to obtain the index for Dataframe or Series -* `.__set_index(label)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L257)\] to set the index value -* `.__reset_index()` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L271)\] to reset the index in DataFrame and Series -* `.values` Obtain the values in DataFrame and Series per rows +* `.dtypes` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L213)] is used to obtain the dtype for each column +* `.index` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L250)] to obtain the index for Dataframe or Series +* `.__set_index(label) ` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L257)] to set the index value +* `.__reset_index()` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L271)] to reset the index in DataFrame and Series +* `.values ` Obtain the values in DataFrame and Series per rows * `.col_data` Obtain the values in DataFrame and Series per columns -* `.column_names` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] Obtain the list of column names -* `.__set_col_types` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L165)\] set the dtype for a column or infer the dtype from it +* `.column_names` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)] Obtain the list of column names +* `.__set_col_types` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L165)] set the dtype for a column or infer the dtype from it * `.columns` to access the column names directly * `row_data_tensor` store the tensor representation of the data in DataFrame and Series -The **Frame** module consists of the following methods and properties to aid implementation. +The **Frame **module consists of the following methods and properties to aid implementation. -* `__frame_is_compactible_for_operation` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1754)\]: check if all the values in a DataFrame are numerical. This helps to check if the numerical operation can be done using the dataframe. +* `__frame_is_compactible_for_operation` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1754)]: check if all the values in a DataFrame are numerical. This helps to check if the numerical operation can be done using the dataframe. * `.__get_ops_tensors(tensors, axis)` \[[source\]](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1767) : obtain tensors from dataframes along axis 0 or 1. -* `.__get_df_from_tensor(val, col_names)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1741)\]: Obtain dataframe from tensor. -* `.__get_tensor_and_idx(df, axis)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L928)\]: Obtain tensors, their index value and their axis from dataframe. +* `.__get_df_from_tensor(val, col_names) ` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1741)]: Obtain dataframe from tensor. +* `.__get_tensor_and_idx(df, axis)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L928)]: Obtain tensors, their index value and their axis from dataframe. -The **Series** module contains mostly Generic properties and less special internal properties. +The **Series **module contains mostly Generic properties and less special internal properties. -* `__check_series_op_compactibility(other)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L666)\] check if two series are compatible for numerical operation +* `__check_series_op_compactibility(other)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L666)] check if two series are compatible for numerical operation Lastly, the **Utils** module contains important utility functions. - diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index 66dd124..b9f9cca 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -7,11 +7,9 @@ description: >- # Titanic Survival Prediction using Danfo.js and Tensorflow.js -> The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. \([Wikipedia](https://en.wikipedia.org/wiki/Titanic)\) +> The RMS Titanic was a British passenger liner that sank in the North Atlantic Ocean in the early morning hours of 15 April 1912, after it collided with an iceberg during its maiden voyage from Southampton to New York City. There were an estimated 2,224 passengers and crew aboard the ship, and more than 1,500 died, making it one of the deadliest commercial peacetime maritime disasters in modern history. The RMS Titanic was the largest ship afloat at the time it entered service and was the second of three Olympic-class ocean liners operated by the White Star Line. The Titanic was built by the Harland and Wolff shipyard in Belfast. Thomas Andrews, her architect, died in the disaster. ([Wikipedia](https://en.wikipedia.org/wiki/Titanic)) - - -In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. +In this tutorial, I will show you how to load and process the famous Titanic dataset with danfo.js, and also how to create a deep learning model with Tensorflow.js to predict survival. This is a classic problem used to introduce new concepts in the field of Machine Learning. The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: @@ -19,9 +17,9 @@ The main objective of this tutorial is to show you how to use danfo.js to load a * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) -### Setting up your environment +## Setting up your environment -Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. +Danfo.js comes in two builds. There's the browser-based build, optimized for browser environments, and there is the node.js version optimized for Node.js environment. In this tutorial, you're going to use the Node.js build. If you do not have Node.js installed, following the guide [here](https://nodejs.org/en/). When you're done, create a new project by running the command below in a terminal opened in your preferred terminal. @@ -31,9 +29,9 @@ npm init Fill in the necessary details to create your app. Next, in your terminal, install danfo.js: -**Update \(14th Feb 2021\):** +**Update (14th Feb 2021):** -Danfo now ships with an exported version of tensorflow \(v2.8.5\). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. +Danfo now ships with an exported version of tensorflow (v2.8.5). This is exported under the namespace `tf`. This fixes the **double registration of runtime** issue many users have faced in the past. ```javascript npm install danfojs-node @@ -46,23 +44,23 @@ const dfd = require("danfojs-node") const tf = dfd.tf //Reference to the exported tensorflowjs library ``` -### Loading and processing your data +## Loading and processing your data -To load a CSV dataset, you can use the [read\_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. +To load a CSV dataset, you can use the [read_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. Below your import add the following lines of code: ```javascript async function load_process_data() { - + let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() - - + + } ``` -```text +``` Shape: (5,8) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -80,7 +78,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. +You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -110,7 +108,7 @@ df.ctypes.print() ╚═════════════════════════╧══════════════════════╝ ``` -From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. +From the data types table above, you'll notice that there are two strong columns. The first is the Name column which contains Names of each passenger. From the head of the dataset you printed above, you'll confirm that each name has a title. So you can extract these titles from the names and this can serve as a new feature. ```javascript //A feature engineering: Extract all titles from names columns @@ -120,11 +118,11 @@ let title = df['Name'].apply((x) => { return x.split(".")[0] }).values df.addColumn({ column: "Name", values: title, inplace: true }) ``` -In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. +In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. So what exactly is the function doing? Well, it is basically slicing each name and extracting the title. And finally, you are using the result to replace the original name column. When you're done, your output becomes: -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -138,7 +136,6 @@ So what exactly is the function doing? Well, it is basically slicing each name a ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 4 │ 0 │ 3 │ Mr │ male │ ... │ 35 │ 0 │ 0 │ 8.05 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` You notice we now have titles inplace of names. You can easily one hot encode this feature. You will do that below: @@ -158,8 +155,7 @@ df.head().print() In code cell above, you're[ label encoding](../api-reference/general-functions/danfo.labelencoder.md) the Sex and Name column. You loop over each column name, fit the encoder to the column, transform it and finally reassign it to the DataFrame. The output is shown below: -```text - +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -183,7 +179,7 @@ Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] ``` -Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. +Next, you'll scale the data using [MinMaxScaler](../api-reference/general-functions/danfo.minmaxscaler.md). It is important to scale your data before model training, as this will affect training. ```javascript // Standardize the data with MinMaxScaler @@ -193,9 +189,9 @@ Xtrain = scaler.transform(Xtrain) return [Xtrain.tensor, ytrain.tensor] ``` -In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. +In the code cell above, first, you create an instance from the MinMaxScaler class. Next, you fit the train data and finally, you transform. The output from the scaler is a DataFrame of same size with the values scaled. -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -211,7 +207,7 @@ In the code cell above, first, you create an instance from the MinMaxScaler clas ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The full code for the load\_process\_data function becomes: +The full code for the load_process_data function becomes: ```javascript const dfd = require("danfojs-node") @@ -250,11 +246,11 @@ async function load_process_data() { load_process_data() ``` -### Model Building With Tensorflow.js +## Model Building With Tensorflow.js -In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). +In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get\_model. This will construct and return a model when called. +Create a simple function called get_model. This will construct and return a model when called. ```javascript function get_model() { @@ -268,12 +264,11 @@ function get_model() { } ``` -In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. +In the code cell above, you created a neural network with 4 layers. Note the input shape, this should be the same as your column numbers. Also, note that you used a sigmoid in the output layer. This is because you're working on a binary classification problem. Next, you will create a function called _**train:**_ ```javascript - async function train() { const model = get_model() const data = await load_process_data() @@ -285,7 +280,7 @@ async function train() { loss: 'binaryCrossentropy', metrics: ['accuracy'], }); - + console.log("Training started....") await model.fit(Xtrain, ytrain,{ batchSize: 32, @@ -298,15 +293,15 @@ async function train() { } } }); - + } ``` -This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. +This function calls the _**load_process_data**_ function to retrieve training data as tensors and also calls the _**get_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. -Next, you call the **fit** function on the model, by passing the training data and labels \(tensors\), specify batch size, epoch size, validation split size, and also a callback function to track training progress. +Next, you call the **fit** function on the model, by passing the training data and labels (tensors), specify batch size, epoch size, validation split size, and also a callback function to track training progress. -The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: +The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript const dfd = require("danfojs-node") @@ -392,8 +387,7 @@ node app.js This runs the script, and displays training progress after each Epoch as shown below: -```text - +``` Epoch 12 / 15 eta=0.0 ===============================================================================================> 322ms 455us/step - acc=0.812 loss=0.433 val_acc=0.826 val_loss=0.371 @@ -419,13 +413,12 @@ EPOCH (15): Train Accuracy: 80.39, Val Accuracy: 83.15 ``` -After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. +After 15 epochs, you reach an accuracy of about 83%. This can definitely be improved, but for the sake of simplicity, we'll stop here. -In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. +In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. -As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. +As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. Go danfo! 😎 - diff --git a/examples/using-danfojs-in-react.md b/examples/using-danfojs-in-react.md index 118de23..b11ca0c 100644 --- a/examples/using-danfojs-in-react.md +++ b/examples/using-danfojs-in-react.md @@ -1,6 +1,6 @@ # Using Danfojs in React -**TL:DR** See Example react application using danfojs [here](https://github.com/opensource9ja/Data-aRT) +**TL:DR **See Example react application using danfojs [here](https://github.com/opensource9ja/Data-aRT) Danfojs works for both browser and NodeJs environment, and as such is available to frontend frameworks like React and Vue. @@ -67,4 +67,3 @@ import { DataFrame } from "danfojs/src/index"; ``` Following these steps, you can use danfojs in any client-side library. - diff --git a/getting-started.md b/getting-started.md index a88f855..5e92af5 100644 --- a/getting-started.md +++ b/getting-started.md @@ -8,27 +8,43 @@ description: >- ## Installation -There are two ways to get danfo.js. We built an optimized and fast version for node.js and its available under the [danfojs-node](https://www.npmjs.com/package/danfojs-node) namespace. To install it via npm, you can do the following: +There are three ways to install and use Danfo.js in your application -```text +For Nodejs applications, you can install the [danfojs-node](https://www.npmjs.com/package/danfojs-node) version via package managers like yarn and npm: + +``` npm install danfojs-node + +or + +yarn add danfojs-node ``` -You can also install and use it in the browsers by using the CDN below: +For client-side applications built with frameworks like React, Vue, Next.js, etc, you can install the [danfojs](https://www.npmjs.com/package/danfojs) version: + +``` +npm install danfojs + +or + +yarn add danfojs +``` + +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment , see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) {% endhint %} ## 10 minutes to danfo.js -This is a short introduction to danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) -We will show you how to use danfo.js in both browser environment and Node.js environment. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM works the same way in both environments. +We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. {% tabs %} {% tab title="Node" %} @@ -45,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -64,9 +80,9 @@ const dfd = require("danfojs-node") {% endtab %} {% endtabs %} -### Object creation +### Creating a DataFrame/Series -Creating a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting danfo.js create a default integer index: +You can create a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) by passing a list of values, letting Danfo.js create a default integer index: {% tabs %} {% tab title="Node" %} @@ -103,7 +119,7 @@ s.print() {% endtab %} {% endtabs %} -```text +``` //output ╔═══╤══════════════════════╗ ║ │ 0 ║ @@ -114,7 +130,7 @@ s.print() ╟───┼──────────────────────╢ ║ 2 │ 5 ║ ╟───┼──────────────────────╢ -║ 3 │ NaN ║ +║ 3 │ undefined ║ ╟───┼──────────────────────╢ ║ 4 │ 6 ║ ╟───┼──────────────────────╢ @@ -167,18 +183,16 @@ s.print() {% endtab %} {% endtabs %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 1 │ 34 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╚═══╧════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing a JSON object: @@ -279,7 +293,7 @@ df.ctypes.print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -363,7 +377,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` //output in console ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D │ E ║ @@ -384,21 +398,19 @@ The columns of the resulting [`DataFrame`](https://pandas.pydata.org/pandas-docs df.ctypes.print() ``` -```text +``` //output -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ string ║ -╟───┼──────────────────────╢ -║ B │ string ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ float32 ║ -╟───┼──────────────────────╢ -║ E │ string ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ string ║ +╟───┼─────────╢ +║ B │ string ║ +╟───┼─────────╢ +║ C │ int32 ║ +╟───┼─────────╢ +║ D │ float32 ║ +╟───┼─────────╢ +║ E │ string ║ +╚═══╧═════════╝ ``` Creating a [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) by passing an array of arrays. Index and column labels are automatically generated for you. @@ -450,7 +462,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` //output in console ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -470,12 +482,12 @@ df.print() Here is how to view the top and bottom rows of the frame above: -```text +``` df.head(2).print() df.tail(2).print() ``` -```text +``` //output from head ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ @@ -560,7 +572,7 @@ console.log(df.columns); {% endtab %} {% endtabs %} -```text +``` //output [ 0, 1, 2, 3 ] [ 'A', 'B', 'C', 'D', 'E' ] @@ -624,7 +636,7 @@ df.tensor.print() {% endtab %} {% endtabs %} -```text +``` //output Tensor { @@ -702,25 +714,29 @@ df.describe().print() {% endtab %} {% endtabs %} -```text -//output in console - -╔════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 4 │ 4 │ 4 │ 4 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 0.533175 │ 0.484235 │ -0.474898 │ 1.5816 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 0.107543 │ 2.569317 │ 3.437147 │ 2.200545 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ -╟────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 0.4902 │ -0.52863 │ -1.50745 │ 1.6492 ║ -╚════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` +//output in console -Sorting by values \(Defaults to ascending\): +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 4 │ 4 │ 4 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 0.533175 │ 0.4842349999999… │ -0.474897500000… │ 1.5816 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 0.1075428712963… │ 2.5693167249095… │ 3.4371471031498… │ 2.2005448052698… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0.4612 │ -1.28863 │ -3.39059 │ -1.1352 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 0.4901999999999… │ -0.528629999999… │ -1.50745 │ 1.6492 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 0.6911 │ 4.28283 │ 4.5059 │ 4.1632 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 0.0115654691666… │ 6.6013884328999… │ 11.813980208691… │ 4.84239744 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Sorting by values (Defaults to ascending): {% tabs %} {% tab title="Node" %} @@ -771,16 +787,18 @@ df.print() {% endtab %} {% endtabs %} -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ -4 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47.3 │ 5 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Selection @@ -840,7 +858,7 @@ df['A'].print() {% endtab %} {% endtabs %} -```text +``` //output ╔═══╤══════════════════════╗ ║ │ A ║ @@ -873,7 +891,7 @@ let sub_df = df.loc({rows: ["a", "c"]}) sub_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -914,7 +932,7 @@ let sub_df = df.loc({ rows: [0,1], columns: ["Name", "Price"] }) sub_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -939,7 +957,7 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Showing label slicing, both endpoints are _included_: +Showing label slicing: ```javascript const dfd = require("danfojs-node") @@ -955,7 +973,7 @@ let sub_df = df.loc({ rows: ["0:2"], columns: ["Name", "Price"] }) sub_df.print() ``` -```text +``` //before slicing ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ @@ -970,17 +988,15 @@ sub_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ //after slicing - Shape: (3,2) + -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` #### Selection by position @@ -1000,7 +1016,7 @@ let sub_df = df.iloc({rows: [1,3]}) sub_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1025,16 +1041,14 @@ let sub_df = df.iloc({rows: ["1:3"]}) sub_df.print() ``` -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` By lists of integer position locations: @@ -1052,7 +1066,7 @@ let sub_df = df.iloc({rows: [1,3], columns: [0,2]}) sub_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Name │ Price ║ ╟───┼───────────────────┼───────────────────╢ @@ -1077,14 +1091,12 @@ let sub_df = df.iloc({rows: ["2:3"], columns: [":"]}) sub_df.print() ``` -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` For slicing columns explicitly: @@ -1102,18 +1114,63 @@ let sub_df = df.iloc({rows: [":"], columns: ["1:2"]}) sub_df.print() ``` -```text -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╗ +║ │ Count ║ +╟────────────┼───────────────────╢ +║ 0 │ 21 ║ +╟────────────┼───────────────────╢ +║ 1 │ 5 ║ +╟────────────┼───────────────────╢ +║ 2 │ 30 ║ +╟────────────┼───────────────────╢ +║ 3 │ 10 ║ +╚════════════╧═══════════════════╝ +``` + +#### Selection with Boolean Mask + +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. + +```javascript +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) + +let sub_df = df.iloc({ rows: df["Count"].gt(10) }) +sub_df.print() +``` + +``` +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. + +```javascript +let sub_df = df.iloc({ + rows: df["Count"].gt(10).and(df["Name"].eq("Apples")), + columns: [0] +}) +sub_df.print() + +//output +╔════════════╤═══════════════════╗ +║ │ Name ║ +╟────────────┼───────────────────╢ +║ 0 │ Apples ║ +╚════════════╧═══════════════════╝ ``` #### Boolean Querying/Filtering @@ -1170,7 +1227,7 @@ query_df.print() //after query {% endtab %} {% endtabs %} -```text +``` //before query ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -1194,7 +1251,7 @@ query_df.print() //after query ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Selecting values from a DataFrame works on string columns: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, @@ -1202,34 +1259,36 @@ let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, {"C": [20, 20, 30, 40]}] let df = new dfd.DataFrame(data) -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +let query_df = df.query({ condition: df["B"].gt(5) }) query_df.print() //after query ``` -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` -//after query +Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let query_df = df.query({ + condition: + df["B"].gt(5).and(df["A"].lt(30)) +}) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### Adding a new column @@ -1249,7 +1308,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace +df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace df.print() ``` @@ -1281,7 +1340,7 @@ df.print() let new_col = [1, 2, 3, 4] df.addColumn({ "column": "D", "values": new_col, inplace: true }); //happens inplace - + df.print() @@ -1292,7 +1351,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` //before adding column ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -1309,22 +1368,22 @@ df.print() //after adding column Shape: (4,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 │ 25 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 │ 35 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 │ 45 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 │ 55 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ### Missing data -danfo primarily uses the value **NaN** to represent missing data. It converts **undefined** type to **NaN** by default when creating DataFrames/Series with missing values. + **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1333,13 +1392,13 @@ To drop any rows that have missing data: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, 20, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} @@ -1378,29 +1437,29 @@ df_drop.print() {% endtab %} {% endtabs %} -```text +``` //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping - Shape: (1,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` To drop any columns with have missing data, set the axis to 1: @@ -1408,44 +1467,45 @@ To drop any columns with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 1}) +let df_drop = df.dropna(1) df_drop.print() ``` -```text +``` //Before dropping -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 34 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ //after droppping -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ + ``` Filling missing data: @@ -1455,18 +1515,18 @@ const dfd = require("danfojs-node") let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] - } + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] + } let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1485,18 +1545,20 @@ Filling missing values in specific columns with specific values: ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", NaN], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1523,7 +1585,7 @@ let df = new dfd.DataFrame(data) df.isna().print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1554,7 +1616,7 @@ data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.print() df.mean().print() //defaults to column axis ``` @@ -1592,7 +1654,7 @@ df.mean().print() //defaults to column axis {% endtab %} {% endtabs %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1608,11 +1670,11 @@ df.mean().print() //defaults to column axis ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ -║ 0 │ 4 ║ +║ A │ 4 ║ ╟───┼──────────────────────╢ -║ 1 │ 38.5 ║ +║ B │ 38.5 ║ ╟───┼──────────────────────╢ -║ 2 │ 31.75 ║ +║ C │ 31.75 ║ ╚═══╧══════════════════════╝ ``` @@ -1630,7 +1692,7 @@ df.print() df.mean(0).print() //row axis=0, column=1 ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -1666,12 +1728,12 @@ let data = { "Col1": [1, 4, 5, 1], "Col2": [3, 2, 0, 4] } let df = new dfd.DataFrame(data) let sf = new dfd.Series([4, 5]) -let df_new = df.sub(sf, axis = 1) +let df_new = df.sub(sf, { axis: 1 }) df_new.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ Col1 │ Col2 ║ ╟───┼───────────────────┼───────────────────╢ @@ -1687,7 +1749,7 @@ df_new.print() #### Apply -Applying JavaScript functions to the data: +Applying functions to the data along specified axis. If axis = 1 (default), then the specified function (`callable)` will be called with each column data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1696,15 +1758,15 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` -```text +``` //before applying ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -1721,22 +1783,18 @@ df_new.print() //after applying -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` -Applying Tensorflow functions to the data: +Applying Element wise operations to the data: -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1745,17 +1803,15 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -function log_sig(x) { - return x.logSigmoid() +function sum_vals(x) { + return x + 10 } -let df_new = df.apply({axis: 0, callable: log_sig }) +let df_new = df.apply_map(sum_vals) df_new.print() ``` -```text +``` //before applying ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -1770,24 +1826,24 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after applying + //after apply_map -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 12 │ 13 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 14 │ 15 │ 16 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 │ 50 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 49 │ 99 │ 88 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` #### String Methods -Series is equipped with a set of string processing methods in the **str** attribute that make it easy to operate on each element of the array, as in the code snippet below. Note that pattern-matching in **str** generally uses JavaScript [regular expressions](https://docs.python.org/3/library/re.html) by default \(and in some cases always uses them\). +Series is equipped with a set of string processing methods in the **str** attribute that make it easy to operate on each element of the array, as in the code snippet below. Note that pattern-matching in **str** generally uses JavaScript [regular expressions](https://docs.python.org/3/library/re.html) by default (and in some cases always uses them). ```javascript const dfd = require("danfojs-node") @@ -1797,7 +1853,7 @@ lower_s = s.str.toLowerCase() lower_s.print() ``` -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -1850,7 +1906,7 @@ let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) //along column axis com_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -1864,7 +1920,7 @@ com_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Concatenate along row axis \(0\). +Concatenate along row axis (0). ```javascript const dfd = require("danfojs-node") @@ -1887,7 +1943,7 @@ let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) //along row axis com_df.print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -1934,7 +1990,7 @@ let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) merge_df.print() ``` -```text +``` //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -2012,7 +2068,7 @@ grp.get_groups(["foo"]).print() grp.get_groups(["bar"]).print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -2061,7 +2117,7 @@ let grp = df.groupby(["A"]) grp.col(["C"]).sum().print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╗ ║ │ A │ C_sum ║ ╟───┼───────────────────┼───────────────────╢ @@ -2091,7 +2147,7 @@ let grp = df.groupby(["A","B"]) grp.col(["C"]).sum().print() ``` -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C_sum ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -2124,7 +2180,7 @@ sf.print() sf.dt.month_name().print() ``` -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -2159,7 +2215,7 @@ sf.print() sf.dt.weekdays().print() ``` -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -2232,7 +2288,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. ``` -![](.gitbook/assets/newplot-29-%20%282%29.png) +![](<.gitbook/assets/newplot-29- (2).png>) On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html#pandas.DataFrame.plot)method exposes various [plot types](api-reference/plotting/). And by default, all columns are plotted unless specified otherwise. @@ -2263,38 +2319,45 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe ``` -![](.gitbook/assets/newplot-2-%20%281%29%20%281%29.png) +![](<.gitbook/assets/newplot-2- (1) (1).png>) ### Getting data in/out #### CSV -[Writing to a csv file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") - let data = { - "Abs": [20.2, 30, 47.3], - "Count": [34, 4, 5], - "country code": ["NG", "FR", "GH"] - } + "Abs": [20.2, 30, 47.3], + "Count": [34, 4, 5], + "country code": ["NG", "FR", "GH"] +} let df = new dfd.DataFrame(data) -df.to_csv().then((csv) => { - console.log(csv); +const csv = df.to_csv() +console.log(csv); +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH + + +df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs + + +df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version -}).catch((err) => { - console.log(err); -}) ``` -```text +``` Abs,Count,country code 20.2,34,NG 30,4,FR @@ -2303,7 +2366,7 @@ Abs,Count,country code [Reading from a CSV file.](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-read-csv-table) -The **read\_csv** method can read CSV file from local disk, or over the internet. If the file is to be read from a local disk in Node environment, you have to prefix the full path name with a "**file://**" prefix. For instance, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: +The **read_csv** method can read CSV file from local disk, or over the internet. If the file is to be read from a local disk in Node environment, you have to prefix the full path name with a "**file://**" prefix. For instance, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: {% tabs %} {% tab title="JavaScript" %} @@ -2372,18 +2435,23 @@ let data = { let df = new dfd.DataFrame(data) -df.to_json().then((json) => { - console.log(json); +const json = df.to_json() +console.log(json); +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] -}).catch((err) => { - console.log(err); -}) -``` +const json = df.to_json({format: "row"}) +console.log(json); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} -```text -[{"Abs":20.2,"Count":34,"country code":"NG"}, -{"Abs":30,"Count":4,"country code":"FR"}, -{"Abs":47.3,"Count":5,"country code":"GH"}] ``` - diff --git a/release-notes.md b/release-notes.md index fc8d8e9..34a3249 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,12 +1,12 @@ # Release Notes -### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.2\), Browser \(0.3.2\) +### \[LATEST] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.3.2), Browser (0.3.2) **Date:** 2nd Oct 2021 Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. -### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.3.1\), Browser \(0.3.1\) +### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.3.1), Browser (0.3.1) **Date:** 1st Oct 2021 @@ -21,12 +21,18 @@ Minor patch update for column name display after aggregation functions like sum, * Add loc indexing support for Series * Add configuration support for formating DataFrame display in the console * New DataFrame `applyMap` function for element-wise apply function -* `and` and `or` logical comparison support. E.g `df.loc({` `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) })` -* `read_csv` now uses [Papaparse](https://www.papaparse.com/) and supports config values for headers, separator, etc. +* `and` and `or` logical comparison support. E.g \ + `df.loc({`\ + `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ + `})` +* `read_csv` now uses [Papaparse](https://www.papaparse.com) and supports config values for headers, separator, etc. * `to_csv` , `to_json` and `to_excel` functions now support saving to local disk in Node and downloadable in the browser. Also, supports config parameters for output. * `read_json` now supports config values for headers, authentication, separator, etc. * `read_excel` now uses [XLSX](https://www.npmjs.com/package/xlsx) parser, hence supports all XLSX config options. -* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g `df.query({` `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) })` +* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g \ + `df.query({`\ + `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) `\ + `})` **Bug Fixes** @@ -39,22 +45,22 @@ Minor patch update for column name display after aggregation functions like sum, Contributors [@risenW](https://github.com/risenW) -### \[LATEST\] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.2.7\), Browser \(0.2.6\) +### \[LATEST] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.2.7), Browser (0.2.6) **Date:** 30th May 2021 -\[Bug Fixes\]: [\#206](https://github.com/opensource9ja/danfojs/issues/206) [\#203](https://github.com/opensource9ja/danfojs/issues/203) [\#200](https://github.com/opensource9ja/danfojs/issues/200) [\#198](https://github.com/opensource9ja/danfojs/issues/198) [\#198](https://github.com/opensource9ja/danfojs/issues/198) [\#188](https://github.com/opensource9ja/danfojs/issues/188) [\#181](https://github.com/opensource9ja/danfojs/issues/181) [\#175](https://github.com/opensource9ja/danfojs/issues/175) [\#183](https://github.com/opensource9ja/danfojs/issues/183) [\#168](https://github.com/opensource9ja/danfojs/issues/168) -\[Patches\] [\#191](https://github.com/opensource9ja/danfojs/issues/191) [\#161](https://github.com/opensource9ja/danfojs/issues/161) [\#206](https://github.com/opensource9ja/danfojs/issues/206) +\[Bug Fixes]: [#206](https://github.com/opensource9ja/danfojs/issues/206) [#203](https://github.com/opensource9ja/danfojs/issues/203) [#200](https://github.com/opensource9ja/danfojs/issues/200) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#188](https://github.com/opensource9ja/danfojs/issues/188) [#181](https://github.com/opensource9ja/danfojs/issues/181) [#175](https://github.com/opensource9ja/danfojs/issues/175) [#183](https://github.com/opensource9ja/danfojs/issues/183) [#168](https://github.com/opensource9ja/danfojs/issues/168)\ +\[Patches] [#191](https://github.com/opensource9ja/danfojs/issues/191) [#161](https://github.com/opensource9ja/danfojs/issues/161) [#206](https://github.com/opensource9ja/danfojs/issues/206) Contributors [@risenW](https://github.com/risenW) [@steveoni](https://github.com/steveoni) [@jpjagt](https://github.com/jpjagt) [@sponsfreixes](https://github.com/sponsfreixes) [@bherbruck](https://github.com/bherbruck) [@woosuk288](https://github.com/woosuk288) and [@adithyaakrishna](https://github.com/adithyaakrishna) -### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node \(v0.2.6\), Browser \(0.2.5\) +### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.2.6), Browser (0.2.5) **Date:** 29th March 2021 -* \[Bug Fixes\]: [\#150](https://github.com/opensource9ja/danfojs/pull/150) [\#152 ](https://github.com/opensource9ja/danfojs/pull/152) -* \[Patches\] [\#159](https://github.com/opensource9ja/danfojs/pull/159) , [\#158 ](https://github.com/opensource9ja/danfojs/pull/158) -* \[Feature\] [\#154](https://github.com/opensource9ja/danfojs/pull/154) Perform groupby operation on grouped columns directly: +* \[Bug Fixes]: [#150](https://github.com/opensource9ja/danfojs/pull/150) [#152 ](https://github.com/opensource9ja/danfojs/pull/152) +* \[Patches] [#159](https://github.com/opensource9ja/danfojs/pull/159) , [#158 ](https://github.com/opensource9ja/danfojs/pull/158) +* \[Feature] [#154](https://github.com/opensource9ja/danfojs/pull/154) Perform groupby operation on grouped columns directly: ```javascript group = df.groupby(['A"]) @@ -67,14 +73,14 @@ groupby.col(["C"]).apply((x) => x.min()) **Contributors**: @steveoni @PrawiraGenestonlia @woosuk288 @risenW -### Release Node \(v0.2.5\), Browser \(0.2.4\) +### Release Node (v0.2.5), Browser (0.2.4) **Date:** 6th March 2021 We added/updated the following features: * Fix error thrown when danfojs CDN is placed in an HTML header -* Smaller bundle size for browser: From ~1.7mb to about ~550kb +* Smaller bundle size for browser: From \~1.7mb to about \~550kb * Stopped bundling Danfojs with Plotly. This means that as of v0.2.3, we no longer ship with Plotly distribution due to the huge size. Plotly plots are still supported, but in order to make them, you have to explicitly add the Plotly CDN or package. A simple example: @@ -120,16 +126,16 @@ A simple example: ``` -### Release [ \(v0.2.2\)](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.2) +### Release [ (v0.2.2)](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.2) **Date:** 14th February 2021 We added/updated the following features: * Fix babel runtime issue in node version -* Smaller size in browser version in this version. From ~8mb to about ~5mb +* Smaller size in browser version in this version. From \~8mb to about \~5mb * Fix browser tag issue and returns back to specific versioning instead of @latest -* Danfojs now ships with an exported version of tensorflowjs-node \(2.8.5\). This fixes the double dependency issue when building ML models, as you no longer need to install/import tensorflowjs separately. +* Danfojs now ships with an exported version of tensorflowjs-node (2.8.5). This fixes the double dependency issue when building ML models, as you no longer need to install/import tensorflowjs separately. To use tensoflowjs-node, you can reference it from danfo as shown below: @@ -143,24 +149,24 @@ model.add(tf.layers.dense({ units: 64, activation: 'relu' })); model.summary(); ``` -### Release \(v0.1.5\) +### Release (v0.1.5) **Date:** 25th September 2020 We added/updated the following features: -* [Read JSON](api-reference/input-output/danfo.read_json.md) files from local and remote URL into DataFrame \(New feature\) -* [Read Excel](api-reference/input-output/danfo.read_excel.md) files from local or remote URL into DataFrame \(New feature\) -* Fix string comparison bug in [query](api-reference/dataframe/danfo.dataframe.query.md) function \(Fix\) -* Add append function for [DataFrame](api-reference/dataframe/dataframe.append.md) and [Series](api-reference/series/series.append.md) \(New feature\) -* Fix null value bug when creating DataFrame from JSON files \(Fix\) +* [Read JSON](api-reference/input-output/danfo.read_json.md) files from local and remote URL into DataFrame (New feature) +* [Read Excel](api-reference/input-output/danfo.read_excel.md) files from local or remote URL into DataFrame (New feature) +* Fix string comparison bug in [query](api-reference/dataframe/danfo.dataframe.query.md) function (Fix) +* Add append function for [DataFrame](api-reference/dataframe/dataframe.append.md) and [Series](api-reference/series/series.append.md) (New feature) +* Fix null value bug when creating DataFrame from JSON files (Fix) * Add relative import for reading files into DataFrame -* Add [sort\_index](api-reference/dataframe/dataframe.sort_index.md) function to DataFrame and Series \(New feature\) -* Minor patch and overall optimizations \(Fix\) +* Add [sort_index](api-reference/dataframe/dataframe.sort_index.md) function to DataFrame and Series (New feature) +* Minor patch and overall optimizations (Fix) **Contributors**: [Rising Odegua](https://github.com/risenW), [Stephen Oni](https://github.com/steveoni), [Jhenner Tigreros](https://github.com/JhennerTigreros), [Aditya Zope](https://github.com/adzo261) -### Release \(v0.1.0-beta\) +### Release (v0.1.0-beta) **Date:** 15th August 2020 @@ -176,5 +182,3 @@ This is a minor release for browser-based environments. We added/updated the fol **Contributors**: Rising Odegua, Stephen Oni - - From be4ec5dc028116e9a6066a412bb4c23875beafda Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 18:55:40 +0000 Subject: [PATCH 144/202] GitBook: [#199] Update docs --- .../dataframe/danfo.dataframe.abs.md | 8 +- .../dataframe/danfo.dataframe.addcolumn.md | 4 +- .../dataframe/danfo.dataframe.describe.md | 34 ++--- .../dataframe/danfo.dataframe.groupby.md | 138 ++++++++++++++---- .../dataframe/danfo.dataframe.query.md | 51 +++++++ .../dataframe/danfo.dataframe.sum.md | 50 +++---- 6 files changed, 208 insertions(+), 77 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.abs.md b/api-reference/dataframe/danfo.dataframe.abs.md index 303a649..83c6cd3 100644 --- a/api-reference/dataframe/danfo.dataframe.abs.md +++ b/api-reference/dataframe/danfo.dataframe.abs.md @@ -4,11 +4,15 @@ description: Return a DataFrame with the absolute numeric value of each element. # DataFrame.abs -danfo.DataFrame.**abs**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L973)] +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | **Returns:** -** **return** DataFrame** +** **return** Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index 2ba2b93..ef0ecc9 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -4,11 +4,11 @@ description: Add new column to a DataFrame # DataFrame.addColumn -danfo.DataFrame.**addColumn**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] +danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] | Parameters | Type | Description | Default | | ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| kwargs | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | +| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | **Returns:** diff --git a/api-reference/dataframe/danfo.dataframe.describe.md b/api-reference/dataframe/danfo.dataframe.describe.md index 525c51f..4dac614 100644 --- a/api-reference/dataframe/danfo.dataframe.describe.md +++ b/api-reference/dataframe/danfo.dataframe.describe.md @@ -37,23 +37,23 @@ df.describe().print() {% tabs %} {% tab title="Output" %} ``` -╔══════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 3 │ 3 │ 3 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 120.666664 │ 62 │ 123.333336 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 207.271159 │ 102.19589 │ 204.961785 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0 │ 2 │ 4 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 2 │ 4 │ 6 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 360 │ 180 │ 360 ║ -╟──────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 42961.333333 │ 10444 │ 42009.333333 ║ -╚══════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 3 │ 3 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0 │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 2 │ 4 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 360 │ 180 │ 360 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.groupby.md b/api-reference/dataframe/danfo.dataframe.groupby.md index 0b9dad9..a31f095 100644 --- a/api-reference/dataframe/danfo.dataframe.groupby.md +++ b/api-reference/dataframe/danfo.dataframe.groupby.md @@ -16,18 +16,52 @@ danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja ## **Examples** -## **Select a single column from a DataFrame** +## **Groupby a single column from a DataFrame** {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] let cols = ["A", "B", "C"] -let df = new DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]); -group_df.col_dict +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]) +console.log(group_df) + +//GroupBy Object +GroupBy { + key_col: [ 'A' ], + col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, + data: [ + [ 'Pear', 2, 3 ], + [ 'Pear', 5, 6 ], + [ 'Apple', 30, 40 ], + [ 'Apple', 89, 78 ] + ], + column_name: [ 'A', 'B', 'C' ], + data_tensors: { + Pear: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + '$index': [Array], + '$dtypes': [Array], + '$columns': [Array] + }, + Apple: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + ... + '$columns': [Array] + } + }, + col_dtype: [ 'string' ] +} ``` {% endtab %} @@ -37,34 +71,78 @@ group_df.col_dict {% endtab %} {% endtabs %} +A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: + +1. [count](danfo.dataframe.count.md) +2. [sum](danfo.dataframe.sum.md) +3. [std](danfo.dataframe.std.md) +4. [var](danfo.dataframe.var.md) +5. [mean](danfo.dataframe.mean.md) +6. [cumsum](danfo.dataframe.cumsum.md) +7. [cummax](danfo.dataframe.cummax.md) +8. [cumprod](danfo.dataframe.cumprod.md) +9. [cummin](danfo.dataframe.cummin.md) +10. [max](danfo.dataframe.max.md) +11. [min](danfo.dataframe.min.md) + +## Example of Groupby and apply a sum function + {% tabs %} -{% tab title="Output" %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]).sum() + +group_df.print() + +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B_sum │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 119 │ 118 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +## **Groupby a two columns from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A", "B"]).sum() + +group_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} ``` -╔═══╤══════════════════════╗ -║ │ Name ║ -╟───┼──────────────────────╢ -║ 0 │ Apples ║ -╟───┼──────────────────────╢ -║ 1 │ Mango ║ -╟───┼──────────────────────╢ -║ 2 │ Banana ║ -╟───┼──────────────────────╢ -║ 3 │ NaN ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ Name ║ -╟───┼──────────────────────╢ -║ 0 │ Apples ║ -╟───┼──────────────────────╢ -║ 1 │ Mango ║ -╟───┼──────────────────────╢ -║ 2 │ Banana ║ -╟───┼──────────────────────╢ -║ 3 │ NaN ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} -To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 2 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Apple │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference/dataframe/danfo.dataframe.query.md b/api-reference/dataframe/danfo.dataframe.query.md index 141b642..847fbe0 100644 --- a/api-reference/dataframe/danfo.dataframe.query.md +++ b/api-reference/dataframe/danfo.dataframe.query.md @@ -18,6 +18,57 @@ danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/da ## **Examples** +## **Query a DataFrame using boolean mask** + +{% hint style="info" %} +Querying by a boolean condition is supported from v0.3.0 and above. +{% endhint %} + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5) }) +query_df.print() //after query +``` + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + ## **Query a DataFrame using logical operators** To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. diff --git a/api-reference/dataframe/danfo.dataframe.sum.md b/api-reference/dataframe/danfo.dataframe.sum.md index 6a8125c..515788b 100644 --- a/api-reference/dataframe/danfo.dataframe.sum.md +++ b/api-reference/dataframe/danfo.dataframe.sum.md @@ -4,15 +4,15 @@ description: Return the sum of the values for the requested axis. # DataFrame.sum -danfo.DataFrame.**sum**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------- | --------- | -| kwargs | Object | {**axis**: 0 for row and 1 for column} | {axis: 1} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | **Returns:** -** **return** DataFrame** +** **return** Series** ## **Examples** @@ -43,27 +43,25 @@ df_sum.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ sum ║ -╟───┼──────────────────────╢ -║ A │ 37.2 ║ -╟───┼──────────────────────╢ -║ B │ 41 ║ -╟───┼──────────────────────╢ -║ C │ -10 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════════════════════╗ +║ A │ 37.199999999999996 ║ +╟───┼────────────────────╢ +║ B │ 41 ║ +╟───┼────────────────────╢ +║ C │ -10 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} From 2ef665f55512b9926eb6f58d54ad0fd3ebe98507 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 19:45:36 +0000 Subject: [PATCH 145/202] GitBook: [#200] Update doc --- SUMMARY.md | 2 +- .../dataframe/danfo.dataframe.apply.md | 159 ++++-------------- .../dataframe/danfo.dataframe.column.md | 51 +++--- .../dataframe/danfo.dataframe.dropna.md | 13 +- api-reference/dataframe/danfo.dataframe.eq.md | 16 +- .../dataframe/danfo.dataframe.fillna.md | 41 +++-- api-reference/dataframe/danfo.dataframe.ge.md | 16 +- api-reference/dataframe/danfo.dataframe.gt.md | 12 +- api-reference/dataframe/danfo.dataframe.it.md | 22 +-- api-reference/dataframe/danfo.dataframe.le.md | 16 +- .../dataframe/danfo.dataframe.nanindex.md | 60 ------- api-reference/dataframe/danfo.dataframe.ne.md | 14 +- .../dataframe/danfo.dataframe.replace.md | 37 ++-- .../dataframe/dataframe.apply_map.md | 68 ++++++++ 14 files changed, 226 insertions(+), 301 deletions(-) delete mode 100644 api-reference/dataframe/danfo.dataframe.nanindex.md create mode 100644 api-reference/dataframe/dataframe.apply_map.md diff --git a/SUMMARY.md b/SUMMARY.md index fd962ba..44764c2 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -168,9 +168,9 @@ * [DataFrame.column](api-reference/dataframe/danfo.dataframe.column.md) * [DataFrame.fillna](api-reference/dataframe/danfo.dataframe.fillna.md) * [DataFrame.isna](api-reference/dataframe/danfo.dataframe.isna.md) - * [DataFrame.nanindex](api-reference/dataframe/danfo.dataframe.nanindex.md) * [DataFrame.dropna](api-reference/dataframe/danfo.dataframe.dropna.md) * [DataFrame.apply](api-reference/dataframe/danfo.dataframe.apply.md) + * [DataFrame.apply_map](api-reference/dataframe/dataframe.apply_map.md) * [DataFrame.It](api-reference/dataframe/danfo.dataframe.it.md) * [DataFrame.gt](api-reference/dataframe/danfo.dataframe.gt.md) * [DataFrame.le](api-reference/dataframe/danfo.dataframe.le.md) diff --git a/api-reference/dataframe/danfo.dataframe.apply.md b/api-reference/dataframe/danfo.dataframe.apply.md index 1d664dd..01fab60 100644 --- a/api-reference/dataframe/danfo.dataframe.apply.md +++ b/api-reference/dataframe/danfo.dataframe.apply.md @@ -1,17 +1,15 @@ --- -description: >- - Apply a function to each element or along a specified axis of a DataFrame. - Supports JavaScipt functions when axis is not specified, and accepts - Tensorflow functions when axis is specified. +description: Apply a function to each element or along a specified axis of a DataFrame. --- # DataFrame.apply -danfo.DataFrame.**apply**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -| kwargs | Object |

{callable: Function to call on each element,

axis: undefined: if undefined, then any JavaScript function

is accepted and will be applied element-wise.

0: Apply along row/index axis

1: Apply across columns axis

}

| undefined | +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | **Returns:** @@ -19,9 +17,11 @@ danfo.DataFrame.**apply**(kwargs) \[[source](https://github.com/opensource9ja/da ## **Examples** -### Apply a JavaScript function to all elements in DataFrame +### Apply a function along default axis 1 (columns) -The **apply** function calls a JavaScript function on every element of the DataFrame when the axis is not specified. +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. +{% endhint %} {% tabs %} {% tab title="Node" %} @@ -32,11 +32,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x + 20 +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 1 }) df_new.print() ``` {% endtab %} @@ -50,68 +50,18 @@ df_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 22 │ 23 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 24 │ 25 │ 26 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 40 │ 50 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 59 │ 109 │ 98 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [{ short_name: ["NG", "GH", "EGY", "SA"] }, - { long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] }] -let df = new dfd.DataFrame(data) - -function lower(x) { - return `${x}`.toLowerCase() -} - -let df_new = df.apply({ callable: lower }) -df_new.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ short_name │ long_name ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ ng │ nigeria ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ gh │ ghana ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ egy │ eqypt ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ sa │ south africa ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Apply [Tensorflow](https://js.tensorflow.org/api/latest/) function element-wise - -You can call any compatible [Tensorflow](https://js.tensorflow.org/api/latest/) function on a DataFrame across a specified axis. For functions that operate _**element-wise**_ and returns the same shape as the original DataFrame, you must specify an axis of 0. +### Apply a function along axis 0 (row) {% tabs %} {% tab title="Node" %} @@ -122,11 +72,11 @@ let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -function sum_vals(x) { - return x.logSigmoid() +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); } -let df_new = df.apply({axis: 0, callable: sum_vals }) +let df_new = df.apply(sum_vals, { axis: 0 }) df_new.print() ``` @@ -141,59 +91,16 @@ df_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.3132616579... │ -0.1269280463... │ -0.0485873296... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.0181499607... │ -0.0067153489... │ -0.0024756519... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -2.0611536921... │ -9.3576229122... │ -4.2483541311... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -1.1548223864... │ -2.2273639090... │ -1.3336148713... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Apply [Tensorflow](https://js.tensorflow.org/api/latest/) function along column axis - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(x) { - return x.sum() -} - -let df_new = df.apply({axis: 1, callable: sum_vals }) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} +╔═══╤═════╗ +║ 0 │ 6 ║ +╟───┼─────╢ +║ 1 │ 15 ║ +╟───┼─────╢ +║ 2 │ 90 ║ +╟───┼─────╢ +║ 3 │ 206 ║ +╚═══╧═════╝ -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 64 ║ -╟───┼──────────────────────╢ -║ B │ 126 ║ -╟───┼──────────────────────╢ -║ C │ 127 ║ -╚═══╧══════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.column.md b/api-reference/dataframe/danfo.dataframe.column.md index eabb06d..2d70bfd 100644 --- a/api-reference/dataframe/danfo.dataframe.column.md +++ b/api-reference/dataframe/danfo.dataframe.column.md @@ -4,11 +4,11 @@ description: Return the elements of the specified column in the DataFrame # DataFrame.column -danfo.DataFrame.**column**(col_name) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] +danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] -| Parameters | Type | Description | Default | -| ---------- | ---- | ------------------------------------- | ------- | -| col_name | Str | The name of a column in the DataFrame | | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------- | ------- | +| column | String | The name of a column in the DataFrame | | **Returns:** @@ -45,29 +45,26 @@ df['Name'].print() //produces the same result as above {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ Name ║ -╟───┼──────────────────────╢ -║ 0 │ Apples ║ -╟───┼──────────────────────╢ -║ 1 │ Mango ║ -╟───┼──────────────────────╢ -║ 2 │ Banana ║ -╟───┼──────────────────────╢ -║ 3 │ NaN ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ Name ║ -╟───┼──────────────────────╢ -║ 0 │ Apples ║ -╟───┼──────────────────────╢ -║ 1 │ Mango ║ -╟───┼──────────────────────╢ -║ 2 │ Banana ║ -╟───┼──────────────────────╢ -║ 3 │ NaN ║ -╚═══╧══════════════════════╝ +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.dropna.md b/api-reference/dataframe/danfo.dataframe.dropna.md index cb0d5a4..81006a1 100644 --- a/api-reference/dataframe/danfo.dataframe.dropna.md +++ b/api-reference/dataframe/danfo.dataframe.dropna.md @@ -1,14 +1,15 @@ --- -description: Remove missing values (NaNs, undefined) for DataFrame +description: Remove missing values (NaNs, undefined, null) for DataFrame --- # DataFrame.dropna -danfo.DataFrame.**dropna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] +danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -| kwargs | Object |

{axis: 0: Apply along row/index axis

1: Apply across columns axis

inplace:If true, perform operation inplace

and return None.

}

|

{axis: 0,

inplace: false}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | +| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace: **false} | **Returns:** @@ -29,7 +30,7 @@ let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna({axis: 0}) +let df_drop = df.dropna(0) df_drop.print() ``` {% endtab %} diff --git a/api-reference/dataframe/danfo.dataframe.eq.md b/api-reference/dataframe/danfo.dataframe.eq.md index be1f7ff..a43fbd0 100644 --- a/api-reference/dataframe/danfo.dataframe.eq.md +++ b/api-reference/dataframe/danfo.dataframe.eq.md @@ -4,16 +4,16 @@ description: Get Equal to of DataFrame and other, element-wise (binary operator # DataFrame.eq -danfo.DataFrame.**eq**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] +danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** -** **return** DataFrame** +**** ## **Examples** @@ -70,7 +70,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let sf = new dfd.Series([10,40]) -let df_rep = df.eq(sf, axis=1) +let df_rep = df.eq(sf, {axis:1}) df_rep.print() @@ -159,7 +159,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let val = [10,40] -let df_rep = df.eq(val, axis=1) +let df_rep = df.eq(val, {axis:1}) df_rep.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.fillna.md b/api-reference/dataframe/danfo.dataframe.fillna.md index ac7cc79..49aa13d 100644 --- a/api-reference/dataframe/danfo.dataframe.fillna.md +++ b/api-reference/dataframe/danfo.dataframe.fillna.md @@ -6,11 +6,12 @@ description: >- # DataFrame.fillna -danfo.DataFrame.**fillna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] +danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| kwargs | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

values: Array | Scalar of value(s) to fill with.

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| | +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| values | Array \| Scalar | The list of value(s) to use for replacement. | | +| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | **Returns:** @@ -18,21 +19,26 @@ danfo.DataFrame.**fillna**(kwargs) \[[source](https://github.com/opensource9ja/d ## **Examples** -### Fill NaNs in specified columns with specified values +### Fill missing values in specified columns with specified values + +Missing values are NaN, undefined or null values {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} - +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna({columns: ["Name", "Count"], values: ["Apples", df["Count"].mean()]}) +let values = ["Apples", df["Count"].mean()] +let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -85,12 +91,14 @@ df_filled.print() ```javascript const dfd = require("danfojs-node") -let data = {"Name":["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250]} +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} let df = new dfd.DataFrame(data) -let df_filled = df.fillna({ values: ["Apples"] }) +let df_filled = df.fillna("Apples") df_filled.print() @@ -128,7 +136,6 @@ df_filled.print() {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") - let data = { "Name": ["Apples", "Mango", "Banana", undefined], "Count": [NaN, 5, NaN, 10], @@ -136,9 +143,9 @@ let data = { } let df = new dfd.DataFrame(data) -df.fillna({ +let values = ["Apples", df["Count"].mean()] +df.fillna(values, { columns: ["Name", "Count"], - values: ["Apples", df["Count"].mean()], inplace: true }) df.print() diff --git a/api-reference/dataframe/danfo.dataframe.ge.md b/api-reference/dataframe/danfo.dataframe.ge.md index ab0ea5c..3b41ec3 100644 --- a/api-reference/dataframe/danfo.dataframe.ge.md +++ b/api-reference/dataframe/danfo.dataframe.ge.md @@ -6,16 +6,16 @@ description: >- # DataFrame.ge -danfo.DataFrame.**ge**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1616)] +danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** -** **return** DataFrame** +** DataFrame** ## **Examples** @@ -74,7 +74,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let sf = new dfd.Series([10,40]) -let df_rep = df.ge(sf, axis=1) +let df_rep = df.ge(sf, {axis:1}) df_rep.print() @@ -164,7 +164,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let val = [10,40] -let df_rep = df.ge(val, axis=1) +let df_rep = df.ge(val, {axis:1}) df_rep.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.gt.md b/api-reference/dataframe/danfo.dataframe.gt.md index 0d6cb3c..121c7e7 100644 --- a/api-reference/dataframe/danfo.dataframe.gt.md +++ b/api-reference/dataframe/danfo.dataframe.gt.md @@ -4,12 +4,12 @@ description: Get Greater than of DataFrame and other, element-wise (binary opera # DataFrame.gt -danfo.DataFrame.**gt**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1583)] +danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** @@ -70,7 +70,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let sf = new dfd.Series([10,40]) -let df_rep = df.gt(sf, axis=1) +let df_rep = df.gt(sf, {axis:1}) df_rep.print() diff --git a/api-reference/dataframe/danfo.dataframe.it.md b/api-reference/dataframe/danfo.dataframe.it.md index 5d5d67b..69093a2 100644 --- a/api-reference/dataframe/danfo.dataframe.it.md +++ b/api-reference/dataframe/danfo.dataframe.it.md @@ -4,12 +4,12 @@ description: Get Less than of DataFrame and other, element-wise (binary operator # DataFrame.It -danfo.DataFrame.l**t**(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** @@ -65,12 +65,14 @@ df_rep.print() ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) +let sf = new dfd.Series([10, 40]) -let df_rep = df.lt(sf, axis=1) +let df_rep = df.lt(sf, { axis: 1 }) df_rep.print() @@ -148,7 +150,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing** **DataFrame with an Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.le.md b/api-reference/dataframe/danfo.dataframe.le.md index 9b86440..0b88ff1 100644 --- a/api-reference/dataframe/danfo.dataframe.le.md +++ b/api-reference/dataframe/danfo.dataframe.le.md @@ -6,12 +6,12 @@ description: >- # DataFrame.le -danfo.DataFrame.le(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] +danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** @@ -74,7 +74,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let sf = new dfd.Series([10,40]) -let df_rep = df.le(sf, axis=1) +let df_rep = df.le(sf, {axis:1}) df_rep.print() @@ -151,7 +151,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing** **DataFrame with an Array {% tabs %} {% tab title="Node" %} @@ -163,7 +163,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let val = [10,40] -let df_rep = df.le(val, axis=1) +let df_rep = df.le(val, {axis:1}) df_rep.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.nanindex.md b/api-reference/dataframe/danfo.dataframe.nanindex.md deleted file mode 100644 index 31db040..0000000 --- a/api-reference/dataframe/danfo.dataframe.nanindex.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Returns array of index with missing values ---- - -# DataFrame.nanindex - -danfo.DataFrame.**nanIndex**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1410)\] - -**Returns:** - -```text - ****return **Array** -``` - -## **Examples** - -### Drop rows \(axis=0\) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -console.log(df.nanIndex()); -``` -{% endtab %} - -{% tab title="Browser" %} -```text - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ NaN │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ NaN │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ NaN │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -[ 1, 2, 3 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.ne.md b/api-reference/dataframe/danfo.dataframe.ne.md index 8dfddc9..1996400 100644 --- a/api-reference/dataframe/danfo.dataframe.ne.md +++ b/api-reference/dataframe/danfo.dataframe.ne.md @@ -4,16 +4,16 @@ description: Get Not Equal to of DataFrame and other, element-wise (binary opera # DataFrame.ne -danfo.DataFrame.ne(other, axis) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1633)] +danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ------------------------------------------------------- | ------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| axis | Int | Whether to compare by the index (0) or columns (1). | 0 | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** -** **return** DataFrame** +**** ## **Examples** @@ -70,7 +70,7 @@ let data = {"Col1": [10, 45, 56, 10], let df = new dfd.DataFrame(data) let sf = new dfd.Series([10,40]) -let df_rep = df.ne(sf, axis=1) +let df_rep = df.ne(sf, {axis:1}) df_rep.print() diff --git a/api-reference/dataframe/danfo.dataframe.replace.md b/api-reference/dataframe/danfo.dataframe.replace.md index e4dae64..9a0b39f 100644 --- a/api-reference/dataframe/danfo.dataframe.replace.md +++ b/api-reference/dataframe/danfo.dataframe.replace.md @@ -4,11 +4,13 @@ description: Replaces values in a DataFrame with specified values # DataFrame.replace -> danfo.DataFrame.**replace**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] +> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| kwargs | Object |

{replace: int, float, str. The value to replace.

with: Int, float, str. The new value to replace with.

in: Array. An array of column names to replace, If not specified, replace all columns.

}

| | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| oldValue | String, boolean, Number | The value you want to replace | | +| newValue | String, boolean, Number | The new value you want to replace the old value with | | +| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | **Returns:** @@ -23,11 +25,13 @@ description: Replaces values in a DataFrame with specified values ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let df_rep = df.replace({ "replace": 10, "with": -999, "in": ["Col1"] }) +let df_rep = df.replace(10, -999, { columns: ["Col1"] }) df_rep.print() @@ -64,13 +68,12 @@ By not specifying a** **column**, **the** **replace works on all columns ** ** {% tabs %} {% tab title="Node" %} ```javascript -const dfd = require("danfojs-js") - +const dfd = require("danfojs-node") let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] let df = new dfd.DataFrame(data) //replace value in all column -let df_rep = df.replace({ "replace": "A", "with": "boy" }) +let df_rep = df.replace("A", "BOY") df_rep.print() @@ -87,13 +90,13 @@ df_rep.print() {% tab title="Output" %} ```javascript -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ boy │ boy │ boy │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ B │ C │ C │ D ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ BOY │ BOY │ BOY │ B ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ B │ C │ C │ D ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/dataframe.apply_map.md b/api-reference/dataframe/dataframe.apply_map.md new file mode 100644 index 0000000..986566f --- /dev/null +++ b/api-reference/dataframe/dataframe.apply_map.md @@ -0,0 +1,68 @@ +--- +description: Apply a function to a Dataframe values element-wise. +--- + +# DataFrame.apply_map + +danfo.DataFrame.**apply_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Apply a function to all values in a DataFrame + +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + short_name: ["NG", "GH", "EGY", "SA"], + long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] +} +let df = new dfd.DataFrame(data) + +function lower(x) { + return `${x}`.toLowerCase() +} + +let df_new = df.apply_map(lower) +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ short_name │ long_name ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ ng │ nigeria ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ gh │ ghana ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ egy │ eqypt ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ sa │ south africa ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} From 1c69e67c4355e2a71f657026d158592048a5e3c3 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 21:05:06 +0100 Subject: [PATCH 146/202] Update version number --- .../dataframe/creating-a-dataframe.md | 8 +-- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +- .../input-output/danfo.read_excel.md | 2 +- api-reference/input-output/danfo.read_json.md | 4 +- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +- api-reference/plotting/box-plots.md | 6 +- .../plotting/configuring-your-plots.md | 2 +- api-reference/plotting/histograms.md | 4 +- api-reference/plotting/line-charts.md | 6 +- api-reference/plotting/pie-charts.md | 6 +- api-reference/plotting/scatter-plots.md | 4 +- api-reference/plotting/tables.md | 4 +- api-reference/plotting/timeseries-plots.md | 2 +- api-reference/plotting/violin-plots.md | 6 +- api-reference/series/creating-a-series.md | 4 +- getting-started.md | 64 +++++++++++-------- release-notes.md | 2 +- 21 files changed, 74 insertions(+), 66 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index dd9931b..0228131 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -75,7 +75,7 @@ df.print() - Document + Document @@ -120,7 +120,7 @@ df.print() - Document + Document @@ -178,7 +178,7 @@ df.ctypes.print() - Document + Document @@ -256,7 +256,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 655b7e8..ee31a5e 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -47,7 +47,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index f6082a0..59f7e34 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -60,7 +60,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 030ccb7..79644f3 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -69,7 +69,7 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - + Document @@ -110,7 +110,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index fe3453a..459aa30 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -44,7 +44,7 @@ load_process_data() - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 6566efe..85412ea 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -64,7 +64,7 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple - + Document @@ -103,7 +103,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index 06e7f95..5bd4105 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -47,7 +47,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 6ec9f70..80eaa04 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index a946ebe..aee82cd 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -20,7 +20,7 @@ The **bar** plot is exposed by the .**plot\(\)** function called on a Series or - + Document @@ -51,7 +51,7 @@ The **bar** plot is exposed by the .**plot\(\)** function called on a Series or - + diff --git a/api-reference/plotting/box-plots.md b/api-reference/plotting/box-plots.md index 8f73a43..8a6e490 100644 --- a/api-reference/plotting/box-plots.md +++ b/api-reference/plotting/box-plots.md @@ -18,7 +18,7 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - + Document @@ -49,7 +49,7 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - + Document @@ -87,7 +87,7 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - + Document diff --git a/api-reference/plotting/configuring-your-plots.md b/api-reference/plotting/configuring-your-plots.md index 359a802..7d96b4d 100644 --- a/api-reference/plotting/configuring-your-plots.md +++ b/api-reference/plotting/configuring-your-plots.md @@ -12,7 +12,7 @@ For example in the following code, we show how to set some basic configuration a - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index fb63b24..12497e3 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -20,7 +20,7 @@ In the example below, we use the titanic dataset, to show a close to a real-worl - + Document @@ -57,7 +57,7 @@ In the example below, we use the titanic dataset, to show a close to a real-worl - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 073e173..73326f4 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -20,7 +20,7 @@ The **line** plot is exposed by the .**plot()** function called on a Series or D - + Document @@ -53,7 +53,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -85,7 +85,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 73278d1..c355bcb 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -18,7 +18,7 @@ A pie plot is a proportional representation of the numerical data in a column - + Document @@ -54,7 +54,7 @@ A pie plot is a proportional representation of the numerical data in a column - + Document @@ -93,7 +93,7 @@ If you have more than one pie charts displayed, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index a05de5d..739a49f 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -20,7 +20,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -57,7 +57,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/tables.md b/api-reference/plotting/tables.md index 83bf86c..efa1fbb 100644 --- a/api-reference/plotting/tables.md +++ b/api-reference/plotting/tables.md @@ -16,7 +16,7 @@ description: Turn DataFrame/Series in D3.js-based tables - + Document @@ -57,7 +57,7 @@ To configure the header and cell of a table, you can pass header/cell styles to - + Document diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index e910f57..7bbb089 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -16,7 +16,7 @@ In the example below, we plot the yearly trend of a financial dataset. First, we - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 9b55644..e0c1c8f 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -14,7 +14,7 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - + Document @@ -45,7 +45,7 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - + Document @@ -83,7 +83,7 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index dd16a93..3c8e4ba 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -62,7 +62,7 @@ df.print() - Document + Document @@ -119,7 +119,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index 5e92af5..438fddd 100644 --- a/getting-started.md +++ b/getting-started.md @@ -33,7 +33,7 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): ```markup - + ``` {% hint style="info" %} @@ -61,7 +61,7 @@ const dfd = require("danfojs-node") - + @@ -100,7 +100,7 @@ s.print() - Document + Document @@ -161,7 +161,7 @@ s.print() - + Document @@ -222,7 +222,7 @@ df.print() - Document + Document @@ -270,7 +270,7 @@ df.ctypes.print() - Document + Document @@ -348,7 +348,7 @@ df.print() - Document + Document @@ -439,7 +439,7 @@ df.print() - Document + Document @@ -542,7 +542,7 @@ console.log(df.columns); - Document + Document @@ -610,7 +610,7 @@ df.tensor.print() - Document + Document @@ -690,7 +690,7 @@ df.describe().print() - Document + Document @@ -763,7 +763,7 @@ df.print() - Document + Document @@ -833,7 +833,7 @@ df['A'].print() - Document + Document @@ -1202,7 +1202,7 @@ query_df.print() //after query - Document + Document @@ -1254,31 +1254,38 @@ query_df.print() //after query The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: ```javascript -let data = [{"A": ["Ng", "Yu", "Mo", "Ng"]}, - {"B": [34, 4, 5, 6]}, - {"C": [20, 20, 30, 40]}] +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} let df = new dfd.DataFrame(data) let query_df = df.query({ condition: df["B"].gt(5) }) -query_df.print() //after query +query_df.print() ``` ``` ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ +║ 0 │ Ng │ 34 │ 20 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ +║ 3 │ Ng │ 6 │ 40 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Querying by a boolean condition is supported from v0.3.0 and above. It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: ```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} let query_df = df.query({ condition: - df["B"].gt(5).and(df["A"].lt(30)) + df["B"].gt(5).and(df["C"].lt(30)) }) query_df.print() //after query @@ -1286,9 +1293,10 @@ query_df.print() //after query ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ +║ 0 │ Ng │ 34 │ 20 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` #### Adding a new column @@ -1323,7 +1331,7 @@ df.print() - Document + Document @@ -1412,7 +1420,7 @@ df_drop.print() - Document + Document @@ -1631,7 +1639,7 @@ df.mean().print() //defaults to column axis - Document + Document @@ -2253,7 +2261,7 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. - + Document @@ -2300,7 +2308,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2393,7 +2401,7 @@ dfd.read_csv("file:///home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 34a3249..e58b398 100644 --- a/release-notes.md +++ b/release-notes.md @@ -92,7 +92,7 @@ A simple example: - + Document From 2775ddea75a26f7f378f0cdcda396a0c947fe44e Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 20:16:52 +0000 Subject: [PATCH 147/202] GitBook: No commit message --- release-notes.md | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/release-notes.md b/release-notes.md index e58b398..a954ab0 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,12 +1,18 @@ # Release Notes -### \[LATEST] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.3.2), Browser (0.3.2) +### \[LATEST] Release Node (v0.3.3), Browser (0.3.3) + +**Date:** 10th Oct 2021 + +Minor patch update + +### \[LATEST] ReleaseNode (v0.3.2), Browser (0.3.2) **Date:** 2nd Oct 2021 -Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. +Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. -### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.3.1), Browser (0.3.1) +### ReleaseNode (v0.3.1), Browser (0.3.1) **Date:** 1st Oct 2021 @@ -21,17 +27,17 @@ Minor patch update for column name display after aggregation functions like sum, * Add loc indexing support for Series * Add configuration support for formating DataFrame display in the console * New DataFrame `applyMap` function for element-wise apply function -* `and` and `or` logical comparison support. E.g \ - `df.loc({`\ - `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ +* `and` and `or` logical comparison support. E.g\ + `df.loc({`\ + `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ `})` * `read_csv` now uses [Papaparse](https://www.papaparse.com) and supports config values for headers, separator, etc. -* `to_csv` , `to_json` and `to_excel` functions now support saving to local disk in Node and downloadable in the browser. Also, supports config parameters for output. +* `to_csv` , `to_json` and `to_excel` functions now support saving to local disk in Node and downloadable in the browser. Also, supports config parameters for output. * `read_json` now supports config values for headers, authentication, separator, etc. -* `read_excel` now uses [XLSX](https://www.npmjs.com/package/xlsx) parser, hence supports all XLSX config options. -* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g \ +* `read_excel` now uses [XLSX](https://www.npmjs.com/package/xlsx) parser, hence supports all XLSX config options. +* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g\ `df.query({`\ - `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60)) `\ + `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ `})` **Bug Fixes** @@ -43,9 +49,9 @@ Minor patch update for column name display after aggregation functions like sum, * Fix loc slicing bug for row index with string labels * DataFrame apply function now works only across a specified axis -Contributors [@risenW](https://github.com/risenW) +Contributors [@risenW](https://github.com/risenW) -### \[LATEST] Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.2.7), Browser (0.2.6) +### \[LATEST] ReleaseNode (v0.2.7), Browser (0.2.6) **Date:** 30th May 2021 @@ -54,12 +60,12 @@ Contributors [@risenW](https://github.com/risenW) Contributors [@risenW](https://github.com/risenW) [@steveoni](https://github.com/steveoni) [@jpjagt](https://github.com/jpjagt) [@sponsfreixes](https://github.com/sponsfreixes) [@bherbruck](https://github.com/bherbruck) [@woosuk288](https://github.com/woosuk288) and [@adithyaakrishna](https://github.com/adithyaakrishna) -### Release [ ](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.3)Node (v0.2.6), Browser (0.2.5) +### ReleaseNode (v0.2.6), Browser (0.2.5) **Date:** 29th March 2021 -* \[Bug Fixes]: [#150](https://github.com/opensource9ja/danfojs/pull/150) [#152 ](https://github.com/opensource9ja/danfojs/pull/152) -* \[Patches] [#159](https://github.com/opensource9ja/danfojs/pull/159) , [#158 ](https://github.com/opensource9ja/danfojs/pull/158) +* \[Bug Fixes]: [#150](https://github.com/opensource9ja/danfojs/pull/150) [#152](https://github.com/opensource9ja/danfojs/pull/152) +* \[Patches] [#159](https://github.com/opensource9ja/danfojs/pull/159) , [#158](https://github.com/opensource9ja/danfojs/pull/158) * \[Feature] [#154](https://github.com/opensource9ja/danfojs/pull/154) Perform groupby operation on grouped columns directly: ```javascript @@ -81,7 +87,7 @@ We added/updated the following features: * Fix error thrown when danfojs CDN is placed in an HTML header * Smaller bundle size for browser: From \~1.7mb to about \~550kb -* Stopped bundling Danfojs with Plotly. This means that as of v0.2.3, we no longer ship with Plotly distribution due to the huge size. Plotly plots are still supported, but in order to make them, you have to explicitly add the Plotly CDN or package. +* Stopped bundling Danfojs with Plotly. This means that as of v0.2.3, we no longer ship with Plotly distribution due to the huge size. Plotly plots are still supported, but in order to make them, you have to explicitly add the Plotly CDN or package. A simple example: @@ -126,13 +132,13 @@ A simple example: ``` -### Release [ (v0.2.2)](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.2) +### Release [(v0.2.2)](https://github.com/opensource9ja/danfojs/releases/tag/v0.2.2) **Date:** 14th February 2021 We added/updated the following features: -* Fix babel runtime issue in node version +* Fix babel runtime issue in node version * Smaller size in browser version in this version. From \~8mb to about \~5mb * Fix browser tag issue and returns back to specific versioning instead of @latest * Danfojs now ships with an exported version of tensorflowjs-node (2.8.5). This fixes the double dependency issue when building ML models, as you no longer need to install/import tensorflowjs separately. @@ -164,7 +170,7 @@ We added/updated the following features: * Add [sort_index](api-reference/dataframe/dataframe.sort_index.md) function to DataFrame and Series (New feature) * Minor patch and overall optimizations (Fix) -**Contributors**: [Rising Odegua](https://github.com/risenW), [Stephen Oni](https://github.com/steveoni), [Jhenner Tigreros](https://github.com/JhennerTigreros), [Aditya Zope](https://github.com/adzo261) +**Contributors**: [Rising Odegua](https://github.com/risenW), [Stephen Oni](https://github.com/steveoni), [Jhenner Tigreros](https://github.com/JhennerTigreros), [Aditya Zope](https://github.com/adzo261) ### Release (v0.1.0-beta) @@ -181,4 +187,3 @@ This is a minor release for browser-based environments. We added/updated the fol * Fixed upper bound bug in indexing **Contributors**: Rising Odegua, Stephen Oni - From 211d2d2fe3c1f4bfdba7264698772b2f634dc75d Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 20:18:32 +0000 Subject: [PATCH 148/202] GitBook: No commit message --- release-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release-notes.md b/release-notes.md index a954ab0..e4ad9a3 100644 --- a/release-notes.md +++ b/release-notes.md @@ -6,13 +6,13 @@ Minor patch update -### \[LATEST] ReleaseNode (v0.3.2), Browser (0.3.2) +### Release- Node (v0.3.2), Browser (0.3.2) **Date:** 2nd Oct 2021 Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. -### ReleaseNode (v0.3.1), Browser (0.3.1) +### Release Node (v0.3.1), Browser (0.3.1) **Date:** 1st Oct 2021 From 04ac423518c88c7e563c2ae5754dead9fb42dad1 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 10 Oct 2021 20:18:43 +0000 Subject: [PATCH 149/202] GitBook: [#203] Update release note --- release-notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release-notes.md b/release-notes.md index e4ad9a3..36ef577 100644 --- a/release-notes.md +++ b/release-notes.md @@ -6,13 +6,13 @@ Minor patch update -### Release- Node (v0.3.2), Browser (0.3.2) +### Release - Node (v0.3.2), Browser (0.3.2) **Date:** 2nd Oct 2021 Minor patch update for column name display after aggregation functions like sum, mean, var, are applied to a column axis. -### Release Node (v0.3.1), Browser (0.3.1) +### Release - Node (v0.3.1), Browser (0.3.1) **Date:** 1st Oct 2021 From 449fbcec5f6e5cc4ca643bbf5692c93ee3f8c673 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Tue, 12 Oct 2021 11:57:27 +0000 Subject: [PATCH 150/202] GitBook: [#204] Update date time doc --- api-reference/general-functions/danfo.to_datetime.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 6112004..97ad1d7 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -25,7 +25,7 @@ let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) let sf = new dfd.Series(data) sf.print() -let dt = dfd.toDateTime({data:sf}) +let dt = dfd.toDateTime(data) dt.month().print() dt.month_name().print() From f3789c51d4735086baf85c6b612e729ed5a21215 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 5 Dec 2021 19:24:04 +0000 Subject: [PATCH 151/202] GitBook: [#205] Update datetime name --- SUMMARY.md | 50 +++++++++---------- .../general-functions/danfo.to_datetime.md | 6 +-- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 44764c2..43e65db 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -4,22 +4,22 @@ * [Getting Started](getting-started.md) * [API reference](api-reference/README.md) * [General Functions](api-reference/general-functions/README.md) - * [danfo.date_range](api-reference/general-functions/danfo.date_range.md) + * [danfo.date\_range](api-reference/general-functions/danfo.date\_range.md) * [danfo.OneHotEncoder](api-reference/general-functions/danfo.onehotencoder.md) * [danfo.StandardScaler](api-reference/general-functions/danfo.standardscaler.md) * [danfo.MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) * [danfo.LabelEncoder](api-reference/general-functions/danfo.labelencoder.md) - * [danfo.to_datetime](api-reference/general-functions/danfo.to_datetime.md) - * [danfo.get_dummies](api-reference/general-functions/danfo.get_dummies.md) + * [danfo.toDateTime](api-reference/general-functions/danfo.to\_datetime.md) + * [danfo.get\_dummies](api-reference/general-functions/danfo.get\_dummies.md) * [danfo.concat](api-reference/general-functions/danfo.concat.md) * [danfo.merge](api-reference/general-functions/danfo.merge.md) * [Input/Output](api-reference/input-output/README.md) - * [danfo.read_excel](api-reference/input-output/danfo.read_excel.md) - * [danfo.read_json](api-reference/input-output/danfo.read_json.md) - * [danfo.read_csv](api-reference/input-output/danfo.read_csv.md) - * [danfo.to_csv](api-reference/input-output/danfo.to_csv.md) - * [danfo.to_excel](api-reference/input-output/danfo.to_excel.md) - * [danfo.to_json](api-reference/input-output/danfo.to_json.md) + * [danfo.read\_excel](api-reference/input-output/danfo.read\_excel.md) + * [danfo.read\_json](api-reference/input-output/danfo.read\_json.md) + * [danfo.read\_csv](api-reference/input-output/danfo.read\_csv.md) + * [danfo.to\_csv](api-reference/input-output/danfo.to\_csv.md) + * [danfo.to\_excel](api-reference/input-output/danfo.to\_excel.md) + * [danfo.to\_json](api-reference/input-output/danfo.to\_json.md) * [Series](api-reference/series/README.md) * [Creating a Series](api-reference/series/creating-a-series.md) * [Series.append](api-reference/series/series.append.md) @@ -50,7 +50,7 @@ * [Series.dt.seconds](api-reference/series/series.dt.second.md) * [Series.dt.minutes](api-reference/series/series.dt.minute.md) * [Series.dt.monthday](api-reference/series/series.dt.monthday.md) - * [Series.dt.month_name](api-reference/series/series.dt.month_name.md) + * [Series.dt.month\_name](api-reference/series/series.dt.month\_name.md) * [Series.dt.hour](api-reference/series/series.dt.hour.md) * [Series.dt.weekdays](api-reference/series/series.dt.weekdays.md) * [Series.dt.day](api-reference/series/series.dt.day.md) @@ -63,8 +63,8 @@ * [Series.isna](api-reference/series/series.isna.md) * [Series.fillna](api-reference/series/series.fillna.md) * [Series.dropna](api-reference/series/series.dropna.md) - * [Series.drop_duplicates](api-reference/series/series.drop_duplicates.md) - * [Series.value_counts](api-reference/series/series.value_counts.md) + * [Series.drop\_duplicates](api-reference/series/series.drop\_duplicates.md) + * [Series.value\_counts](api-reference/series/series.value\_counts.md) * [Series.nunique](api-reference/series/series.nunique.md) * [Series.unique](api-reference/series/series.unique.md) * [Series.abs](api-reference/series/series.abs.md) @@ -84,11 +84,11 @@ * [Series.index](api-reference/series/series.index.md) * [Series.apply](api-reference/series/series.apply.md) * [Series.map](api-reference/series/series.map.md) - * [Series.set_index](api-reference/series/series.set_index.md) - * [Series.reset_index](api-reference/series/series.reset_index.md) + * [Series.set\_index](api-reference/series/series.set\_index.md) + * [Series.reset\_index](api-reference/series/series.reset\_index.md) * [Series.describe](api-reference/series/series.describe.md) * [Series.copy](api-reference/series/series.copy.md) - * [Series.sort_values](api-reference/series/series.sort_values.md) + * [Series.sort\_values](api-reference/series/series.sort\_values.md) * [Series.var](api-reference/series/series.var.md) * [Series.std](api-reference/series/series.std.md) * [Series.round](api-reference/series/series.round.md) @@ -114,17 +114,17 @@ * [Series.or](api-reference/series/series.or.md) * [Dataframe](api-reference/dataframe/README.md) * [Creating a DataFrame](api-reference/dataframe/creating-a-dataframe.md) - * [DataFrame.sort_index](api-reference/dataframe/dataframe.sort_index.md) + * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort\_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) * [DataFrame.nunique](api-reference/dataframe/dataframe.nunique-1.md) * [DataFrame.tensor](api-reference/dataframe/dataframe.tensor.md) * [DataFrame.print](api-reference/dataframe/dataframe.print.md) - * [DataFrame.to_csv](api-reference/dataframe/dataframe.to_csv.md) - * [DataFrame.to_json](api-reference/dataframe/dataframe.to_json.md) - * [DataFrame.to_excel](api-reference/dataframe/dataframe.to_excel.md) - * [DataFrame.sort_values](api-reference/dataframe/dataframe.sort_values.md) - * [DataFrame.set_index](api-reference/dataframe/dataframe.set_index.md) - * [DataFrame.reset_index](api-reference/dataframe/dataframe.reset_index.md) + * [DataFrame.to\_csv](api-reference/dataframe/dataframe.to\_csv.md) + * [DataFrame.to\_json](api-reference/dataframe/dataframe.to\_json.md) + * [DataFrame.to\_excel](api-reference/dataframe/dataframe.to\_excel.md) + * [DataFrame.sort\_values](api-reference/dataframe/dataframe.sort\_values.md) + * [DataFrame.set\_index](api-reference/dataframe/dataframe.set\_index.md) + * [DataFrame.reset\_index](api-reference/dataframe/dataframe.reset\_index.md) * [DataFrame.rename](api-reference/dataframe/dataframe.rename.md) * [DataFrame.drop](api-reference/dataframe/dataframe.drop.md) * [DataFrame.astype](api-reference/dataframe/dataframe.astype.md) @@ -132,7 +132,7 @@ * [DataFrame.axis](api-reference/dataframe/dataframe.axes.md) * [DataFrame.ndim](api-reference/dataframe/dataframe.ndim.md) * [DataFrame.values](api-reference/dataframe/dataframe.values.md) - * [DataFrame.select_dtypes](api-reference/dataframe/dataframe.select_dtypes.md) + * [DataFrame.select\_dtypes](api-reference/dataframe/dataframe.select\_dtypes.md) * [DataFrame.ctypes](api-reference/dataframe/dataframe.dtypes.md) * [DataFrame.index](api-reference/dataframe/dataframe.index.md) * [DataFrame.loc](api-reference/dataframe/danfo.dataframe.loc.md) @@ -170,7 +170,7 @@ * [DataFrame.isna](api-reference/dataframe/danfo.dataframe.isna.md) * [DataFrame.dropna](api-reference/dataframe/danfo.dataframe.dropna.md) * [DataFrame.apply](api-reference/dataframe/danfo.dataframe.apply.md) - * [DataFrame.apply_map](api-reference/dataframe/dataframe.apply_map.md) + * [DataFrame.apply\_map](api-reference/dataframe/dataframe.apply\_map.md) * [DataFrame.It](api-reference/dataframe/danfo.dataframe.it.md) * [DataFrame.gt](api-reference/dataframe/danfo.dataframe.gt.md) * [DataFrame.le](api-reference/dataframe/danfo.dataframe.le.md) @@ -191,7 +191,7 @@ * [Line Charts](api-reference/plotting/line-charts.md) * [Configuring your plots](api-reference/plotting/configuring-your-plots.md) * [Groupby](api-reference/groupby/README.md) - * [Groupby.get_groups](api-reference/groupby/groupby.get_groups.md) + * [Groupby.get\_groups](api-reference/groupby/groupby.get\_groups.md) * [Groupby.col](api-reference/groupby/groupby.col.md) * [Groupby.max](api-reference/groupby/groupby.max.md) * [Groupby.min](api-reference/groupby/groupby.min.md) diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 97ad1d7..7012100 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -2,9 +2,9 @@ description: Converts an array of Date time string to Date object. --- -# danfo.to_datetime +# danfo.toDateTime -danfo.**to_datetime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] | Parameters | Type | Description | Default | | ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | @@ -12,7 +12,7 @@ danfo.**to_datetime**(data) \[[source](https://github.com/opensource9ja/danfojs/ **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** From 685b7076b7cfcd31f1853a1d5b215675e325fe14 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 5 Dec 2021 21:31:18 +0000 Subject: [PATCH 152/202] GitBook: [#207] Update query page --- .../dataframe/danfo.dataframe.query.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/api-reference/dataframe/danfo.dataframe.query.md b/api-reference/dataframe/danfo.dataframe.query.md index 847fbe0..129c8e7 100644 --- a/api-reference/dataframe/danfo.dataframe.query.md +++ b/api-reference/dataframe/danfo.dataframe.query.md @@ -1,24 +1,24 @@ --- description: >- - Query the DataFrame by the result of a logical comparison. Supports logical - operations like (">", "<", ">=", "<=", and. "==") + Query the DataFrame by the result of a logical comparison or boolean mask. + Supports logical operations like (">", "<", ">=", "<=", and. "==") --- # DataFrame.query danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| kwargs | Object |

{column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | **Returns:** -** **return** new DataFrame** + **** return **new DataFrame** ## **Examples** -## **Query a DataFrame using boolean mask** +## **Query a DataFrame using a boolean mask** {% hint style="info" %} Querying by a boolean condition is supported from v0.3.0 and above. @@ -71,7 +71,7 @@ query_df.print() //after query ## **Query a DataFrame using logical operators** -To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. +To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. {% tabs %} {% tab title="Node" %} @@ -177,7 +177,7 @@ query_df.print() //after query ## **Query by a string column in a DataFrame** -The query method also works on string columns. +The query method also works on string columns. {% tabs %} {% tab title="Node" %} From cd6d216b721bd178e45bc855698faff22724d4fb Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 5 Dec 2021 21:34:19 +0000 Subject: [PATCH 153/202] GitBook: [#208] update getting started --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c09b3c..1d1d31c 100644 --- a/README.md +++ b/README.md @@ -7,26 +7,26 @@ description: >- # Danfo.js Documentation -D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js. ** +D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js.** ## Main Features -* Danfo.js is fast. It is built on[ Tensorflow.js](https://js.tensorflow.org), and supports tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. -* Easy handling of missing** **data (represented as `NaN`) in floating point as well as non-floating point data +* Danfo.js is fast and supports[ Tensorflow.js](https://js.tensorflow.org)'s tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Easy handling of missing **** data (represented as `NaN`) in floating point as well as non-floating point data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations * Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data * Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects * Intelligent label-based slicing, fancy indexing, and querying of large data sets * Intuitive [merging](api-reference/general-functions/danfo.merge.md) and [joining](api-reference/general-functions/danfo.concat.md) data sets -* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read_csv.md) (CSV and delimited), Excel, and JSON data format. +* Robust IO tools for loading data from [flat-files](api-reference/input-output/danfo.read\_csv.md) (CSV and delimited), Excel, and JSON data format. * Powerful, flexible, and intiutive API for [plotting](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MESZnq3\_VBU0EW71MxS/api-reference/plotting) DataFrames and Series interactively. * Timeseries-specific functionality: date range generation and date and time properties. * Robust data preprocessing functions like [OneHotEncoders](api-reference/general-functions/danfo.onehotencoder.md), [LabelEncoders](api-reference/general-functions/danfo.labelencoder.md), and scalers like [StandardScaler](api-reference/general-functions/danfo.standardscaler.md) and [MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) are supported on DataFrame and Series ## Getting Started -New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's _main concepts and links to additional content. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. {% content-ref url="getting-started.md" %} [getting-started.md](getting-started.md) @@ -34,7 +34,7 @@ New to Danfo? Check out the getting started guides. It contains a quick introduc ## **API Reference** -The reference guide contains a detailed description of the **danfo** API. The reference describes how each function works and which parameters can be used. +The reference guide contains a detailed description of the **danfo** API. The reference describes how each function works and which parameters can be used. {% content-ref url="api-reference/" %} [api-reference](api-reference/) @@ -54,7 +54,7 @@ The reference guide contains a detailed description of the **danfo** API. The re ## Contributing Guide -Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. +Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. {% content-ref url="contributing-guide.md" %} [contributing-guide.md](contributing-guide.md) From f0de80466cd1de8a28fbf5e7b6e3529cc03f2357 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 2 Jan 2022 20:30:27 +0100 Subject: [PATCH 154/202] Duplicate new page for stable release doc --- api-reference-v1-stable/README.md | 54 +++ .../configuration-options.md | 128 +++++ api-reference-v1-stable/dataframe/README.md | 145 ++++++ .../dataframe/creating-a-dataframe.md | 355 ++++++++++++++ .../dataframe/danfo.dataframe.abs.md | 74 +++ .../dataframe/danfo.dataframe.add.md | 246 ++++++++++ .../dataframe/danfo.dataframe.addcolumn.md | 118 +++++ .../dataframe/danfo.dataframe.apply.md | 106 ++++ .../dataframe/danfo.dataframe.column.md | 72 +++ .../dataframe/danfo.dataframe.copy.md | 53 ++ .../dataframe/danfo.dataframe.count.md | 100 ++++ .../dataframe/danfo.dataframe.cummax.md | 99 ++++ .../dataframe/danfo.dataframe.cummin.md | 99 ++++ .../dataframe/danfo.dataframe.cumprod.md | 99 ++++ .../dataframe/danfo.dataframe.cumsum.md | 99 ++++ .../dataframe/danfo.dataframe.describe.md | 61 +++ .../dataframe/danfo.dataframe.div.md | 254 ++++++++++ .../dataframe/danfo.dataframe.dropna.md | 96 ++++ .../dataframe/danfo.dataframe.eq.md | 190 ++++++++ .../dataframe/danfo.dataframe.fillna.md | 178 +++++++ .../dataframe/danfo.dataframe.ge.md | 195 ++++++++ .../dataframe/danfo.dataframe.groupby.md | 148 ++++++ .../dataframe/danfo.dataframe.gt.md | 191 ++++++++ .../dataframe/danfo.dataframe.head.md | 53 ++ .../dataframe/danfo.dataframe.iloc.md | 331 +++++++++++++ .../dataframe/danfo.dataframe.isna.md | 54 +++ .../dataframe/danfo.dataframe.it.md | 194 ++++++++ .../dataframe/danfo.dataframe.le.md | 194 ++++++++ .../dataframe/danfo.dataframe.loc.md | 367 ++++++++++++++ .../dataframe/danfo.dataframe.max.md | 118 +++++ .../dataframe/danfo.dataframe.mean.md | 120 +++++ .../dataframe/danfo.dataframe.median.md | 120 +++++ .../dataframe/danfo.dataframe.min.md | 120 +++++ .../dataframe/danfo.dataframe.mod.md | 258 ++++++++++ .../dataframe/danfo.dataframe.mul.md | 252 ++++++++++ .../dataframe/danfo.dataframe.ne.md | 187 ++++++++ .../dataframe/danfo.dataframe.pow.md | 260 ++++++++++ .../dataframe/danfo.dataframe.query.md | 278 +++++++++++ .../dataframe/danfo.dataframe.replace.md | 102 ++++ .../dataframe/danfo.dataframe.round.md | 128 +++++ .../dataframe/danfo.dataframe.sample.md | 112 +++++ .../dataframe/danfo.dataframe.std.md | 94 ++++ .../dataframe/danfo.dataframe.sub.md | 250 ++++++++++ .../dataframe/danfo.dataframe.sum.md | 121 +++++ .../dataframe/danfo.dataframe.tail.md | 53 ++ .../dataframe/danfo.dataframe.var.md | 94 ++++ .../dataframe/dataframe.append.md | 75 +++ .../dataframe/dataframe.apply_map.md | 68 +++ .../dataframe/dataframe.astype.md | 222 +++++++++ .../dataframe/dataframe.axes.md | 47 ++ .../dataframe/dataframe.drop.md | 143 ++++++ .../dataframe/dataframe.dtypes.md | 100 ++++ .../dataframe/dataframe.index.md | 69 +++ .../dataframe/dataframe.ndim.md | 46 ++ .../dataframe/dataframe.nunique-1.md | 98 ++++ .../dataframe/dataframe.print.md | 105 ++++ .../dataframe/dataframe.rename.md | 148 ++++++ .../dataframe/dataframe.reset_index.md | 73 +++ .../dataframe/dataframe.select_dtypes.md | 94 ++++ .../dataframe/dataframe.set_index.md | 176 +++++++ .../dataframe/dataframe.shape.md | 43 ++ .../dataframe/dataframe.sort_index.md | 73 +++ .../dataframe/dataframe.sort_values.md | 99 ++++ .../dataframe/dataframe.tensor.md | 107 +++++ .../dataframe/dataframe.to_csv.md | 114 +++++ .../dataframe/dataframe.to_excel.md | 53 ++ .../dataframe/dataframe.to_json.md | 126 +++++ .../dataframe/dataframe.values.md | 50 ++ .../general-functions/README.md | 27 ++ .../general-functions/danfo.concat.md | 187 ++++++++ .../general-functions/danfo.date_range.md | 111 +++++ .../general-functions/danfo.get_dummies.md | 188 ++++++++ .../general-functions/danfo.labelencoder.md | 140 ++++++ .../general-functions/danfo.merge.md | 453 ++++++++++++++++++ .../general-functions/danfo.minmaxscaler.md | 125 +++++ .../general-functions/danfo.onehotencoder.md | 148 ++++++ .../general-functions/danfo.standardscaler.md | 132 +++++ .../general-functions/danfo.to_datetime.md | 141 ++++++ api-reference-v1-stable/groupby.md | 122 +++++ api-reference-v1-stable/groupby/README.md | 34 ++ .../groupby/groupby.agg.md | 93 ++++ .../groupby/groupby.apply.md | 84 ++++ .../groupby/groupby.col.md | 105 ++++ .../groupby/groupby.count.md | 175 +++++++ .../groupby/groupby.cummax.md | 258 ++++++++++ .../groupby/groupby.cummin.md | 258 ++++++++++ .../groupby/groupby.cumprod.md | 258 ++++++++++ .../groupby/groupby.cumsum.md | 259 ++++++++++ .../groupby/groupby.get_groups.md | 129 +++++ .../groupby/groupby.max.md | 170 +++++++ .../groupby/groupby.mean.md | 173 +++++++ .../groupby/groupby.min.md | 171 +++++++ .../groupby/groupby.std.md | 175 +++++++ .../groupby/groupby.sum.md | 172 +++++++ .../groupby/groupby.var.md | 175 +++++++ .../input-output/README.md | 18 + .../input-output/danfo.read_csv.md | 135 ++++++ .../input-output/danfo.read_excel.md | 68 +++ .../input-output/danfo.read_json.md | 128 +++++ .../input-output/danfo.to_csv.md | 115 +++++ .../input-output/danfo.to_excel.md | 54 +++ .../input-output/danfo.to_json.md | 124 +++++ api-reference-v1-stable/input-output/read.md | 138 ++++++ api-reference-v1-stable/plotting/README.md | 19 + .../plotting/bar-charts.md | 78 +++ api-reference-v1-stable/plotting/box-plots.md | 122 +++++ .../plotting/configuring-your-plots.md | 69 +++ .../plotting/histograms.md | 120 +++++ .../plotting/line-charts.md | 112 +++++ .../plotting/pie-charts.md | 127 +++++ .../plotting/scatter-plots.md | 91 ++++ api-reference-v1-stable/plotting/tables.md | 97 ++++ .../plotting/timeseries-plots.md | 58 +++ .../plotting/violin-plots.md | 116 +++++ api-reference-v1-stable/series/README.md | 182 +++++++ .../series/creating-a-series.md | 210 ++++++++ .../series/danfo.series.add.md | 22 + .../series/danfo.series.apply.md | 63 +++ .../series/danfo.series.copy.md | 22 + .../series/danfo.series.count.md | 24 + .../series/danfo.series.describe.md | 26 + .../series/danfo.series.div.md | 26 + .../series/danfo.series.head.md | 25 + .../series/danfo.series.map.md | 42 ++ .../series/danfo.series.max.md | 2 + .../series/danfo.series.maximum.md | 22 + .../series/danfo.series.mean.md | 2 + .../series/danfo.series.median.md | 2 + .../series/danfo.series.min.md | 2 + .../series/danfo.series.minimum.md | 22 + .../series/danfo.series.mod.md | 24 + .../series/danfo.series.mode.md | 2 + .../series/danfo.series.mul.md | 26 + .../series/danfo.series.pow.md | 26 + .../series/danfo.series.reset_index.md | 31 ++ .../series/danfo.series.round.md | 20 + .../series/danfo.series.sample.md | 22 + .../series/danfo.series.set_index.md | 40 ++ .../series/danfo.series.sort_values.md | 27 ++ .../series/danfo.series.std.md | 20 + .../series/danfo.series.sub.md | 24 + .../series/danfo.series.sum-1.md | 22 + .../series/danfo.series.tail.md | 22 + .../series/danfo.series.tostring.md | 18 + .../series/danfo.series.var.md | 20 + api-reference-v1-stable/series/series.abs.md | 52 ++ api-reference-v1-stable/series/series.add.md | 86 ++++ api-reference-v1-stable/series/series.and.md | 132 +++++ .../series/series.append.md | 135 ++++++ .../series/series.apply.md | 149 ++++++ .../series/series.argmax.md | 35 ++ .../series/series.argmin.md | 35 ++ .../series/series.argsort.md | 75 +++ .../series/series.astype.md | 2 + api-reference-v1-stable/series/series.copy.md | 45 ++ api-reference-v1-stable/series/series.corr.md | 2 + .../series/series.count.md | 36 ++ .../series/series.cummax.md | 51 ++ .../series/series.cummin.md | 51 ++ .../series/series.cumprod.md | 51 ++ .../series/series.cumsum.md | 74 +++ .../series/series.describe.md | 57 +++ api-reference-v1-stable/series/series.div.md | 87 ++++ api-reference-v1-stable/series/series.dot.md | 2 + .../series/series.drop_duplicates.md | 121 +++++ .../series/series.dropna.md | 91 ++++ .../series/series.dt.day.md | 55 +++ .../series/series.dt.hour.md | 52 ++ .../series/series.dt.minute.md | 60 +++ .../series/series.dt.month.md | 47 ++ .../series/series.dt.month_name.md | 55 +++ .../series/series.dt.monthday.md | 55 +++ .../series/series.dt.second.md | 60 +++ .../series/series.dt.weekdays.md | 79 +++ .../series/series.dt.year.md | 45 ++ .../series/series.dtype.md | 34 ++ api-reference-v1-stable/series/series.eq.md | 95 ++++ .../series/series.fillna.md | 106 ++++ api-reference-v1-stable/series/series.ge.md | 95 ++++ api-reference-v1-stable/series/series.gt.md | 95 ++++ api-reference-v1-stable/series/series.head.md | 51 ++ api-reference-v1-stable/series/series.iloc.md | 158 ++++++ .../series/series.index.md | 33 ++ api-reference-v1-stable/series/series.isna.md | 45 ++ api-reference-v1-stable/series/series.le.md | 96 ++++ api-reference-v1-stable/series/series.loc.md | 198 ++++++++ api-reference-v1-stable/series/series.lt.md | 96 ++++ api-reference-v1-stable/series/series.map.md | 92 ++++ api-reference-v1-stable/series/series.max.md | 36 ++ .../series/series.maximum.md | 50 ++ api-reference-v1-stable/series/series.mean.md | 36 ++ .../series/series.median.md | 36 ++ api-reference-v1-stable/series/series.min.md | 36 ++ .../series/series.minimum.md | 48 ++ api-reference-v1-stable/series/series.mod.md | 85 ++++ api-reference-v1-stable/series/series.mode.md | 36 ++ api-reference-v1-stable/series/series.mul.md | 86 ++++ api-reference-v1-stable/series/series.ndim.md | 34 ++ api-reference-v1-stable/series/series.ne.md | 95 ++++ .../series/series.nunique.md | 34 ++ api-reference-v1-stable/series/series.or.md | 132 +++++ api-reference-v1-stable/series/series.pow.md | 87 ++++ .../series/series.replace.md | 89 ++++ .../series/series.reset_index.md | 113 +++++ .../series/series.round.md | 48 ++ .../series/series.sample.md | 65 +++ .../series/series.set_index.md | 136 ++++++ .../series/series.shape.md | 35 ++ api-reference-v1-stable/series/series.size.md | 37 ++ .../series/series.sort_values.md | 140 ++++++ api-reference-v1-stable/series/series.std.md | 39 ++ .../series/series.str.capitalize.md | 52 ++ .../series/series.str.charat.md | 53 ++ .../series/series.str.concat.md | 165 +++++++ .../series/series.str.endswith.md | 51 ++ .../series/series.str.includes.md | 51 ++ .../series/series.str.indexof.md | 51 ++ .../series/series.str.join.md | 52 ++ .../series/series.str.lastindexof.md | 54 +++ .../series/series.str.len.md | 52 ++ .../series/series.str.repeat.md | 51 ++ .../series/series.str.replace.md | 50 ++ .../series/series.str.search.md | 94 ++++ .../series/series.str.slice.md | 54 +++ .../series/series.str.split.md | 74 +++ .../series/series.str.startswith.md | 51 ++ .../series/series.str.substr.md | 50 ++ .../series/series.str.substring.md | 56 +++ .../series/series.str.tolowercase.md | 50 ++ .../series/series.str.touppercase.md | 52 ++ .../series/series.str.trim.md | 50 ++ api-reference-v1-stable/series/series.sub.md | 86 ++++ api-reference-v1-stable/series/series.sum.md | 36 ++ api-reference-v1-stable/series/series.tail.md | 49 ++ .../series/series.tensor.md | 46 ++ .../series/series.unique.md | 55 +++ .../series/series.value_counts.md | 54 +++ .../series/series.values.md | 35 ++ api-reference-v1-stable/series/series.var.md | 35 ++ 239 files changed, 22652 insertions(+) create mode 100644 api-reference-v1-stable/README.md create mode 100644 api-reference-v1-stable/configuration-options.md create mode 100644 api-reference-v1-stable/dataframe/README.md create mode 100644 api-reference-v1-stable/dataframe/creating-a-dataframe.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.abs.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.add.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.apply.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.column.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.copy.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.count.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.describe.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.div.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.eq.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ge.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.gt.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.head.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.isna.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.it.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.le.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.loc.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.max.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mean.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.median.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.min.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mod.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mul.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ne.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.pow.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.query.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.replace.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.round.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sample.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.std.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sub.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sum.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.tail.md create mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.var.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.append.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.apply_map.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.astype.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.axes.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.drop.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.dtypes.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.index.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.ndim.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.nunique-1.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.print.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.rename.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.reset_index.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.select_dtypes.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.set_index.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.shape.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_index.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_values.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.tensor.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.to_csv.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.to_excel.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.to_json.md create mode 100644 api-reference-v1-stable/dataframe/dataframe.values.md create mode 100644 api-reference-v1-stable/general-functions/README.md create mode 100644 api-reference-v1-stable/general-functions/danfo.concat.md create mode 100644 api-reference-v1-stable/general-functions/danfo.date_range.md create mode 100644 api-reference-v1-stable/general-functions/danfo.get_dummies.md create mode 100644 api-reference-v1-stable/general-functions/danfo.labelencoder.md create mode 100644 api-reference-v1-stable/general-functions/danfo.merge.md create mode 100644 api-reference-v1-stable/general-functions/danfo.minmaxscaler.md create mode 100644 api-reference-v1-stable/general-functions/danfo.onehotencoder.md create mode 100644 api-reference-v1-stable/general-functions/danfo.standardscaler.md create mode 100644 api-reference-v1-stable/general-functions/danfo.to_datetime.md create mode 100644 api-reference-v1-stable/groupby.md create mode 100644 api-reference-v1-stable/groupby/README.md create mode 100644 api-reference-v1-stable/groupby/groupby.agg.md create mode 100644 api-reference-v1-stable/groupby/groupby.apply.md create mode 100644 api-reference-v1-stable/groupby/groupby.col.md create mode 100644 api-reference-v1-stable/groupby/groupby.count.md create mode 100644 api-reference-v1-stable/groupby/groupby.cummax.md create mode 100644 api-reference-v1-stable/groupby/groupby.cummin.md create mode 100644 api-reference-v1-stable/groupby/groupby.cumprod.md create mode 100644 api-reference-v1-stable/groupby/groupby.cumsum.md create mode 100644 api-reference-v1-stable/groupby/groupby.get_groups.md create mode 100644 api-reference-v1-stable/groupby/groupby.max.md create mode 100644 api-reference-v1-stable/groupby/groupby.mean.md create mode 100644 api-reference-v1-stable/groupby/groupby.min.md create mode 100644 api-reference-v1-stable/groupby/groupby.std.md create mode 100644 api-reference-v1-stable/groupby/groupby.sum.md create mode 100644 api-reference-v1-stable/groupby/groupby.var.md create mode 100644 api-reference-v1-stable/input-output/README.md create mode 100644 api-reference-v1-stable/input-output/danfo.read_csv.md create mode 100644 api-reference-v1-stable/input-output/danfo.read_excel.md create mode 100644 api-reference-v1-stable/input-output/danfo.read_json.md create mode 100644 api-reference-v1-stable/input-output/danfo.to_csv.md create mode 100644 api-reference-v1-stable/input-output/danfo.to_excel.md create mode 100644 api-reference-v1-stable/input-output/danfo.to_json.md create mode 100644 api-reference-v1-stable/input-output/read.md create mode 100644 api-reference-v1-stable/plotting/README.md create mode 100644 api-reference-v1-stable/plotting/bar-charts.md create mode 100644 api-reference-v1-stable/plotting/box-plots.md create mode 100644 api-reference-v1-stable/plotting/configuring-your-plots.md create mode 100644 api-reference-v1-stable/plotting/histograms.md create mode 100644 api-reference-v1-stable/plotting/line-charts.md create mode 100644 api-reference-v1-stable/plotting/pie-charts.md create mode 100644 api-reference-v1-stable/plotting/scatter-plots.md create mode 100644 api-reference-v1-stable/plotting/tables.md create mode 100644 api-reference-v1-stable/plotting/timeseries-plots.md create mode 100644 api-reference-v1-stable/plotting/violin-plots.md create mode 100644 api-reference-v1-stable/series/README.md create mode 100644 api-reference-v1-stable/series/creating-a-series.md create mode 100644 api-reference-v1-stable/series/danfo.series.add.md create mode 100644 api-reference-v1-stable/series/danfo.series.apply.md create mode 100644 api-reference-v1-stable/series/danfo.series.copy.md create mode 100644 api-reference-v1-stable/series/danfo.series.count.md create mode 100644 api-reference-v1-stable/series/danfo.series.describe.md create mode 100644 api-reference-v1-stable/series/danfo.series.div.md create mode 100644 api-reference-v1-stable/series/danfo.series.head.md create mode 100644 api-reference-v1-stable/series/danfo.series.map.md create mode 100644 api-reference-v1-stable/series/danfo.series.max.md create mode 100644 api-reference-v1-stable/series/danfo.series.maximum.md create mode 100644 api-reference-v1-stable/series/danfo.series.mean.md create mode 100644 api-reference-v1-stable/series/danfo.series.median.md create mode 100644 api-reference-v1-stable/series/danfo.series.min.md create mode 100644 api-reference-v1-stable/series/danfo.series.minimum.md create mode 100644 api-reference-v1-stable/series/danfo.series.mod.md create mode 100644 api-reference-v1-stable/series/danfo.series.mode.md create mode 100644 api-reference-v1-stable/series/danfo.series.mul.md create mode 100644 api-reference-v1-stable/series/danfo.series.pow.md create mode 100644 api-reference-v1-stable/series/danfo.series.reset_index.md create mode 100644 api-reference-v1-stable/series/danfo.series.round.md create mode 100644 api-reference-v1-stable/series/danfo.series.sample.md create mode 100644 api-reference-v1-stable/series/danfo.series.set_index.md create mode 100644 api-reference-v1-stable/series/danfo.series.sort_values.md create mode 100644 api-reference-v1-stable/series/danfo.series.std.md create mode 100644 api-reference-v1-stable/series/danfo.series.sub.md create mode 100644 api-reference-v1-stable/series/danfo.series.sum-1.md create mode 100644 api-reference-v1-stable/series/danfo.series.tail.md create mode 100644 api-reference-v1-stable/series/danfo.series.tostring.md create mode 100644 api-reference-v1-stable/series/danfo.series.var.md create mode 100644 api-reference-v1-stable/series/series.abs.md create mode 100644 api-reference-v1-stable/series/series.add.md create mode 100644 api-reference-v1-stable/series/series.and.md create mode 100644 api-reference-v1-stable/series/series.append.md create mode 100644 api-reference-v1-stable/series/series.apply.md create mode 100644 api-reference-v1-stable/series/series.argmax.md create mode 100644 api-reference-v1-stable/series/series.argmin.md create mode 100644 api-reference-v1-stable/series/series.argsort.md create mode 100644 api-reference-v1-stable/series/series.astype.md create mode 100644 api-reference-v1-stable/series/series.copy.md create mode 100644 api-reference-v1-stable/series/series.corr.md create mode 100644 api-reference-v1-stable/series/series.count.md create mode 100644 api-reference-v1-stable/series/series.cummax.md create mode 100644 api-reference-v1-stable/series/series.cummin.md create mode 100644 api-reference-v1-stable/series/series.cumprod.md create mode 100644 api-reference-v1-stable/series/series.cumsum.md create mode 100644 api-reference-v1-stable/series/series.describe.md create mode 100644 api-reference-v1-stable/series/series.div.md create mode 100644 api-reference-v1-stable/series/series.dot.md create mode 100644 api-reference-v1-stable/series/series.drop_duplicates.md create mode 100644 api-reference-v1-stable/series/series.dropna.md create mode 100644 api-reference-v1-stable/series/series.dt.day.md create mode 100644 api-reference-v1-stable/series/series.dt.hour.md create mode 100644 api-reference-v1-stable/series/series.dt.minute.md create mode 100644 api-reference-v1-stable/series/series.dt.month.md create mode 100644 api-reference-v1-stable/series/series.dt.month_name.md create mode 100644 api-reference-v1-stable/series/series.dt.monthday.md create mode 100644 api-reference-v1-stable/series/series.dt.second.md create mode 100644 api-reference-v1-stable/series/series.dt.weekdays.md create mode 100644 api-reference-v1-stable/series/series.dt.year.md create mode 100644 api-reference-v1-stable/series/series.dtype.md create mode 100644 api-reference-v1-stable/series/series.eq.md create mode 100644 api-reference-v1-stable/series/series.fillna.md create mode 100644 api-reference-v1-stable/series/series.ge.md create mode 100644 api-reference-v1-stable/series/series.gt.md create mode 100644 api-reference-v1-stable/series/series.head.md create mode 100644 api-reference-v1-stable/series/series.iloc.md create mode 100644 api-reference-v1-stable/series/series.index.md create mode 100644 api-reference-v1-stable/series/series.isna.md create mode 100644 api-reference-v1-stable/series/series.le.md create mode 100644 api-reference-v1-stable/series/series.loc.md create mode 100644 api-reference-v1-stable/series/series.lt.md create mode 100644 api-reference-v1-stable/series/series.map.md create mode 100644 api-reference-v1-stable/series/series.max.md create mode 100644 api-reference-v1-stable/series/series.maximum.md create mode 100644 api-reference-v1-stable/series/series.mean.md create mode 100644 api-reference-v1-stable/series/series.median.md create mode 100644 api-reference-v1-stable/series/series.min.md create mode 100644 api-reference-v1-stable/series/series.minimum.md create mode 100644 api-reference-v1-stable/series/series.mod.md create mode 100644 api-reference-v1-stable/series/series.mode.md create mode 100644 api-reference-v1-stable/series/series.mul.md create mode 100644 api-reference-v1-stable/series/series.ndim.md create mode 100644 api-reference-v1-stable/series/series.ne.md create mode 100644 api-reference-v1-stable/series/series.nunique.md create mode 100644 api-reference-v1-stable/series/series.or.md create mode 100644 api-reference-v1-stable/series/series.pow.md create mode 100644 api-reference-v1-stable/series/series.replace.md create mode 100644 api-reference-v1-stable/series/series.reset_index.md create mode 100644 api-reference-v1-stable/series/series.round.md create mode 100644 api-reference-v1-stable/series/series.sample.md create mode 100644 api-reference-v1-stable/series/series.set_index.md create mode 100644 api-reference-v1-stable/series/series.shape.md create mode 100644 api-reference-v1-stable/series/series.size.md create mode 100644 api-reference-v1-stable/series/series.sort_values.md create mode 100644 api-reference-v1-stable/series/series.std.md create mode 100644 api-reference-v1-stable/series/series.str.capitalize.md create mode 100644 api-reference-v1-stable/series/series.str.charat.md create mode 100644 api-reference-v1-stable/series/series.str.concat.md create mode 100644 api-reference-v1-stable/series/series.str.endswith.md create mode 100644 api-reference-v1-stable/series/series.str.includes.md create mode 100644 api-reference-v1-stable/series/series.str.indexof.md create mode 100644 api-reference-v1-stable/series/series.str.join.md create mode 100644 api-reference-v1-stable/series/series.str.lastindexof.md create mode 100644 api-reference-v1-stable/series/series.str.len.md create mode 100644 api-reference-v1-stable/series/series.str.repeat.md create mode 100644 api-reference-v1-stable/series/series.str.replace.md create mode 100644 api-reference-v1-stable/series/series.str.search.md create mode 100644 api-reference-v1-stable/series/series.str.slice.md create mode 100644 api-reference-v1-stable/series/series.str.split.md create mode 100644 api-reference-v1-stable/series/series.str.startswith.md create mode 100644 api-reference-v1-stable/series/series.str.substr.md create mode 100644 api-reference-v1-stable/series/series.str.substring.md create mode 100644 api-reference-v1-stable/series/series.str.tolowercase.md create mode 100644 api-reference-v1-stable/series/series.str.touppercase.md create mode 100644 api-reference-v1-stable/series/series.str.trim.md create mode 100644 api-reference-v1-stable/series/series.sub.md create mode 100644 api-reference-v1-stable/series/series.sum.md create mode 100644 api-reference-v1-stable/series/series.tail.md create mode 100644 api-reference-v1-stable/series/series.tensor.md create mode 100644 api-reference-v1-stable/series/series.unique.md create mode 100644 api-reference-v1-stable/series/series.value_counts.md create mode 100644 api-reference-v1-stable/series/series.values.md create mode 100644 api-reference-v1-stable/series/series.var.md diff --git a/api-reference-v1-stable/README.md b/api-reference-v1-stable/README.md new file mode 100644 index 0000000..b5d5d28 --- /dev/null +++ b/api-reference-v1-stable/README.md @@ -0,0 +1,54 @@ +--- +description: >- + This page gives an overview of all public danfo objects, functions and + methods. All classes and functions exposed in danfo.* namespace are public. +--- + +# API reference + +* [General Functions](general-functions/) + * [Data manipulations](general-functions/#data-manipulations) + * [Data Processing/Normalization](general-functions/#data-processing-normalization) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) +* [Input/output](input-output/) + * [CSV](input-output/#csv) + * [JSON](input-output/#json) +* [Series](series/) + * [Attributes](series/#attributes) + * [Conversion](series/#conversion) + * [Indexing, iteration](series/#indexing-iteration) + * [Binary operator functions](series/#binary-operator-functions) + * [Function application, GroupBy & window](series/#function-application-and-groupby) + * [Computations / descriptive stats](series/#computations-descriptive-stats) + * [Reindexing / selection / label manipulation](series/#reindexing-selection-label-manipulation) + * [Missing data handling](series/#missing-data-handling) + * [Reshaping, sorting](series/#reshaping-sorting) + * [Accessors](series/#accessors) + * [Serialization / IO / conversion](series/#serialization-io-conversion) +* [DataFrame](dataframe/) + * [Attributes ](dataframe/#attributes) + * [Conversion](dataframe/#conversion) + * [Indexing, iteration](dataframe/#indexing-iteration) + * [Binary operator functions](dataframe/#binary-operator-functions) + * [Function application, GroupBy & window](dataframe/#function-application-and-groupby) + * [Computations / descriptive stats](dataframe/#computations-descriptive-stats) + * [Reindexing / selection / label manipulation](dataframe/#reindexing-selection-label-manipulation) + * [Missing data handling](dataframe/#missing-data-handling) + * [Reshaping, sorting, transposing](dataframe/#sorting-and-transposing) + * [Combining / comparing / joining / merging](dataframe/#combining-comparing-joining-merging) + * [Serialization / IO / conversion](dataframe/#serialization-io-conversion) +* [Plotting](plotting/) + * [Line Charts](plotting/line-charts.md) + * [Bar Charts](plotting/bar-charts.md) + * [Scatter Plots](plotting/scatter-plots.md) + * [Histograms](plotting/histograms.md) + * [Pie Charts](plotting/pie-charts.md) + * [Tables](plotting/tables.md) + * [Box Plots](plotting/box-plots.md) + * [Violin Plots](plotting/violin-plots.md) + * [Timeseries Plots](plotting/timeseries-plots.md) +* [GroupBy](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html) + * [Indexing, iteration](groupby/#indexing-iteration) + * [Function application](groupby/#function-application) + * [Computations / descriptive stats](groupby/#computations-descriptive-stats) + diff --git a/api-reference-v1-stable/configuration-options.md b/api-reference-v1-stable/configuration-options.md new file mode 100644 index 0000000..f4c2136 --- /dev/null +++ b/api-reference-v1-stable/configuration-options.md @@ -0,0 +1,128 @@ +--- +description: >- + This section describes all user configurable options available on + DataFrame/Series creation. +--- + +# Configuration Options + +On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. + +| Parameter | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | +| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | +| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | +| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| + +> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) + +## Examples of setting configs + +### Add a DataFrame header + +```javascript + const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] + }; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + }, + } +}); +df.print() +``` + +```javascript +╔════════════════════════════════════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟────────────┬───────────────────┬───────────────────┬───────────────────╢ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Configure column size and display format of DataFrame + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +}; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + columns: [ + { alignment: 'left' }, + { alignment: 'center', width: 20 }, + { alignment: 'right' }, + { alignment: 'justify' } + ], + }, + } +}); +df.print() +``` + +```javascript +╔══════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟───┬──────────────────────┬───────┬───────╢ +║ │ Name │ Count │ Price ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧══════════════════════╧═══════╧═══════╝ +``` + +### Configure the number of rows displayed when **print** is called + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250], + +}; +const df = new DataFrame(data, { + config: { + tableMaxColInConsole: 6, + tableMaxRow: 1 + } +}); +df.print() +``` + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference-v1-stable/dataframe/README.md b/api-reference-v1-stable/dataframe/README.md new file mode 100644 index 0000000..a45aabd --- /dev/null +++ b/api-reference-v1-stable/dataframe/README.md @@ -0,0 +1,145 @@ +--- +description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. +--- + +# Dataframe + +> `DataFrame`(data, {\ +> **columns:** \[ Array ],\ +> **dtypes:** \[ Array ],** **\ +> ** index: **\[Array], \ +> **options**: Object}) + +### Attributes + +| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | +| ------------------------------------------------ | ---------------------------------------- | +| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | + +| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | +| ------------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.select_dtypes`](dataframe.select_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | +| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | +| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | +| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | +| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | +| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | + +### Conversion + +| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | +| ------------------------------------------- | -------------------------------------------------- | +| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | + +### Indexing, iteration + +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | +| --------------------------------------------- | ------------------------------------------------------------------ | +| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | +| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | + +### Binary operator functions + +| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | +| ----------------------------------------- | --------------------------------------------------------------------------------------- | +| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | +| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | +| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | +| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | +| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | +| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | +| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | +| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | +| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | +| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | +| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | + +### Function application & GroupBy + +| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | +| --------------------------------------------- | --------------------------------------------------------- | +| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | +| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | + +### Computations / descriptive stats + +| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | +| --------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | +| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | +| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | +| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | +| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | +| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | +| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | +| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | +| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | +| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | +| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | +| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | + +### Reindexing / selection / label manipulation + +| | | +| --------------------------------------------------- | ------------------------------------------------------- | +| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | +| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | +| [`DataFrame.reset_index`](dataframe.reset_index.md) | Reset the index of a DataFrame | +| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | +| [`DataFrame.set_index`](dataframe.set_index.md) | Set the DataFrame index using existing columns. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | + +### Missing data handling + +| | | +| ------------------------------------------------- | ------------------------------------------- | +| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | +| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | +| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | +| [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | + +### Sorting & transposing + +| | | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| [`DataFrame.sort_values`](dataframe.sort_values.md) | Sort by the values along either axis. | +| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | + +### Combining / comparing / joining / merging + +| | | +| ---------------------------------------------------------- | ------------------------------------------------------------------- | +| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | +| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | +| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | + +### Plotting + +`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. + +| | | +| -------------------------------------------------------- | ------------------------------------------------------------- | +| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | +| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | +| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | + +### Serialization / IO / conversion + +| | | +| ------------------------------------------- | ---------------------------------------------------- | +| [`DataFrame.to_csv`](dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | +| [`DataFrame.to_json`](dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/dataframe/creating-a-dataframe.md b/api-reference-v1-stable/dataframe/creating-a-dataframe.md new file mode 100644 index 0000000..0228131 --- /dev/null +++ b/api-reference-v1-stable/dataframe/creating-a-dataframe.md @@ -0,0 +1,355 @@ +--- +description: Creates a DataFrame object from flat structure +--- + +# Creating a DataFrame + +new danfo.**DataFrame**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

columns: Array of column names. If not specified, column names are + auto generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ +In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. + +### Creating a `DataFrame` from a JSON object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +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 }] + +df = new dfd.DataFrame(json_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Creating a `DataFrame` from an array of array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] +let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` from a 2D tensor + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const tf = require("@tensorflow/tfjs-node") + + +let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) +let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) +df.print() +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ int32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ +``` + +### Creating a `DataFrame` from an object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) + +console.log(dates); + +obj_data = {'A': dates, + 'B': ["bval1", "bval2", "bval3", "bval4"], + 'C': [10, 20, 30, 40], + 'D': [1.2, 3.45, 60.1, 45], + 'E': ["test", "train", "test", "train"] + } + +df = new dfd.DataFrame(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +//output in console +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D │ E ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying index, dtypes, columns + +You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. + +> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; +let index = ["a", "b"]; +let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] +let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] + +let df = new DataFrame(data1, { index, columns, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying memory mode + +To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: + +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; + +let df = new DataFrame(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. +{% endhint %} + +For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md b/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md new file mode 100644 index 0000000..83c6cd3 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md @@ -0,0 +1,74 @@ +--- +description: Return a DataFrame with the absolute numeric value of each element. +--- + +# DataFrame.abs + +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | + +**Returns:** + +** **return** Series** + +## **Examples** + +The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let df_abs = df.abs() +df_abs.abs().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after applying abs function + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.add.md b/api-reference-v1-stable/dataframe/danfo.dataframe.add.md new file mode 100644 index 0000000..467c143 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.add.md @@ -0,0 +1,246 @@ +--- +description: Get Addition of DataFrame and other, element-wise (binary operator add). +--- + +# DataFrame.add + +danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Addition of** scalar to **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.add(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of** Series to **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.add(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 8 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 8 │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 9 │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of** **DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.add(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 2 │ 22 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 9 │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 25 │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of** ** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.add(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Addition works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.add(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md b/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md new file mode 100644 index 0000000..ef0ecc9 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md @@ -0,0 +1,118 @@ +--- +description: Add new column to a DataFrame +--- + +# DataFrame.addColumn + +danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | + +**Returns:** + +## **Examples** + +## **Add Array as a new column to DataFrame** + +New columns get added at the end of the DataFrame, and this happens so returns nothing, + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) +df.print() + +let new_col = [1, 2, 3, 4] +df.addColumn({ "column": "D", "values": new_col, inplace: true }); + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Add Series as a new column to DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) +let s = new dfd.Series([1, 2, 3, 4]) +df.addColumn({ "column": "D", "values": s, inplace: true }); + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md b/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md new file mode 100644 index 0000000..01fab60 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md @@ -0,0 +1,106 @@ +--- +description: Apply a function to each element or along a specified axis of a DataFrame. +--- + +# DataFrame.apply + +danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Apply a function along default axis 1 (columns) + +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); +} + +let df_new = df.apply(sum_vals, { axis: 1 }) +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +### Apply a function along axis 0 (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); +} + +let df_new = df.apply(sum_vals, { axis: 0 }) +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 0 │ 6 ║ +╟───┼─────╢ +║ 1 │ 15 ║ +╟───┼─────╢ +║ 2 │ 90 ║ +╟───┼─────╢ +║ 3 │ 206 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.column.md b/api-reference-v1-stable/dataframe/danfo.dataframe.column.md new file mode 100644 index 0000000..2d70bfd --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.column.md @@ -0,0 +1,72 @@ +--- +description: Return the elements of the specified column in the DataFrame +--- + +# DataFrame.column + +danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------- | ------- | +| column | String | The name of a column in the DataFrame | | + +**Returns:** + +** **return** Series** + +## **Examples** + +## **Select a single column from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = { "Name": ["Apples", "App", "Banana", undefined], + "Count": [NaN, 5, NaN, 10] , + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) + +df.column("Name").print() + +//Alternatively, you can retrieve columns by using the object property +df['Name'].print() //produces the same result as above + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + +``` +{% endtab %} +{% endtabs %} + +To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md b/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md new file mode 100644 index 0000000..ef705ed --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md @@ -0,0 +1,53 @@ +--- +description: Makes a new copy of the DataFrame +--- + +# DataFrame.copy + +danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] + +**Returns:** + +** **return** new DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) +let new_df = df.copy() +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.count.md b/api-reference-v1-stable/dataframe/danfo.dataframe.count.md new file mode 100644 index 0000000..9e9916e --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.count.md @@ -0,0 +1,100 @@ +--- +description: >- + Count non-NaN cells for each column or row. The values NaN and undefined are + considered NaN +--- + +# DataFrame.count + +danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Count Non-NaN values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.count().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══════╤══════════════════════╗ +║ │ 0 ║ +╟───────┼──────────────────────╢ +║ Name │ 3 ║ +╟───────┼──────────────────────╢ +║ Count │ 2 ║ +╟───────┼──────────────────────╢ +║ Price │ 4 ║ +╚═══════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Count Non-NaN values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.count({axis: 0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 3 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md new file mode 100644 index 0000000..c46ae7b --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative maximum over a DataFrame or Series axis. +--- + +# DataFrame.cummax + +danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +## Cumulative maximum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummax({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 11 │ 20 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 11 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 11 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative maximum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummax({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 15 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 89 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md new file mode 100644 index 0000000..53f4045 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative minimum over a DataFrame or Series axis. +--- + +# DataFrame.cummin + +danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +## Cumulative minimum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummin({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 15 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 15 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative minimum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummin({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 11 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 2 │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md new file mode 100644 index 0000000..b780cd2 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative product over a DataFrame or Series axis. +--- + +# DataFrame.cumprod + +danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +## Cumulative product of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumprod() + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 10 │ 18 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 300 │ 720 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 4 │ 26700 │ 56160 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative product of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumprod({axis: 1}) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 60 │ 2400 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 178 │ 13884 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md new file mode 100644 index 0000000..4863805 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative sum over a DataFrame or Series axis. +--- + +# DataFrame.cumsum + +danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +## Cumulative sum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumsum({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 12 │ 35 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 14 │ 65 │ 49 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 16 │ 154 │ 127 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative sum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumsum({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 31 │ 34 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 16 │ 22 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 32 │ 72 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 91 │ 169 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md b/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md new file mode 100644 index 0000000..4dac614 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md @@ -0,0 +1,61 @@ +--- +description: >- + Generate descriptive statistics for each numeric column. Numeric columns are + of type Int and float. +--- + +# DataFrame.describe + +danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] +let col_names = ["col1", "col2", "col3", "col4"] +let df = new dfd.DataFrame(data, {columns: col_names}) + +df.describe().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 3 │ 3 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0 │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 2 │ 4 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 360 │ 180 │ 360 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.div.md b/api-reference-v1-stable/dataframe/danfo.dataframe.div.md new file mode 100644 index 0000000..54123d9 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.div.md @@ -0,0 +1,254 @@ +--- +description: >- + Get Float division of DataFrame and other, element-wise (binary operator + truediv). +--- + +# DataFrame.div + +danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Division of** scalar with **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.div(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Division of** Series with **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.div(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0.25 │ 0.6000000238418… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0.4000000059604… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1.25 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0.25 │ 0.8000000119209… ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Division of** **DataFrame **with** a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.div(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0.1000000014901… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0.8000000119209… │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0.25 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Division of** ** Array **with** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.div(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Division works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.div(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md new file mode 100644 index 0000000..81006a1 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md @@ -0,0 +1,96 @@ +--- +description: Remove missing values (NaNs, undefined, null) for DataFrame +--- + +# DataFrame.dropna + +danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | +| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace: **false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Drop rows (axis=0) with missing values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.print() + +let df_drop = df.dropna(0) +df_drop.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop columns (axis=1) with missing values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.print() + +df.dropna({axis: 1, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md b/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md new file mode 100644 index 0000000..a43fbd0 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md @@ -0,0 +1,190 @@ +--- +description: Get Equal to of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.eq + +danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +**** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.eq(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.eq(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.eq(df2) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.eq(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md new file mode 100644 index 0000000..49aa13d --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md @@ -0,0 +1,178 @@ +--- +description: >- + Fill NaN/undefined values using the specified method. Detect missing values + for an array-like object. +--- + +# DataFrame.fillna + +danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] + +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| values | Array \| Scalar | The list of value(s) to use for replacement. | | +| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Fill missing values in specified columns with specified values + +Missing values are NaN, undefined or null values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +df.print() + +let values = ["Apples", df["Count"].mean()] +let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) +df_filled.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Before filling +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ NaN │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ NaN │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After filling + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 7.5 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 7.5 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ +``` +{% endtab %} +{% endtabs %} + +### Fill all columns with NaNs with a specified value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +let df_filled = df.fillna("Apples") + +df_filled.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ Apples │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Fill NaNs inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +let values = ["Apples", df["Count"].mean()] +df.fillna(values, { + columns: ["Name", "Count"], + inplace: true +}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ Apples │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md new file mode 100644 index 0000000..3b41ec3 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md @@ -0,0 +1,195 @@ +--- +description: >- + Get Greater or Equal to of DataFrame and other, element-wise (binary operator + eq). +--- + +# DataFrame.ge + +danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +** DataFrame** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) + +let df_rep = df.ge(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.ge(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.ge(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.ge(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md b/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md new file mode 100644 index 0000000..a31f095 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md @@ -0,0 +1,148 @@ +--- +description: Group DataFrame using a mapper or by a Series of columns. +--- + +# DataFrame.groupby + +danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] + +| Parameters | Type | Description | Default | +| ---------- | ----- | ----------------------------------------------------- | ------- | +| columns | Array | The names of a column(s) in the DataFrame to group by | | + +**Returns:** + +** **return** DataFrame.groups** + +## **Examples** + +## **Groupby a single column from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]) +console.log(group_df) + +//GroupBy Object +GroupBy { + key_col: [ 'A' ], + col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, + data: [ + [ 'Pear', 2, 3 ], + [ 'Pear', 5, 6 ], + [ 'Apple', 30, 40 ], + [ 'Apple', 89, 78 ] + ], + column_name: [ 'A', 'B', 'C' ], + data_tensors: { + Pear: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + '$index': [Array], + '$dtypes': [Array], + '$columns': [Array] + }, + Apple: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + ... + '$columns': [Array] + } + }, + col_dtype: [ 'string' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: + +1. [count](danfo.dataframe.count.md) +2. [sum](danfo.dataframe.sum.md) +3. [std](danfo.dataframe.std.md) +4. [var](danfo.dataframe.var.md) +5. [mean](danfo.dataframe.mean.md) +6. [cumsum](danfo.dataframe.cumsum.md) +7. [cummax](danfo.dataframe.cummax.md) +8. [cumprod](danfo.dataframe.cumprod.md) +9. [cummin](danfo.dataframe.cummin.md) +10. [max](danfo.dataframe.max.md) +11. [min](danfo.dataframe.min.md) + +## Example of Groupby and apply a sum function + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]).sum() + +group_df.print() + +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B_sum │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 119 │ 118 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +## **Groupby a two columns from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A", "B"]).sum() + +group_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 2 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Apple │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md b/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md new file mode 100644 index 0000000..121c7e7 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md @@ -0,0 +1,191 @@ +--- +description: Get Greater than of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.gt + +danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.gt(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.gt(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.gt(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.gt(val, axis=1) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.head.md b/api-reference-v1-stable/dataframe/danfo.dataframe.head.md new file mode 100644 index 0000000..10ae0f2 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.head.md @@ -0,0 +1,53 @@ +--- +description: Returns the first n rows of the DataFrame based on position. +--- + +# DataFrame.head + +danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let s_df = df.head(2) +s_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md new file mode 100644 index 0000000..f8e0f4c --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md @@ -0,0 +1,331 @@ +--- +description: Purely integer-location based indexing for selection by position. +--- + +# DataFrame.iloc + +danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). + +Allowed inputs are: + +* An integer, e.g. `5`. +* A list or array of integers, e.g. `[4, 3, 0]`. +* A string slice object with ints, e.g. `"1:7"` +* A boolean array. + +_**Note:** only the start index is included._ + +`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. + +### **Indexing specific rows by index and return all columns** + +If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: [0,1,3]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row and return all columns** + +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: ["1:3"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of column and return all rows** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({columns: ["1:"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Indexing both axes by the specified index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: [0,3], columns: [1,2]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after indexing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Indexing both axes by slices + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +╔═══╤═══════════════════╗ +║ │ Count ║ +╟───┼───────────────────╢ +║ 2 │ 30 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### More default slicing behavior + +If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md new file mode 100644 index 0000000..b919db5 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md @@ -0,0 +1,54 @@ +--- +description: >- + Return a boolean same-sized object indicating if the values are NaN. + NaN/undefined values gets mapped to true values, and everything else gets + mapped to false values. +--- + +# DataFrame.isna + +danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.isna().print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ false │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ true │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ true │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ false │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.it.md b/api-reference-v1-stable/dataframe/danfo.dataframe.it.md new file mode 100644 index 0000000..69093a2 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.it.md @@ -0,0 +1,194 @@ +--- +description: Get Less than of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.It + +danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.lt(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10, 40]) + +let df_rep = df.lt(sf, { axis: 1 }) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.lt(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with an Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.lt(val, axis=1) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.le.md b/api-reference-v1-stable/dataframe/danfo.dataframe.le.md new file mode 100644 index 0000000..0b88ff1 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.le.md @@ -0,0 +1,194 @@ +--- +description: >- + Get Less than or Equal to of DataFrame and other, element-wise (binary + operator eq). +--- + +# DataFrame.le + +danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) + +let df_rep = df.le(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.le(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.le(df2) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with an Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.le(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md new file mode 100644 index 0000000..88d7556 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md @@ -0,0 +1,367 @@ +--- +description: Access a group of rows and columns by label(s) +--- + +# DataFrame.loc + +danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | +| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +`.loc()` is label position based-from `0` to `length-1` of the row axis. + +Allowed inputs for are: + +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` + +_**Note: **only** **the start label is included, and the end label is ignored. _ + +`.loc` will raise a `ValueEror` if a requested label is not found. + +### **Index by specific rows and return all columns** + +If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.print() +let sub_df = df.loc({rows: ["a", "c"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a list of column names and return all rows** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.print() +let sub_df = df.loc({columns: ["Count", "Price"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after indexing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ a │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ b │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ c │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ d │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Index both axes by the specified labels + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +df.print() +let sub_df = df.loc({ rows: ["c","d"], columns: ["Name", "Price"] }) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//after slicing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ c │ Banana │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ d │ Pear │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +df.print() +let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +df`.loc({ row: [a:e]}).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +df``.loc({ row: [`"a":"e"`]}).print()``\ +\ +_**Inner**_ _**quotes are not needed for numeric indices!**_ +{% endhint %} + +### Slice DataFrame rows by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let sub_df = df.loc({ rows: df["Count"].gt(6) }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + +### Slice DataFrame rows by multiple boolean conditions + +{% hint style="info" %} +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let condition = df["Count"].gt(6).and(df["Price"].lt(250)) +let sub_df = df.loc({ rows: condition }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +### Slice DataFrame with boolean mask + +{% hint style="info" %} +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) + +let sub_df = df.loc({ rows: [false, true, true, true] }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.max.md b/api-reference-v1-stable/dataframe/danfo.dataframe.max.md new file mode 100644 index 0000000..f8e9124 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.max.md @@ -0,0 +1,118 @@ +--- +description: Return the maximum of the values for the requested axis. +--- + +# DataFrame.max + +danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Return the maximum value along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.max().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 11 ║ +╟───┼──────────────────────╢ +║ B │ 89 ║ +╟───┼──────────────────────╢ +║ C │ 78 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Return the maximum value along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.max({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 20 ║ +╟───┼──────────────────────╢ +║ 1 │ 15 ║ +╟───┼──────────────────────╢ +║ 2 │ 40 ║ +╟───┼──────────────────────╢ +║ 3 │ 89 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md new file mode 100644 index 0000000..fbc005e --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md @@ -0,0 +1,120 @@ +--- +description: Return the mean of the values for the requested axis. +--- + +# DataFrame.mean + +danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Computes the mean of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.mean().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 4 ║ +╟───┼──────────────────────╢ +║ B │ 38.5 ║ +╟───┼──────────────────────╢ +║ C │ 31.75 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Computes the mean of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.mean({ axis: 0 }).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 11.333333015441895 ║ +╟───┼──────────────────────╢ +║ 1 │ 7.333333492279053 ║ +╟───┼──────────────────────╢ +║ 2 │ 24 ║ +╟───┼──────────────────────╢ +║ 3 │ 56.33333206176758 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.median.md b/api-reference-v1-stable/dataframe/danfo.dataframe.median.md new file mode 100644 index 0000000..e75519f --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.median.md @@ -0,0 +1,120 @@ +--- +description: Return the median of the values for the requested axis. +--- + +# DataFrame.median + +danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Calculates the median of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.median().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 2 ║ +╟───┼──────────────────────╢ +║ B │ 25 ║ +╟───┼──────────────────────╢ +║ C │ 23 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculates the median of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.median({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 11 ║ +╟───┼──────────────────────╢ +║ 1 │ 6 ║ +╟───┼──────────────────────╢ +║ 2 │ 30 ║ +╟───┼──────────────────────╢ +║ 3 │ 78 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.min.md b/api-reference-v1-stable/dataframe/danfo.dataframe.min.md new file mode 100644 index 0000000..93b9bf8 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.min.md @@ -0,0 +1,120 @@ +--- +description: Return the minimum of the values for the requested axis. +--- + +# DataFrame.min + +danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Returns the minimum value along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.min().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 1 ║ +╟───┼──────────────────────╢ +║ B │ 15 ║ +╟───┼──────────────────────╢ +║ C │ 3 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Return the minimum value along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.min({axis: 0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md new file mode 100644 index 0000000..8cd7e9f --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md @@ -0,0 +1,258 @@ +--- +description: Get Modulo of DataFrame and other, element-wise (binary operator mod). +--- + +# DataFrame.mod + +danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Modulo of** scalar with **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.mod(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of** Series with **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.mod(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 4 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.mod(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 5 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of** ** Array with DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.mod(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Modulo works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.mod(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md new file mode 100644 index 0000000..3627b59 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md @@ -0,0 +1,252 @@ +--- +description: Get Multiplication of dataframe and other, element-wise (binary operator mul). +--- + +# DataFrame.mul + +danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Multiplication of** scalar to **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.mul(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Multiplication of** Series to **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.mul(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 4 │ 15 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 16 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 4 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Multiplication of** **DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.mul(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 100 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 8 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Multiplication of** ** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.mul(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Multiplication works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.mul(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md new file mode 100644 index 0000000..1996400 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md @@ -0,0 +1,187 @@ +--- +description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.ne + +danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +**** + +## **Examples** + +### Comparing** **DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.ne(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.ne(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.ne(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing** **DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10, 40, 30, 20] + +let df_rep = df.le(val) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ true │ false │ false │ true ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ false │ true │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md b/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md new file mode 100644 index 0000000..634e6e2 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md @@ -0,0 +1,260 @@ +--- +description: >- + Get Exponential power of dataframe and other, element-wise (binary operator + pow). +--- + +# DataFrame.pow + +danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Exponential of** scalar with **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.pow(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of** Series with **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.pow(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 243 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 256 │ 32 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 625 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 1024 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of** **DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.pow(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 1048576 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1024 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 95367433551872 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 16 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of** ** Array with DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.pow(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Exponential works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.pow(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.query.md b/api-reference-v1-stable/dataframe/danfo.dataframe.query.md new file mode 100644 index 0000000..129c8e7 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.query.md @@ -0,0 +1,278 @@ +--- +description: >- + Query the DataFrame by the result of a logical comparison or boolean mask. + Supports logical operations like (">", "<", ">=", "<=", and. "==") +--- + +# DataFrame.query + +danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | + +**Returns:** + + **** return **new DataFrame** + +## **Examples** + +## **Query a DataFrame using a boolean mask** + +{% hint style="info" %} +Querying by a boolean condition is supported from v0.3.0 and above. +{% endhint %} + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5) }) +query_df.print() //after query +``` + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + +## **Query a DataFrame using logical operators** + +To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() //before query + +let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) +query_df.print() //after query +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//before query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) +query_df.print() //after query + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Query by a string column in a DataFrame** + +The query method also works on string columns. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +query_df.print() //after query + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Query a DataFrame inplace** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.query({ + column: "B", + is: ">", + to: 5, + inplace: true +}) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md b/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md new file mode 100644 index 0000000..9a0b39f --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md @@ -0,0 +1,102 @@ +--- +description: Replaces values in a DataFrame with specified values +--- + +# DataFrame.replace + +> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| oldValue | String, boolean, Number | The value you want to replace | | +| newValue | String, boolean, Number | The new value you want to replace the old value with | | +| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | + +**Returns:** + +** **return** DataFrame** + +**** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_rep = df.replace(10, -999, { columns: ["Col1"] }) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ -999 │ 23 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 45 │ 20 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 56 │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ -999 │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +By not specifying a** **column**, **the** **replace works on all columns ** ** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] +let df = new dfd.DataFrame(data) +//replace value in all column +let df_rep = df.replace("A", "BOY") + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ BOY │ BOY │ BOY │ B ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ B │ C │ C │ D ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.round.md b/api-reference-v1-stable/dataframe/danfo.dataframe.round.md new file mode 100644 index 0000000..32e7c8a --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.round.md @@ -0,0 +1,128 @@ +--- +description: Round elements in a DataFrame to a specified number of decimal places. +--- + +# DataFrame.round + +danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +## Round elements to 1dp (Default) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() + +let new_df = df.round() + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.234 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after round + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1 │ 3.6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.1 │ 40.2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Round elements to a specified number of decimal places + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() + +let new_df = df.round(2) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.234 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after round operation + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.12 │ 3.57 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.23 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md new file mode 100644 index 0000000..73e057a --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md @@ -0,0 +1,112 @@ +--- +description: Return a random sample of rows from DataFrame. +--- + +# DataFrame.sample + +danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | +| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | +| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | + +**Returns:** + +** **return** {Promies} resolves to DataFrame** + +**** + +## Sample a DataFrame randomly + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(2); + s_df.print(); + +} + +load_data() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Sample a DataFrame randomly with seed + +By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(3, { seed: 2 }); + s_df.print(); + +} + +load_data() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.std.md b/api-reference-v1-stable/dataframe/danfo.dataframe.std.md new file mode 100644 index 0000000..b94372e --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.std.md @@ -0,0 +1,94 @@ +--- +description: Return sample standard deviation over requested axis. +--- + +# DataFrame.std + +danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Calculates the standard deviation of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.std().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4.69041575982343 ║ +╟───┼──────────────────────╢ +║ 1 │ 34.23935357645254 ║ +╟───┼──────────────────────╢ +║ 2 │ 35.103418636936205 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculates the standard deviation of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.std({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 8.504900548115383 ║ +╟───┼──────────────────────╢ +║ 1 │ 7.094598884597588 ║ +╟───┼──────────────────────╢ +║ 2 │ 19.697715603592208 ║ +╟───┼──────────────────────╢ +║ 3 │ 47.37439533475159 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md new file mode 100644 index 0000000..aded5cb --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md @@ -0,0 +1,250 @@ +--- +description: Get Subtraction of dataframe and other, element-wise (binary operator sub). +--- + +# DataFrame.sub + +danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Subtraction of** scalar to **DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.sub(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Subtraction of** Series to **DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.sub(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ -3 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ -3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ -5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -3 │ -1 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Subtraction of** **DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.sub(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ -18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ -1 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ -15 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -10 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Subtraction of** ** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.sub(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Subtraction works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.sub(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md new file mode 100644 index 0000000..515788b --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md @@ -0,0 +1,121 @@ +--- +description: Return the sum of the values for the requested axis. +--- + +# DataFrame.sum + +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Sum elements along default axis (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +df.print() + +let df_sum = df.sum() +df_sum.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════════════════════╗ +║ A │ 37.199999999999996 ║ +╟───┼────────────────────╢ +║ B │ 41 ║ +╟───┼────────────────────╢ +║ C │ -10 ║ +╚═══╧════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Sum elements along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +df.print() + +let df_sum = df.sum({axis: 0}) +df_sum.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ sum ║ +╟───┼──────────────────────╢ +║ 0 │ 33.9 ║ +╟───┼──────────────────────╢ +║ 1 │ 6 ║ +╟───┼──────────────────────╢ +║ 2 │ 82.3 ║ +╟───┼──────────────────────╢ +║ 3 │ -54 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md b/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md new file mode 100644 index 0000000..f317ba2 --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md @@ -0,0 +1,53 @@ +--- +description: Returns the last n rows from the DataFrame based on position. +--- + +# DataFrame.tail + +danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let s_df = df.tail(3) +s_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.var.md b/api-reference-v1-stable/dataframe/danfo.dataframe.var.md new file mode 100644 index 0000000..b95bb1a --- /dev/null +++ b/api-reference-v1-stable/dataframe/danfo.dataframe.var.md @@ -0,0 +1,94 @@ +--- +description: Return unbiased variance over requested axis. +--- + +# DataFrame.var + +danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + +** **return** Series** + +## **Examples** + +## Calculate variance of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.var().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 22 ║ +╟───┼──────────────────────╢ +║ 1 │ 1172.3333333333333 ║ +╟───┼──────────────────────╢ +║ 2 │ 1232.25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculate variance of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.var({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 72.33333333333334 ║ +╟───┼──────────────────────╢ +║ 1 │ 50.33333333333333 ║ +╟───┼──────────────────────╢ +║ 2 │ 388 ║ +╟───┼──────────────────────╢ +║ 3 │ 2244.333333333333 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference-v1-stable/dataframe/dataframe.append.md b/api-reference-v1-stable/dataframe/dataframe.append.md new file mode 100644 index 0000000..ae84a8b --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.append.md @@ -0,0 +1,75 @@ +--- +description: Adds new row to the end of a DataFrame +--- +# DataFrame.append + +danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] + +| Parameters | Type | Description | Default | +| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | +| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | +| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Appends a new row to the end of a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = [[0, 2, 4, "b"], + [360, 180, 360, "a"], + [2, 4, 6, "c"]] + +let df = new dfd.DataFrame(data) +df.print() + +let new_df = df.append([[20, 40, 60, "d"]], [3]) +new_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 4 │ 6 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 4 │ 6 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 40 │ 60 │ d ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/dataframe/dataframe.apply_map.md b/api-reference-v1-stable/dataframe/dataframe.apply_map.md new file mode 100644 index 0000000..986566f --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.apply_map.md @@ -0,0 +1,68 @@ +--- +description: Apply a function to a Dataframe values element-wise. +--- + +# DataFrame.apply_map + +danfo.DataFrame.**apply_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Apply a function to all values in a DataFrame + +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + short_name: ["NG", "GH", "EGY", "SA"], + long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] +} +let df = new dfd.DataFrame(data) + +function lower(x) { + return `${x}`.toLowerCase() +} + +let df_new = df.apply_map(lower) +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ short_name │ long_name ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ ng │ nigeria ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ gh │ ghana ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ egy │ eqypt ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ sa │ south africa ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.astype.md b/api-reference-v1-stable/dataframe/dataframe.astype.md new file mode 100644 index 0000000..fb388a3 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.astype.md @@ -0,0 +1,222 @@ +--- +description: Cast column of a DataFrame to a specified dtype. +--- + +# DataFrame.astype + +danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Cast a float dtype column to int** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.print() +df.ctypes.print() + +let df_new = df.astype({column: "A", dtype: "int32"}) +df_new.print() + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//before casting +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ + + + //after casting + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20.1 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47 │ 5 │ 30.3 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ int32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Casting a string column of numbers to int** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["20", "13", "45", "90"] } + +let df = new dfd.DataFrame(data) +let df_new = df.astype({column: "D", dtype: "int32"}) +df_new.print() + +df_new.ctypes.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ 13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ 45 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +**Note: **Casting a string column of alphabets/words to numeric form will return NaNs as values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +let df_new = df.astype({column: "D", dtype: "int32"}) +df_new.print() + +df_new.ctypes.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.axes.md b/api-reference-v1-stable/dataframe/dataframe.axes.md new file mode 100644 index 0000000..4bdc319 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.axes.md @@ -0,0 +1,47 @@ +--- +description: >- + Return an Object containing the axes of the DataFrame. It has the row axis + labels and column axis labels as the only members. They are returned in that + order. +--- + +# DataFrame.axes + +danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + +** **return** Object** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) + +console.log(df.axis) + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +{ index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.drop.md b/api-reference-v1-stable/dataframe/dataframe.drop.md new file mode 100644 index 0000000..2376308 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.drop.md @@ -0,0 +1,143 @@ +--- +description: >- + Drop specified labels from rows or columns.Remove rows or columns by + specifying label names and corresponding axis. +--- + +# DataFrame.drop + +danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Drop columns by specifying the names + +By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.drop({ columns: ["C", "B"], inplace: true }); +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ D ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ a ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ b ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ c ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ c ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop rows by specifying int labels/index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] +} + +let df = new dfd.DataFrame(data) +df.drop({ index: [0, 2], inplace: true }); +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 30 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop rows by specifying string labels/index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.drop({ index: ["a", "c"], inplace: true }); +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -4 │ 20 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ -20 │ 6 │ 30 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.dtypes.md b/api-reference-v1-stable/dataframe/dataframe.dtypes.md new file mode 100644 index 0000000..6e856d5 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.dtypes.md @@ -0,0 +1,100 @@ +--- +description: >- + Return the inferred column types in the DataFrame. This returns a Series with + the data type of each column. The result’s index is the original DataFrame’s + columns. +--- + +# DataFrame.ctypes + +danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] + +**Returns:** + +** **return** Series** + +## **Examples** + +Returns auto-generated** **index of a** **DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Columns with mixed types are represented as **string.** + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40], + "D": ["a", "b", 20, 2.5]} + +let df = new dfd.DataFrame(data) + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference-v1-stable/dataframe/dataframe.index.md b/api-reference-v1-stable/dataframe/dataframe.index.md new file mode 100644 index 0000000..0983db8 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.index.md @@ -0,0 +1,69 @@ +--- +description: The index (row labels) of the DataFrame. +--- + +# DataFrame.index + +danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] + +## **Examples** + +Returns auto-generated** **index of a** **DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +console.log(df.index); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[0, 1, 2, 3] +``` +{% endtab %} +{% endtabs %} + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data, {index: ["r1", "r2", "r3", "r4"]) + +console.log(df.index); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ 'r1', 'r2', 'r3', 'r4' ] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.ndim.md b/api-reference-v1-stable/dataframe/dataframe.ndim.md new file mode 100644 index 0000000..002da15 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.ndim.md @@ -0,0 +1,46 @@ +--- +description: >- + Return an int representing the number of axes / array dimensions. Returns 1 if + Series. Otherwise return 2 for DataFrame. +--- + +# DataFrame.ndim + +danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + +** **return** Int** + +**Note:** To get the **shape **of the DataFrame use the .[shape](dataframe.shape.md) property. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +console.log(df.ndim) + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +2 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.nunique-1.md b/api-reference-v1-stable/dataframe/dataframe.nunique-1.md new file mode 100644 index 0000000..f06d4ed --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.nunique-1.md @@ -0,0 +1,98 @@ +# DataFrame.nunique + +danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | -------------------------------------- | ------- | +| axis | Int | 0 for row axis, and 1 for column axis | 1 | + +**Returns:** + +** **return** Series** + +## **Examples** + +### Return number of unique values along column axis (axis=1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.nunique().print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 4 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} + +### Return number of unique values in row axis (axis=0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.nunique(axis=0).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note: **To get the unique elements along an axis, use** **[DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference-v1-stable/dataframe/dataframe.print.md b/api-reference-v1-stable/dataframe/dataframe.print.md new file mode 100644 index 0000000..d03232d --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.print.md @@ -0,0 +1,105 @@ +--- +description: >- + Pretty prints default (10) number of rows in a DataFrame or Series to the + console +--- + +# DataFrame.print + +danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 4, 5] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Abs │ Count │ country code ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.2 │ 34 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 4 │ FR ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ GH ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Using JavaScript default **console.log** to display a DataFrame will return the Object instead unless you manually cast it to a String + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 4, 5, 6] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +console.log(df) +console.log(String(df)); +// console.log(df + ""); //same result as above +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +DataFrame { + '$isSeries': false, + '$config': Configs { + tableDisplayConfig: {}, + tableMaxRow: 10, + tableMaxColInConsole: 21, + dtypeTestLim: 7, + lowMemoryMode: false + }, + '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], + '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], + '$index': [ 0, 1, 2 ], + '$dtypes': [ 'float32', 'int32', 'string' ], + '$columns': [ 'Abs', 'Count', 'country code' ] +} +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Abs │ Count │ country code ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.2 │ 34 │ NG ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ FR ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ GH ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.rename.md b/api-reference-v1-stable/dataframe/dataframe.rename.md new file mode 100644 index 0000000..6625bc1 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.rename.md @@ -0,0 +1,148 @@ +--- +description: >- + Change axes labels. Object values must be unique (1-to-1). Labels not + contained in a dict / Series will be left as-is. Extra labels listed don’t + throw an error. +--- + +# DataFrame.rename + +danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | +| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### Rename columns + +By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -4, 5], + "C": [20, 2, 30] } + + +let df = new dfd.DataFrame(data) +df.rename({ mapper: {"A": "new_name"},inplace: true }) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ new_name │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Rename more the one column at time + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -4, 6], + "C": [20, 2, 30] } + + +let df = new dfd.DataFrame(data) +df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ new_name │ B │ new_c ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Rename index by labels + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3], + "B": [34, -4, 6], + "C": [20, 2, 30] +} + + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) +df = df.rename({ mapper: { "a": 0 }, axis: 0 }) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.reset_index.md b/api-reference-v1-stable/dataframe/dataframe.reset_index.md new file mode 100644 index 0000000..00239fc --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.reset_index.md @@ -0,0 +1,73 @@ +--- +description: Reset the index of the DataFrame, and use the default one instead. +--- + +# DataFrame.reset_index + +danfo.DataFrame.**reset_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] +} + + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) +df.print() + +df.reset_index({ inplace: true }) //inplace +//df = df.reset_index() //not in inplace + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md b/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md new file mode 100644 index 0000000..127b433 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md @@ -0,0 +1,94 @@ +--- +description: Return a subset of the DataFrame’s columns based on the column dtypes. +--- + +# DataFrame.select_dtypes + +danfo.DataFrame.**select_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] + +| Parameters | Type | Description | Default | +| ---------- | ----- | -------------------------------- | ------- | +| include | Array | List of column dtypes to return | | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40], + "D": ["a", "b", 20, 2.5]} + +let df = new dfd.DataFrame(data) + +float_df = df.select_dtypes(['float32']) +float_df.print() + +mix_df = df.select_dtypes(include=['float32', "int32"]) +mix_df.print() + +str_df = df.select_dtypes(include=['string']) +str_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//select float column(s) +╔═══╤══════════════════════╗ +║ │ A ║ +╟───┼──────────────────────╢ +║ 0 │ -20.1 ║ +╟───┼──────────────────────╢ +║ 1 │ 30 ║ +╟───┼──────────────────────╢ +║ 2 │ 47.3 ║ +╟───┼──────────────────────╢ +║ 3 │ -20 ║ +╚═══╧══════════════════════╝ + + + //select both float and int columns + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//return string type column +╔═══╤══════════════════════╗ +║ │ D ║ +╟───┼──────────────────────╢ +║ 0 │ a ║ +╟───┼──────────────────────╢ +║ 1 │ b ║ +╟───┼──────────────────────╢ +║ 2 │ 20 ║ +╟───┼──────────────────────╢ +║ 3 │ 2.5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.set_index.md b/api-reference-v1-stable/dataframe/dataframe.set_index.md new file mode 100644 index 0000000..e82c213 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.set_index.md @@ -0,0 +1,176 @@ +--- +description: >- + Set the DataFrame index using existing columns or an array (of the equal + length). +--- + +# DataFrame.set_index + +danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | + +## **Examples** + +### **Setting index to a column in the DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) +df.print() + +df.set_index({column: "A", inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ -20 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 30 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **** + +### **Setting index to a column in the DataFrame and dropping the column** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) +df.print() + +df.set_index({column: "A", drop: true, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ B │ C ║ +╟────────────┼───────────────────┼───────────────────╢ +║ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Set index to an array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.print() + +let new_index = ["a", "b", "c"] +df.set_index({index: new_index, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). diff --git a/api-reference-v1-stable/dataframe/dataframe.shape.md b/api-reference-v1-stable/dataframe/dataframe.shape.md new file mode 100644 index 0000000..3e8486f --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.shape.md @@ -0,0 +1,43 @@ +--- +description: Returns an Array representing the dimensionality of the DataFrame. +--- + +# DataFrame.shape + +danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + +** **return** Int** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) + +console.log(df.shape) + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[4,3] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_index.md b/api-reference-v1-stable/dataframe/dataframe.sort_index.md new file mode 100644 index 0000000..0829afe --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.sort_index.md @@ -0,0 +1,73 @@ +--- +description: Sort DataFrame by index +--- +# DataFrame.sort_index + +DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Sort DataFrame by a column in ascending order** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[0, 2, 4, "b"], + [360, 180, 360, "a"], + [2, 4, 6, "c"]] + +let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], + index: ["b", "a", "c"] }) +df.print() + +let df2 = df.sort_index({ ascending: false }) +df2.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 2 │ 4 │ 6 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after sorting in descending order + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 2 │ 4 │ 6 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 360 │ 180 │ 360 │ a ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_values.md b/api-reference-v1-stable/dataframe/dataframe.sort_values.md new file mode 100644 index 0000000..8da51fe --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.sort_values.md @@ -0,0 +1,99 @@ +--- +description: Sort a Dataframe in ascending or descending order by a specified column name. +--- + +# DataFrame.sort_values + +danfo.DataFrame.**sort_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Sort DataFrame by a column in ascending order** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.sort_values({by: "C", inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Sort DataFrame by a column in descending order** + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.sort_values({by: "B", inplace: true, ascending: false}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.tensor.md b/api-reference-v1-stable/dataframe/dataframe.tensor.md new file mode 100644 index 0000000..125198f --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.tensor.md @@ -0,0 +1,107 @@ +--- +description: Return a Tensorflow tensor representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. +--- +# DataFrame.tensor + +danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + +** **return** tf.tensor** + +> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30]} + +let df = new dfd.DataFrame(data) +let tf_tensor = df.tensor + +console.log(tf_tensor.dtype); + +console.log(tf_tensor); + +tf_tensor.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 +Tensor + [[-20 , 34, 20], + [30 , -4, 20], + [47.2999992, 5 , 30], + [-20 , 6 , 30]] +``` +{% endtab %} +{% endtabs %} + +String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 5, 6] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +let tf_tensor = df.tensor + +console.log(tf_tensor.dtype); + +console.log(tf_tensor); + +tf_tensor.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 + +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 3, 3 ], + dtype: 'float32', + size: 9, + strides: [ 3 ], + dataId: {}, + id: 0, + rankType: '2' +} + +Tensor + [[20.2000008, 34, NaN], + [30 , 4 , NaN], + [47.2999992, 5 , NaN]] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.to_csv.md b/api-reference-v1-stable/dataframe/dataframe.to_csv.md new file mode 100644 index 0000000..ee31a5e --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.to_csv.md @@ -0,0 +1,114 @@ +--- +description: Convert DataFrame data to a comma-separated values (csv) +--- +# DataFrame.to_csv + +DataFrame.**to_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +**** + +### Convert DataFrame to CSV string and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const csv = df.to_csv({ download: false }); +console.log(csv); + +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ filePath: "testOut.csv"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and download file in browser + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ fileName: "testOut.csv", download: true}); +``` + diff --git a/api-reference-v1-stable/dataframe/dataframe.to_excel.md b/api-reference-v1-stable/dataframe/dataframe.to_excel.md new file mode 100644 index 0000000..4adf437 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.to_excel.md @@ -0,0 +1,53 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# DataFrame.to_excel + +> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| + +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in a browser + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ fileName: "testOut.xlsx"}); +``` diff --git a/api-reference-v1-stable/dataframe/dataframe.to_json.md b/api-reference-v1-stable/dataframe/dataframe.to_json.md new file mode 100644 index 0000000..59f7e34 --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.to_json.md @@ -0,0 +1,126 @@ +--- +description: Convert DataFrame to JSON format +--- +# DataFrame.to_json + +> DataFrame.**to_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. + +### Convert DataFrame/Series to JSON and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = df.to_json({ download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = df.to_json({ + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ filePath: "./testOutput.json" }); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ fileName: "test_out.json" }); +``` diff --git a/api-reference-v1-stable/dataframe/dataframe.values.md b/api-reference-v1-stable/dataframe/dataframe.values.md new file mode 100644 index 0000000..6b7ea1d --- /dev/null +++ b/api-reference-v1-stable/dataframe/dataframe.values.md @@ -0,0 +1,50 @@ +--- +description: Return a the JavaScript array representation of the DataFrame. +--- + +# DataFrame.values + +danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + +** **return** Array** + +**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +console.log(df.values) + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + [ -20.1, 34, 20 ], + [ 30, -4, -20 ], + [ 47.3, 5, 30 ], + [ -20, 6, -40 ] +] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/general-functions/README.md b/api-reference-v1-stable/general-functions/README.md new file mode 100644 index 0000000..07815b0 --- /dev/null +++ b/api-reference-v1-stable/general-functions/README.md @@ -0,0 +1,27 @@ +--- +description: Top level functions that can be called from the Danfo namespace +--- + +# General Functions + +### Data manipulations + +| | | +| ------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | +| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | +| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | + +### Data Processing/Normalization + +| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | +| ----------------------------------------- | ---------------------------------------------------------------------- | +| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | +| [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | +| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | + +### Top-level dealing with datetime + +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| ------------------------------------ | --------------------------------------- | +| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference-v1-stable/general-functions/danfo.concat.md b/api-reference-v1-stable/general-functions/danfo.concat.md new file mode 100644 index 0000000..19c3d8e --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.concat.md @@ -0,0 +1,187 @@ +--- +description: Concatenate DataFrames and Series along an axis +--- + +# danfo.concat + +danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | +| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Concatenate two DataFrames along column axis (1) ** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) +com_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Concatenate two DataFrames along row axis (0) ** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +com_df.print(10) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Concatenate two Series along row axis (0) ** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +com_df.print(10) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. diff --git a/api-reference-v1-stable/general-functions/danfo.date_range.md b/api-reference-v1-stable/general-functions/danfo.date_range.md new file mode 100644 index 0000000..32d18b8 --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.date_range.md @@ -0,0 +1,111 @@ +--- +description: Return a fixed frequency Dates spread between start and end parameters. +--- + +# danfo.date_range + +danfo.**date_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) +console.log(data); +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + '1/1/2018, 12:00:00 AM', + '2/1/2018, 12:00:00 AM', + '3/1/2018, 12:00:00 AM', + '4/1/2018, 12:00:00 AM', + '5/1/2018, 12:00:00 AM' +] +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) +console.log(data); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + '1/1/2018, 12:00:00 AM', + '1/1/2019, 12:00:00 AM', + '1/1/2020, 12:00:00 AM', + '1/1/2021, 12:00:00 AM', + '1/1/2022, 12:00:00 AM', + '1/1/2023, 12:00:00 AM', + '1/1/2024, 12:00:00 AM', + '1/1/2025, 12:00:00 AM', + '1/1/2026, 12:00:00 AM', + '1/1/2027, 12:00:00 AM', + '1/1/2028, 12:00:00 AM', + '1/1/2029, 12:00:00 AM' +] +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.get_dummies.md b/api-reference-v1-stable/general-functions/danfo.get_dummies.md new file mode 100644 index 0000000..793aa58 --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.get_dummies.md @@ -0,0 +1,188 @@ +--- +description: Convert categorical variable into dummy/indicator variables. +--- + +# danfo.get_dummies + +danfo.**get_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| data | Series or Dataframe | The data to dummify | | +| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +### **Convert Series to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] +let sf1 = new dfd.Series(datasf) + +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Convert all categorical columns in a DataFrame to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + +let df = new dfd.DataFrame(data) +df.print() + +let dum_df = dfd.get_dummies(df) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruits │ Count │ Country ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ pear │ 20 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ mango │ 30 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ pawpaw │ 89 │ GH ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ mango │ 12 │ RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bean │ 30 │ RU ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after dummification + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Count │ fruits_pear │ fruits_mango │ ... │ fruits_bean │ Country_NG │ Country_GH │ Country_RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 1 │ 0 │ ... │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 0 │ 1 │ ... │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 89 │ 0 │ 0 │ ... │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 0 │ 1 │ ... │ 0 │ 0 │ 0 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 30 │ 0 │ 0 │ ... │ 1 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Convert a specific column in a DataFrame to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + +let df = new dfd.DataFrame(data) +df.print() + +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruits │ Count │ Country ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ pear │ 20 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ mango │ 30 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ pawpaw │ 89 │ GH ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ mango │ 12 │ RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bean │ 30 │ RU ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after dummification + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Count │ Country │ fruits_pear │ fruits_mango │ fruits_pawpaw │ fruits_bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ NG │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ NG │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 89 │ GH │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ RU │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 30 │ RU │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) +{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.labelencoder.md b/api-reference-v1-stable/general-functions/danfo.labelencoder.md new file mode 100644 index 0000000..12d57ee --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.labelencoder.md @@ -0,0 +1,140 @@ +--- +description: Encode target labels with value between 0 and n_classes-1. +--- + +# danfo.LabelEncoder + +class danfo.**LabelEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. + +The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. + +## **Examples** + +### **Label Encode values in a Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = ["dog","cat","man","dog","cat","man","man","cat"] +let series = new dfd.Series(data) + +let encode = new dfd.LabelEncoder() + +encode.fit(series) +console.log(encode); + +let sf_enc = encode.transform(series.values) +sf_enc.print() + +let new_sf = encode.transform(["dog","man"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +LabelEncoder { label: [ 'dog', 'cat', 'man' ] } +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 1 ║ +╟───┼──────────────────────╢ +║ 5 │ 2 ║ +╟───┼──────────────────────╢ +║ 6 │ 2 ║ +╟───┼──────────────────────╢ +║ 7 │ 1 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +**Labels not found in the original data used for fitting are represented with -1** +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.LabelEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","man"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.merge.md b/api-reference-v1-stable/general-functions/danfo.merge.md new file mode 100644 index 0000000..82a9a3d --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.merge.md @@ -0,0 +1,453 @@ +--- +description: >- + Merge DataFrame or named Series objects with a database-style join.The join is + done on columns or indexes. +--- + +# danfo.merge + +danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | + +**Returns:** + +** **return** DataFrame** + +## **Examples** + +**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. + +danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. + +For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. + +### **Merging by a single key found in both axis** + +By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + + //first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //Second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After inner join on column 'Key1' + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### **Inner Join/Merge by multiple keys found in both axis** + +Merging by two keys takes into consideration the keys appearing in both`left` and `right DataFrame.` + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", 'Key2'], how: "inner"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After inner join on two keys + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent + +### Outer join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1"], how: "outer"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//First DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //Second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//After outer join + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Left join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", "Key2"], how: "left"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + After left join +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K2 │ K2 │ A3 │ B3 │ NaN │ NaN ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Right join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", "Key2"], how: "right"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//after right join + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ NaN │ NaN │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. +{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md b/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md new file mode 100644 index 0000000..06add63 --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md @@ -0,0 +1,125 @@ +--- +description: Transform features by scaling each feature to a range of max and min values. +--- + +# danfo.MinMaxScaler + +class danfo.**MinMaxScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. + +This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). + +The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. + +## **Examples** + +### Standardize DataFrame Object using MinMaxScaler + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let scaler = new dfd.MinMaxScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 20, 10], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +df.print() + +scaler.fit(df) + +let df_enc = scaler.transform(df) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 30 │ 20 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 1 │ 1 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 1 │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0.19191919267... │ 0.02902902849... │ 0.00950475223... │ 0.00333333341... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Standardize Series Object Using MinMaxScaler + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let scaler = new dfd.MinMaxScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 20, 10], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +let sf = df.iloc({columns: ["0"]}) + +scaler.fit(sf) + +let df_enc = scaler.transform(sf) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + + Shape: (3,1) + +╔═══╤═══════════════════╗ +║ │ 0 ║ +╟───┼───────────────────╢ +║ 0 │ 1 ║ +╟───┼───────────────────╢ +║ 1 │ 0.19191919267... ║ +╟───┼───────────────────╢ +║ 2 │ 0 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.onehotencoder.md b/api-reference-v1-stable/general-functions/danfo.onehotencoder.md new file mode 100644 index 0000000..fdb8d4a --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.onehotencoder.md @@ -0,0 +1,148 @@ +--- +description: Encode categorical features as a one-hot numeric array. +--- + +# danfo.OneHotEncoder + +class danfo.**OneHotEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] + +danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. + +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. + +## **Examples** + +### **Convert Series to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.OneHotEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","bean"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +**Labels not found in the original data used for fitting are represented with 0s all through** +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.OneHotEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","woman", "cup"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.standardscaler.md b/api-reference-v1-stable/general-functions/danfo.standardscaler.md new file mode 100644 index 0000000..298d86e --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.standardscaler.md @@ -0,0 +1,132 @@ +--- +description: Standardize features by removing the mean and scaling to unit variance. +--- + +# danfo.StandardScaler + +class danfo.**StandScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: + +> z = (x - u) / s + +where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. + +The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. + +## **Examples** + +### Standardize Series Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let scaler = new dfd.StandardScaler() + +let sf = new dfd.Series([100,1000,2000, 3000]) +sf.print() + +scaler.fit(sf) + +let sf_enc = scaler.transform(sf) +sf_enc.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 100 ║ +╟───┼──────────────────────╢ +║ 1 │ 1000 ║ +╟───┼──────────────────────╢ +║ 2 │ 2000 ║ +╟───┼──────────────────────╢ +║ 3 │ 3000 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1.1375757455825806 ║ +╟───┼──────────────────────╢ +║ 1 │ -0.4191068708896637 ║ +╟───┼──────────────────────╢ +║ 2 │ 0.37919193506240845 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.1774907112121582 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Standardize DataFrame Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let scaler = new dfd.StandardScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 89, 12], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +df.print() + +scaler.fit(df) + +let df_enc = scaler.transform(df) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 30 │ 20 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 1 │ 1 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.to_datetime.md b/api-reference-v1-stable/general-functions/danfo.to_datetime.md new file mode 100644 index 0000000..7012100 --- /dev/null +++ b/api-reference-v1-stable/general-functions/danfo.to_datetime.md @@ -0,0 +1,141 @@ +--- +description: Converts an array of Date time string to Date object. +--- + +# danfo.toDateTime + +danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | +| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +Converts a **Series** of Date strings to Date time and get time properties + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) +let sf = new dfd.Series(data) +sf.print() + +let dt = dfd.toDateTime(data) + +dt.month().print() +dt.month_name().print() +dt.weekdays().print() +dt.day().print() +dt.seconds().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + +//Int representation for month + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 + +//string representation for month +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec + +//string representation for day of the week +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + +//Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 + +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +{% endhint %} diff --git a/api-reference-v1-stable/groupby.md b/api-reference-v1-stable/groupby.md new file mode 100644 index 0000000..1db2e52 --- /dev/null +++ b/api-reference-v1-stable/groupby.md @@ -0,0 +1,122 @@ +--- +description: >- + GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby(), + danfo.Series.groupby() +--- + +# Groupby + +### Indexing, iteration + +| [`GroupBy.__iter__`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.__iter__.html#pandas.core.groupby.GroupBy.__iter__)\(\) | Groupby iterator. | +| :--- | :--- | +| [`GroupBy.groups`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups) | Dict {group name -> group labels}. | +| [`GroupBy.indices`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.indices.html#pandas.core.groupby.GroupBy.indices) | Dict {group name -> group indices}. | +| [`GroupBy.get_group`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.get_group.html#pandas.core.groupby.GroupBy.get_group)\(name\[, obj\]\) | Construct DataFrame from group with provided name. | + +| [`Grouper`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Grouper.html#pandas.Grouper)\(\*args, \*\*kwargs\) | A Grouper allows the user to specify a groupby instruction for an object. | +| :--- | :--- | + + +### Function application + +| [`GroupBy.apply`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.apply.html#pandas.core.groupby.GroupBy.apply)\(func, \*args, \*\*kwargs\) | Apply function func group-wise and combine the results together. | +| :--- | :--- | +| [`GroupBy.agg`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.agg.html#pandas.core.groupby.GroupBy.agg)\(func, \*args, \*\*kwargs\) | | +| [`SeriesGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.aggregate.html#pandas.core.groupby.SeriesGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | +| [`DataFrameGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html#pandas.core.groupby.DataFrameGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | +| [`SeriesGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.transform.html#pandas.core.groupby.SeriesGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed Series on each group and return a Series having the same indexes as the original object filled with the transformed values | +| [`DataFrameGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.transform.html#pandas.core.groupby.DataFrameGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed DataFrame on each group and return a DataFrame having the same indexes as the original object filled with the transformed values | +| [`GroupBy.pipe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pipe.html#pandas.core.groupby.GroupBy.pipe)\(func, \*args, \*\*kwargs\) | Apply a function func with arguments to this GroupBy object and return the function’s result. | + +### Computations / descriptive stats + +| [`GroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.all.html#pandas.core.groupby.GroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | +| :--- | :--- | +| [`GroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.any.html#pandas.core.groupby.GroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | +| [`GroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.bfill.html#pandas.core.groupby.GroupBy.bfill)\(\[limit\]\) | Backward fill the values. | +| [`GroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.backfill.html#pandas.core.groupby.GroupBy.backfill)\(\[limit\]\) | Backward fill the values. | +| [`GroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.count.html#pandas.core.groupby.GroupBy.count)\(\) | Compute count of group, excluding missing values. | +| [`GroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumcount.html#pandas.core.groupby.GroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | +| [`GroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummax.html#pandas.core.groupby.GroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | +| [`GroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummin.html#pandas.core.groupby.GroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | +| [`GroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumprod.html#pandas.core.groupby.GroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | +| [`GroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumsum.html#pandas.core.groupby.GroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | +| [`GroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ffill.html#pandas.core.groupby.GroupBy.ffill)\(\[limit\]\) | Forward fill the values. | +| [`GroupBy.first`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html#pandas.core.groupby.GroupBy.first)\(\[numeric\_only, min\_count\]\) | Compute first of group values. | +| [`GroupBy.head`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.head.html#pandas.core.groupby.GroupBy.head)\(\[n\]\) | Return first n rows of each group. | +| [`GroupBy.last`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html#pandas.core.groupby.GroupBy.last)\(\[numeric\_only, min\_count\]\) | Compute last of group values. | +| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max)\(\[numeric\_only, min\_count\]\) | Compute max of group values. | +| [`GroupBy.mean`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.mean.html#pandas.core.groupby.GroupBy.mean)\(\[numeric\_only\]\) | Compute mean of groups, excluding missing values. | +| [`GroupBy.median`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.median.html#pandas.core.groupby.GroupBy.median)\(\[numeric\_only\]\) | Compute median of groups, excluding missing values. | +| [`GroupBy.min`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.min.html#pandas.core.groupby.GroupBy.min)\(\[numeric\_only, min\_count\]\) | Compute min of group values. | +| [`GroupBy.ngroup`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ngroup.html#pandas.core.groupby.GroupBy.ngroup)\(\[ascending\]\) | Number each group from 0 to the number of groups - 1. | +| [`GroupBy.nth`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.nth.html#pandas.core.groupby.GroupBy.nth)\(n\[, dropna\]\) | Take the nth row from each group if n is an int, or a subset of rows if n is a list of ints. | +| [`GroupBy.ohlc`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ohlc.html#pandas.core.groupby.GroupBy.ohlc)\(\) | Compute open, high, low and close values of a group, excluding missing values. | +| [`GroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pad.html#pandas.core.groupby.GroupBy.pad)\(\[limit\]\) | Forward fill the values. | +| [`GroupBy.prod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.prod.html#pandas.core.groupby.GroupBy.prod)\(\[numeric\_only, min\_count\]\) | Compute prod of group values. | +| [`GroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html#pandas.core.groupby.GroupBy.rank)\(\[method, ascending, na\_option, …\]\) | Provide the rank of values within each group. | +| [`GroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pct_change.html#pandas.core.groupby.GroupBy.pct_change)\(\[periods, fill\_method, …\]\) | Calculate pct\_change of each value to previous entry in group. | +| [`GroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.size.html#pandas.core.groupby.GroupBy.size)\(\) | Compute group sizes. | +| [`GroupBy.sem`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sem.html#pandas.core.groupby.GroupBy.sem)\(\[ddof\]\) | Compute standard error of the mean of groups, excluding missing values. | +| [`GroupBy.std`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.std.html#pandas.core.groupby.GroupBy.std)\(\[ddof\]\) | Compute standard deviation of groups, excluding missing values. | +| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum)\(\[numeric\_only, min\_count\]\) | Compute sum of group values. | +| [`GroupBy.var`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.var.html#pandas.core.groupby.GroupBy.var)\(\[ddof\]\) | Compute variance of groups, excluding missing values. | +| [`GroupBy.tail`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.tail.html#pandas.core.groupby.GroupBy.tail)\(\[n\]\) | Return last n rows of each group. | + +The following methods are available in both `SeriesGroupBy` and `DataFrameGroupBy` objects, but may differ slightly, usually in that the `DataFrameGroupBy` version usually permits the specification of an axis argument, and often an argument indicating whether to restrict application to columns of a specific data type. + +| [`DataFrameGroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.all.html#pandas.core.groupby.DataFrameGroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | +| :--- | :--- | +| [`DataFrameGroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.any.html#pandas.core.groupby.DataFrameGroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | +| [`DataFrameGroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.backfill.html#pandas.core.groupby.DataFrameGroupBy.backfill)\(\[limit\]\) | Backward fill the values. | +| [`DataFrameGroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.bfill.html#pandas.core.groupby.DataFrameGroupBy.bfill)\(\[limit\]\) | Backward fill the values. | +| [`DataFrameGroupBy.corr`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corr.html#pandas.core.groupby.DataFrameGroupBy.corr) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrameGroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.count.html#pandas.core.groupby.DataFrameGroupBy.count)\(\) | Compute count of group, excluding missing values. | +| [`DataFrameGroupBy.cov`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cov.html#pandas.core.groupby.DataFrameGroupBy.cov) | Compute pairwise covariance of columns, excluding NA/null values. | +| [`DataFrameGroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumcount.html#pandas.core.groupby.DataFrameGroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | +| [`DataFrameGroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummax.html#pandas.core.groupby.DataFrameGroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | +| [`DataFrameGroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummin.html#pandas.core.groupby.DataFrameGroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | +| [`DataFrameGroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumprod.html#pandas.core.groupby.DataFrameGroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | +| [`DataFrameGroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumsum.html#pandas.core.groupby.DataFrameGroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | +| [`DataFrameGroupBy.describe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.describe.html#pandas.core.groupby.DataFrameGroupBy.describe)\(\*\*kwargs\) | Generate descriptive statistics. | +| [`DataFrameGroupBy.diff`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.diff.html#pandas.core.groupby.DataFrameGroupBy.diff) | First discrete difference of element. | +| [`DataFrameGroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.ffill.html#pandas.core.groupby.DataFrameGroupBy.ffill)\(\[limit\]\) | Forward fill the values. | +| [`DataFrameGroupBy.fillna`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.fillna.html#pandas.core.groupby.DataFrameGroupBy.fillna) | Fill NA/NaN values using the specified method. | +| [`DataFrameGroupBy.filter`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.filter.html#pandas.core.groupby.DataFrameGroupBy.filter)\(func\[, dropna\]\) | Return a copy of a DataFrame excluding filtered elements. | +| [`DataFrameGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.hist.html#pandas.core.groupby.DataFrameGroupBy.hist) | Make a histogram of the DataFrame’s. | +| [`DataFrameGroupBy.idxmax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmax.html#pandas.core.groupby.DataFrameGroupBy.idxmax) | Return index of first occurrence of maximum over requested axis. | +| [`DataFrameGroupBy.idxmin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmin.html#pandas.core.groupby.DataFrameGroupBy.idxmin) | Return index of first occurrence of minimum over requested axis. | +| [`DataFrameGroupBy.mad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.mad.html#pandas.core.groupby.DataFrameGroupBy.mad) | Return the mean absolute deviation of the values for the requested axis. | +| [`DataFrameGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.nunique.html#pandas.core.groupby.DataFrameGroupBy.nunique)\(\[dropna\]\) | Return DataFrame with counts of unique elements in each position. | +| [`DataFrameGroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pad.html#pandas.core.groupby.DataFrameGroupBy.pad)\(\[limit\]\) | Forward fill the values. | +| [`DataFrameGroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pct_change.html#pandas.core.groupby.DataFrameGroupBy.pct_change)\(\[periods, …\]\) | Calculate pct\_change of each value to previous entry in group. | +| [`DataFrameGroupBy.plot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.plot.html#pandas.core.groupby.DataFrameGroupBy.plot) | Class implementing the .plot attribute for groupby objects. | +| [`DataFrameGroupBy.quantile`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.quantile.html#pandas.core.groupby.DataFrameGroupBy.quantile)\(\[q, interpolation\]\) | Return group values at the given quantile, a la numpy.percentile. | +| [`DataFrameGroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.rank.html#pandas.core.groupby.DataFrameGroupBy.rank)\(\[method, ascending, …\]\) | Provide the rank of values within each group. | +| [`DataFrameGroupBy.resample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.resample.html#pandas.core.groupby.DataFrameGroupBy.resample)\(rule, \*args, \*\*kwargs\) | Provide resampling when using a TimeGrouper. | +| [`DataFrameGroupBy.sample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html#pandas.core.groupby.DataFrameGroupBy.sample)\(\[n, frac, replace, …\]\) | Return a random sample of items from each group. | +| [`DataFrameGroupBy.shift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.shift.html#pandas.core.groupby.DataFrameGroupBy.shift)\(\[periods, freq, …\]\) | Shift each group by periods observations. | +| [`DataFrameGroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.size.html#pandas.core.groupby.DataFrameGroupBy.size)\(\) | Compute group sizes. | +| [`DataFrameGroupBy.skew`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.skew.html#pandas.core.groupby.DataFrameGroupBy.skew) | Return unbiased skew over requested axis. | +| [`DataFrameGroupBy.take`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.take.html#pandas.core.groupby.DataFrameGroupBy.take) | Return the elements in the given _positional_ indices along an axis. | +| [`DataFrameGroupBy.tshift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.tshift.html#pandas.core.groupby.DataFrameGroupBy.tshift) | \(DEPRECATED\) Shift the time index, using the index’s frequency if available. | + +The following methods are available only for `SeriesGroupBy` objects. + +| [`SeriesGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.hist.html#pandas.core.groupby.SeriesGroupBy.hist) | Draw histogram of the input series using matplotlib. | +| :--- | :--- | +| [`SeriesGroupBy.nlargest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nlargest.html#pandas.core.groupby.SeriesGroupBy.nlargest) | Return the largest n elements. | +| [`SeriesGroupBy.nsmallest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nsmallest.html#pandas.core.groupby.SeriesGroupBy.nsmallest) | Return the smallest n elements. | +| [`SeriesGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nunique.html#pandas.core.groupby.SeriesGroupBy.nunique)\(\[dropna\]\) | Return number of unique elements in the group. | +| [`SeriesGroupBy.unique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.unique.html#pandas.core.groupby.SeriesGroupBy.unique) | Return unique values of Series object. | +| [`SeriesGroupBy.value_counts`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.value_counts.html#pandas.core.groupby.SeriesGroupBy.value_counts)\(\[normalize, …\]\) | | +| [`SeriesGroupBy.is_monotonic_increasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing) | Alias for is\_monotonic. | +| [`SeriesGroupBy.is_monotonic_decreasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing) | Return boolean if values in the object are monotonic\_decreasing. | + +The following methods are available only for `DataFrameGroupBy` objects. + +| [`DataFrameGroupBy.corrwith`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corrwith.html#pandas.core.groupby.DataFrameGroupBy.corrwith) | Compute pairwise correlation. | +| :--- | :--- | +| [`DataFrameGroupBy.boxplot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.boxplot.html#pandas.core.groupby.DataFrameGroupBy.boxplot)\(\[subplots, column, …\]\) | Make box plots from DataFrameGroupBy data. | + diff --git a/api-reference-v1-stable/groupby/README.md b/api-reference-v1-stable/groupby/README.md new file mode 100644 index 0000000..9a1db65 --- /dev/null +++ b/api-reference-v1-stable/groupby/README.md @@ -0,0 +1,34 @@ +--- +description: 'GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby()' +--- + +# Groupby + +### Indexing, iteration + +| | | +| :--- | :--- | +| [`GroupBy.get_group`](groupby.get_groups.md) | Construct DataFrame from group with provided name. | + +### Function application + +| | | +| :--- | :--- | +| [`GroupBy.agg`](groupby.agg.md) | Aggregate using one or more operations over the specified axis. | + +### Computations / descriptive stats + +| | | +| :--- | :--- | +| [`GroupBy.count`](groupby.count.md) | Compute count of group, excluding missing values. | +| [`GroupBy.cummax`](groupby.cummax.md) | Cumulative max for each group. | +| [`GroupBy.cummin`](groupby.cummin.md) | Cumulative min for each group. | +| [`GroupBy.cumprod`](groupby.cumprod.md) | Cumulative product for each group. | +| [`GroupBy.cumsum`](groupby.cumsum.md) | Cumulative sum for each group. | +| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max) | Compute max of group values. | +| [`GroupBy.mean`](groupby.mean.md) | Compute mean of groups, excluding missing values. | +| [`GroupBy.min`](groupby.min.md) | Compute min of group values. | +| [`GroupBy.std`](groupby.std.md) | Compute standard deviation of groups, excluding missing values. | +| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum) | Compute sum of group values. | +| [`GroupBy.var`](groupby.var.md) | Compute variance of groups, excluding missing values. | + diff --git a/api-reference-v1-stable/groupby/groupby.agg.md b/api-reference-v1-stable/groupby/groupby.agg.md new file mode 100644 index 0000000..f9d6a5f --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.agg.md @@ -0,0 +1,93 @@ +--- +description: Obtain data aggregate per groups for each column +--- + +# Groupby.agg + +> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | +| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | + +**Return: **DataFrame + +**Examples** + +Using mean and sum aggregate + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.agg({"C":"mean","D":"sum"}).print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... │ 27 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Mean and Sum aggregate on dataframe groupby two column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.agg({"C":"mean","D":"sum"}).print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference-v1-stable/groupby/groupby.apply.md b/api-reference-v1-stable/groupby/groupby.apply.md new file mode 100644 index 0000000..2150a21 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.apply.md @@ -0,0 +1,84 @@ +--- +description: Apply custom aggregate function to grouped data +--- + +# Groupby.apply + +danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function \| function to be applied to grouped data | Undefined | | + +**Returns:** + + ****return **DataFrame** + +## **Examples** + +Using apply to create a custom function that subtract the minimum value of each grouped data from each of its values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + 'A': ['foo', 'bar', 'foo', 'bar', + + 'foo', 'bar', 'foo', 'foo'], + + 'B': ['one', 'one', 'two', 'three', + + 'two', 'two', 'one', 'three'], + + 'C': [1, 3, 2, 4, 5, 2, 6, 7], + + 'D': [3, 2, 4, 1, 5, 6, 7, 8] + }; +let df = new dfd.DataFrame(data); +let group_df = df.groupby(["A", "B"]); + +const subMin = (x) => { + return x.sub(x.min()); +}; + +group_df.apply(subMin).print(); + +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_apply │ D_apply ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 5 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 3 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +\*\*\*\* diff --git a/api-reference-v1-stable/groupby/groupby.col.md b/api-reference-v1-stable/groupby/groupby.col.md new file mode 100644 index 0000000..02e7cdd --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.col.md @@ -0,0 +1,105 @@ +--- +description: Obtain the column(s) per groups +--- + +# Groupby.col + +> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| col\_names | Array | List of column | | + +Returns: Groupby Data structure + +Note: This is similar to pandas `df.groupby(["column"])["col_names"]` + +**Examples** + +Obtain a column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]) + +//for more coumns +grp.col(["C","D"]) +``` +{% endtab %} +{% endtabs %} + +Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. + +```text +//it returns the groupby data structure +GroupBy { + key_col: [ 'A' ], + col_dict: { + foo: [ [Array], [Array], [Array], [Array], [Array] ], + bar: [ [Array], [Array], [Array] ] + }, + data: [ + [ 'foo', 'one', 1, 3 ], + [ 'bar', 'one', 3, 2 ], + [ 'foo', 'two', 2, 4 ], + [ 'bar', 'three', 4, 1 ], + [ 'foo', 'two', 5, 5 ], + [ 'bar', 'two', 2, 6 ], + [ 'foo', 'one', 6, 7 ], + [ 'foo', 'three', 7, 8 ] + ], + column_name: [ 'A', 'B', 'C', 'D' ], + data_tensors: { + foo: DataFrame { + kwargs: [Object], + series: false, + data: [Array], + row_data_tensor: [Tensor], + index_arr: [Array], + columns: [Array], + col_data: [Array], + col_data_tensor: [Tensor], + col_types: [Array], + A: [Getter/Setter], + B: [Getter/Setter], + C: [Getter/Setter], + D: [Getter/Setter] + }, + bar: DataFrame { + kwargs: [Object], + series: false, + data: [Array], + row_data_tensor: [Tensor], + index_arr: [Array], + columns: [Array], + col_data: [Array], + col_data_tensor: [Tensor], + col_types: [Array], + A: [Getter/Setter], + B: [Getter/Setter], + C: [Getter/Setter], + D: [Getter/Setter] + } + }, + group_col_name: [ 'C' ], + group_col: { foo: [ [Series] ], bar: [ [Series] ] } +} +``` + + + diff --git a/api-reference-v1-stable/groupby/groupby.count.md b/api-reference-v1-stable/groupby/groupby.count.md new file mode 100644 index 0000000..36733be --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.count.md @@ -0,0 +1,175 @@ +--- +description: Count the occurrence of values in columns per groups +--- + +# Groupby.count + +> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the variance of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_count ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_count │ D_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).count().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count │ D_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 1 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.cummax.md b/api-reference-v1-stable/groupby/groupby.cummax.md new file mode 100644 index 0000000..8231a61 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.cummax.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cummulative max per groups for each column +--- + +# Groupby.cummax + +> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative max of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cummax().head().print() +grp.col(["C"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + +Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 4 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cummax().head().print() +grp.col(["C","D"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax │ D_cummax ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 4 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 4 │ 6 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 4 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 4 │ 6 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummax for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cummax().head().print() +grp.col(["C"]).cummax().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummax for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cummax().head().print() +grp.col(["C","D"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference-v1-stable/groupby/groupby.cummin.md b/api-reference-v1-stable/groupby/groupby.cummin.md new file mode 100644 index 0000000..7fd9ed6 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.cummin.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cummulative minimum per groups for each column +--- + +# Groupby.cummin + +> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative min of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 2 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 2 │ 1 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference-v1-stable/groupby/groupby.cumprod.md b/api-reference-v1-stable/groupby/groupby.cumprod.md new file mode 100644 index 0000000..af46123 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.cumprod.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cumulative product per group for each column +--- + +# Groupby.cumprod + +> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative product of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + +Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 │ 420 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 │ 3360 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 24 │ 12 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 24 │ 12 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 21 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference-v1-stable/groupby/groupby.cumsum.md b/api-reference-v1-stable/groupby/groupby.cumsum.md new file mode 100644 index 0000000..3b2b0e6 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.cumsum.md @@ -0,0 +1,259 @@ +--- +description: Obtain the cumulative sum per groups for each column +--- + +# Groupby.cumsum + +> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative sum of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + +Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 │ 19 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 │ 27 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 9 │ 9 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 9 │ 9 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.get_groups.md b/api-reference-v1-stable/groupby/groupby.get_groups.md new file mode 100644 index 0000000..0cdf912 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.get_groups.md @@ -0,0 +1,129 @@ +--- +description: Obtain the data for each element of the groupby column +--- + +# Groupby.get\_groups + +> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] + +| Parameters | Type | Description | default | +| :--- | :--- | :--- | :--- | +| key | Array | element of the groupby column | | + +**Returns**: DataFrame + +**Example** + +Group the dataframe by column A and obtain the group belonging to the values in column A + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) + +grp.get_groups(["foo"]).print() + +grp.get_groups(["bar"]).print() +``` +{% endtab %} +{% endtabs %} + +```text +//get groups for key "foo" + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get groups for key "bar" + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ three │ 4 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) + +grp.get_groups(["foo","one"]).print() + +grp.get_groups(["bar","one"]).print() +``` +{% endtab %} +{% endtabs %} + +```text +//get_groups(["foo","one"] + + + Shape: (2,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get_groups(["bar","one"]) + + + Shape: (1,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference-v1-stable/groupby/groupby.max.md b/api-reference-v1-stable/groupby/groupby.max.md new file mode 100644 index 0000000..6bebae5 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.max.md @@ -0,0 +1,170 @@ +--- +description: Obtain the maximum value of columns per groups +--- + +# Groupby.max + +> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] + +**Parameters: **None + +**Returns**: DataFrame + +**Example** + +Obtain the maximum value for a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_max ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_max │ D_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 4 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_max │ D_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference-v1-stable/groupby/groupby.mean.md b/api-reference-v1-stable/groupby/groupby.mean.md new file mode 100644 index 0000000..add6958 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.mean.md @@ -0,0 +1,173 @@ +--- +description: Obtain the mean per groups for each column(s) +--- + +# Groupby.mean + +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the mean of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ D_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... │ 5.40000009536... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean │ D_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 │ 4.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.min.md b/api-reference-v1-stable/groupby/groupby.min.md new file mode 100644 index 0000000..0151e64 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.min.md @@ -0,0 +1,171 @@ +--- +description: Obtain the minimum value per groups for a coumn(s) +--- + +# Groupby.min + +> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the minimum value for a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_min ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the minimum value for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_min │ D_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 2 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min │ D_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.std.md b/api-reference-v1-stable/groupby/groupby.std.md new file mode 100644 index 0000000..c792a8e --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.std.md @@ -0,0 +1,175 @@ +--- +description: Obtain the standard deviation per groups for specified columns +--- + +# Groupby.std + +> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the standard deviation of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_std ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 2.58843582110... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_std │ D_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 2.58843582110... │ 2.07364413533... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 │ 2.64575131106... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).std().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.53553390593... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2.12132034355... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_std │ D_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.53553390593... │ 2.82842712474... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2.12132034355... │ 0.70710678118... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.sum.md b/api-reference-v1-stable/groupby/groupby.sum.md new file mode 100644 index 0000000..f6f2900 --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.sum.md @@ -0,0 +1,172 @@ +--- +description: Obtain the sum per groups for columns +--- + +# Groupby.sum + +> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the sum of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_sum ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 21 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_sum │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 21 │ 27 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 9 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 7 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/groupby/groupby.var.md b/api-reference-v1-stable/groupby/groupby.var.md new file mode 100644 index 0000000..373109f --- /dev/null +++ b/api-reference-v1-stable/groupby/groupby.var.md @@ -0,0 +1,175 @@ +--- +description: Obtain the variance per groups for a specified column +--- + +# Groupby.var + +> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the variance of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_var ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 6.7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_var │ D_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 6.7 │ 4.3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).var().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 12.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 4.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_var │ D_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 12.5 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 4.5 │ 0.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference-v1-stable/input-output/README.md b/api-reference-v1-stable/input-output/README.md new file mode 100644 index 0000000..e86d5de --- /dev/null +++ b/api-reference-v1-stable/input-output/README.md @@ -0,0 +1,18 @@ +--- +description: Functions for reading tabular/structured data into DataFrame/Series Objects +--- + +# Input/Output + +## CSV + +| \`\` | | +| ----------------------------------- | -------------------------------------------------------- | +| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | +| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | +| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | + +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference-v1-stable/input-output/danfo.read_csv.md b/api-reference-v1-stable/input-output/danfo.read_csv.md new file mode 100644 index 0000000..79644f3 --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.read_csv.md @@ -0,0 +1,135 @@ +--- +description: >- + Reads a comma-separated values (CSV) file into DataFrame. Also supports the + reading of CSV files in chunks. +--- + +# danfo.read_csv + +> danfo.**read_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] + +| **Parameters** | Type | Description | Default | +| -------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | +| **configs**: | object, optional |

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

|

{

dynamicTyping: true,

header: true

}

| + +**Returns:** + +** **_**Promise**_. Resolves to DataFrame + +The **read_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. + +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_csv("./user_names.csv") //assumes file is in CWD + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading files from a URL** + +By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_excel.md b/api-reference-v1-stable/input-output/danfo.read_excel.md new file mode 100644 index 0000000..459aa30 --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.read_excel.md @@ -0,0 +1,68 @@ +--- +description: Reads an excel file into DataFrame. +--- + +# danfo.read_excel + +> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] + +| Parameters | Type | Description | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| source | string | **source** : string, URL or local file path to retreive Excel file. | +| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| + +> **Returns:** +> +> ** **return** **{**Promise**} DataFrame structure of parsed Excel data + +### Example + +The **read_excel** method can read excel files saved on a local disk, or over the internet. + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") +const path = require("path") + +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") + +async function load_process_data() { + let df = await dfd.read_excel(local_xcel) + df.head().print() +} + +load_process_data() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_json.md b/api-reference-v1-stable/input-output/danfo.read_json.md new file mode 100644 index 0000000..85412ea --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.read_json.md @@ -0,0 +1,128 @@ +--- +description: Reads a JSON file into DataFrame. +--- + +# danfo.read_json + +> danfo.**read_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| _**source**_ | Input file object, string file** **path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | +| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| + +**Returns:** + +** **_**Promise**_. Resolves to DataFrame + +The **read_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. + +### **Reading JSON files from local disk** + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.to_csv.md b/api-reference-v1-stable/input-output/danfo.to_csv.md new file mode 100644 index 0000000..5bd4105 --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.to_csv.md @@ -0,0 +1,115 @@ +--- +description: Writes a DataFrame or Series to CSV format. +--- + +# danfo.to_csv + +> danfo.**to_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +### Convert DataFrame to CSV string and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const csv = dfd.to_csv(df, { download: false }); +console.log(csv); + +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_csv(df, { filePath: "testOut.csv"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and download file in Client-side lib + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +const dfd = require("danfojs") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_csv(df, { fileName: "testOut.csv", download: true}); +``` diff --git a/api-reference-v1-stable/input-output/danfo.to_excel.md b/api-reference-v1-stable/input-output/danfo.to_excel.md new file mode 100644 index 0000000..1fe1adf --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.to_excel.md @@ -0,0 +1,54 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# danfo.to_excel + +> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| + +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_excel(df, { filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in Client-side lib + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_excel(df, { fileName: "testOut.xlsx"}); +``` diff --git a/api-reference-v1-stable/input-output/danfo.to_json.md b/api-reference-v1-stable/input-output/danfo.to_json.md new file mode 100644 index 0000000..80eaa04 --- /dev/null +++ b/api-reference-v1-stable/input-output/danfo.to_json.md @@ -0,0 +1,124 @@ +# danfo.to_json + +> danfo.**to_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. + +### Convert DataFrame/Series to JSON and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = dfd.to_json(df, { download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = dfd.to_json(df, { + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_json(df, { filePath: "./testOutput.json" }); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_json(df, { fileName: "test_out.json" }); +``` diff --git a/api-reference-v1-stable/input-output/read.md b/api-reference-v1-stable/input-output/read.md new file mode 100644 index 0000000..c38778e --- /dev/null +++ b/api-reference-v1-stable/input-output/read.md @@ -0,0 +1,138 @@ +--- +description: >- + The generic read function loads a tabular data using the Frictionless + specification. +--- + +# read + +> danfo.**read**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
source + stringA path to the file/resources. It can be a local file, a URL to tabular + data (CSV, EXCEL) or Datahub.io Data Resource.
configs + object +

+

Configuration options. Supported params are:

+

data_num (Defaults => 0): The specific dataset to load, when + reading data from a datapackage.json,

+

header (Defaults => true): Whether the dataset contains a header + or not.

+

sheet (Defaults => 0): Number of the excel sheet which u want + to load.

+

}

+
+ +**Returns:** + + ****_**Promise**_. Resolves to DataFrame + +The **read** function uses [frictionless.js](https://github.com/frictionlessdata/frictionless-js) underhood.[`frictionless.js`](https://github.com/frictionlessdata/frictionless-js) is a lightweight, standardized "stream-plus-metadata" interface for accessing files and datasets, especially tabular ones \(CSV, Excel\). It follows the [Frictionless spec](https://frictionlessdata.io/specs/) + +> ### **Note**: The `read` method is only available in danfojs-node at the moment. + +### Read a CSV file + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let df = await dfd.read("file.csv") + let sample = await df.sample(10) + sample.print() +} + +load_data() +``` +{% endtab %} +{% endtabs %} + +### **Loading Files from URL** + +By specifying a valid URL, you can load CSV/EXCEL file: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let df = await dfd.read("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") + df.head().print() +} + +load_data() +``` +{% endtab %} +{% endtabs %} + +### Loading Data from a Data Package Descriptor + +You can load data from a frictionless data package [descriptor](https://specs.frictionlessdata.io/data-package/#descriptor). A data package descriptor is a central file in a Data Package. It is a JSON file that provides: + +* General metadata such as the package’s title, license, publisher etc +* A list of the data “resources” that make up the package including their location on disk or online and other relevant information \(including, possibly, schema information about these data resources in a structured form\) + +For instance, in the example below, we load the first resource in the [Natural Gas dataset](https://datahub.io/core/natural-gas) from datahub.io. + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + const package_url = + "https://datahub.io/core/natural-gas/datapackage.json"; + + const df = await dfd.read(package_url, { data_num: 1 }); + df.head().print(); + +load_data() +``` +{% endtab %} +{% endtabs %} + +```bash +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Date │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 1997-01-07 │ 3.81999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 1997-01-08 │ 3.79999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 1997-01-09 │ 3.60999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 1997-01-10 │ 3.91999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ 1997-01-13 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + + + diff --git a/api-reference-v1-stable/plotting/README.md b/api-reference-v1-stable/plotting/README.md new file mode 100644 index 0000000..93161e3 --- /dev/null +++ b/api-reference-v1-stable/plotting/README.md @@ -0,0 +1,19 @@ +--- +description: >- + DataFrame and Series have inbuilt support for plotting using Plotly's backend. + All customization can be done using Plotly's parameter passed to the config + object. +--- + +# Plotting + +* [Line Charts](line-charts.md) +* [Bar Charts](bar-charts.md) +* [Scatter Plots](scatter-plots.md) +* [Histograms](histograms.md) +* [Pie Charts](pie-charts.md) +* [Tables](tables.md) +* [Box Plots](box-plots.md) +* [Violin Plots](violin-plots.md) +* [Timeseries Plots](timeseries-plots.md) + diff --git a/api-reference-v1-stable/plotting/bar-charts.md b/api-reference-v1-stable/plotting/bar-charts.md new file mode 100644 index 0000000..aee82cd --- /dev/null +++ b/api-reference-v1-stable/plotting/bar-charts.md @@ -0,0 +1,78 @@ +--- +description: Makes a vertical bar plot. +--- + +# Bar Charts + +A bar plot presents categorical data with rectangular bars with lengths proportional to the values that they represent. + +## Examples + +The **bar** plot is exposed by the .**plot\(\)** function called on a Series or DataFrame. The **.plot\(\)** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. + +### Bar plot on Series + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-6-.png) + +### Bar plot on DataFrame + +```markup + + + + + + + + + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-7-.png) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} + diff --git a/api-reference-v1-stable/plotting/box-plots.md b/api-reference-v1-stable/plotting/box-plots.md new file mode 100644 index 0000000..8a6e490 --- /dev/null +++ b/api-reference-v1-stable/plotting/box-plots.md @@ -0,0 +1,122 @@ +--- +description: Make a box plot from DataFrame columns. +--- + +# Box Plots + +Make a box-and-whisker plot from DataFrame columns, optionally grouped by some other columns. A box plot is a method for graphically depicting groups of numerical data through their quartiles. + +## Examples + +### Boxplot for a Series Object + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-23-.png) + +### Box plots on a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am%20%281%29%20%281%29.png) + +### Box plot for selected columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-24-.png) + + + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} + diff --git a/api-reference-v1-stable/plotting/configuring-your-plots.md b/api-reference-v1-stable/plotting/configuring-your-plots.md new file mode 100644 index 0000000..7d96b4d --- /dev/null +++ b/api-reference-v1-stable/plotting/configuring-your-plots.md @@ -0,0 +1,69 @@ +# Configuring your plots + +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. + +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. + +For example in the following code, we show how to set some basic configuration as well as layout for a line plot. + +```markup + + + + + + + + + + + +
+ + + + +``` + +![](../../.gitbook/assets/newplot-32-.png) + diff --git a/api-reference-v1-stable/plotting/histograms.md b/api-reference-v1-stable/plotting/histograms.md new file mode 100644 index 0000000..12497e3 --- /dev/null +++ b/api-reference-v1-stable/plotting/histograms.md @@ -0,0 +1,120 @@ +--- +description: 'Draw one histogram of the DataFrame’s columns, or single histogram for Series' +--- + +# Histograms + +A histogram is a representation of the distribution of data. This function groups the values of all given Series in the DataFrame into bins + +## Examples + +### Histogram of a Column in a DataFrame + +In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-10-.png) + +### Customized Histogram plots on DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-20-.png) + +### Configuring your plots + +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. + +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: + +```javascript +var layout = { + title: 'A sample plot', + xaxis: { + title: 'X', + }, + yaxis: { + title: 'Y', + } +} + +df.plot("div_tag").histogram({layout: layout}) +``` + +{% hint style="info" %} +For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. +{% endhint %} + diff --git a/api-reference-v1-stable/plotting/line-charts.md b/api-reference-v1-stable/plotting/line-charts.md new file mode 100644 index 0000000..73326f4 --- /dev/null +++ b/api-reference-v1-stable/plotting/line-charts.md @@ -0,0 +1,112 @@ +--- +description: >- + Plot Series or DataFrame as lines. This function is useful to plot lines using + DataFrame’s values as coordinates. +--- + +# Line Charts + +## Examples + +### Basic Line plot on Series + +The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-4-.png) + +### Line plots on DataFrame + +The example below shows the plot of column values against a common x-axis (index) + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](<../../.gitbook/assets/newplot-2- (1) (1) (2) (2).png>) + +The example below shows how to plot two columns in a DataFrame against each other. + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-3-.png) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference-v1-stable/plotting/pie-charts.md b/api-reference-v1-stable/plotting/pie-charts.md new file mode 100644 index 0000000..c355bcb --- /dev/null +++ b/api-reference-v1-stable/plotting/pie-charts.md @@ -0,0 +1,127 @@ +--- +description: Generate a pie plot. +--- + +# Pie Charts + +A pie plot is a proportional representation of the numerical data in a column + +## Examples + +### Pie Chart from Columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-12-.png) + +### Multiple Pie Chart from Columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-21-.png) + +### Configure Position of Pie Charts + +If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-22-.png) + +{% hint style="info" %} +For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. +{% endhint %} + diff --git a/api-reference-v1-stable/plotting/scatter-plots.md b/api-reference-v1-stable/plotting/scatter-plots.md new file mode 100644 index 0000000..739a49f --- /dev/null +++ b/api-reference-v1-stable/plotting/scatter-plots.md @@ -0,0 +1,91 @@ +--- +description: Create a scatter plot of columns in a DataFrame +--- + +# Scatter Plots + +The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. + +## Examples + +### Scatter Plots on Columns in a DataFrame + +In the example below, we use the titanic dataset, to show a close to real-world use case of danfo.js + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-8-%20%281%29.png) + +### More Examples + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-19-.png) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} + diff --git a/api-reference-v1-stable/plotting/tables.md b/api-reference-v1-stable/plotting/tables.md new file mode 100644 index 0000000..efa1fbb --- /dev/null +++ b/api-reference-v1-stable/plotting/tables.md @@ -0,0 +1,97 @@ +--- +description: Turn DataFrame/Series in D3.js-based tables +--- + +# Tables + +## Examples + +### Create Interactive Tables from DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png) + +### Configure the header and cell of a table + +To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. + +```markup + + + + + + + + + Document + + + + +
+ + + + + + +``` + +![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png) + diff --git a/api-reference-v1-stable/plotting/timeseries-plots.md b/api-reference-v1-stable/plotting/timeseries-plots.md new file mode 100644 index 0000000..7bbb089 --- /dev/null +++ b/api-reference-v1-stable/plotting/timeseries-plots.md @@ -0,0 +1,58 @@ +--- +description: Timeseries plot are based on date index +--- + +# Timeseries Plots + +## Examples + +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot-29- (2) (1).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference-v1-stable/plotting/violin-plots.md b/api-reference-v1-stable/plotting/violin-plots.md new file mode 100644 index 0000000..e0c1c8f --- /dev/null +++ b/api-reference-v1-stable/plotting/violin-plots.md @@ -0,0 +1,116 @@ +# Violin Plots + +Make a violin plot from DataFrame columns, optionally grouped by some other columns. A violin plot is a method for graphically depicting groups of numerical data through their quartiles. See also [Box Plot](box-plots.md) + +## Examples + +### Boxplot for a Series Object + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-25-.png) + +### Box plots on a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-26-.png) + +### Box plot for selected columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](../../.gitbook/assets/newplot-27-.png) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} + diff --git a/api-reference-v1-stable/series/README.md b/api-reference-v1-stable/series/README.md new file mode 100644 index 0000000..7eefaa7 --- /dev/null +++ b/api-reference-v1-stable/series/README.md @@ -0,0 +1,182 @@ +--- +description: One-dimensional ndarray with axis labels (including time series). +--- + +# Series + +> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ],** index: **\[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] + +### Attributes + +| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | +| --------------------------------- | ------------------------------------------- | + +| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | +| ----------------------------------- | ---------------------------------------------------------------- | +| [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | +| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | +| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | +| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | +| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | + +### Conversion + +| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | +| --------------------------------------------------- | ---------------------------------------------- | +| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | + +### Indexing, iteration + +| | | +| ------------------------------------------------------- | ------------------------------------------------------------------ | +| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | +| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | + +### Binary operator functions + +| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | +| --------------------------------- | --------------------------------------------------------------------------------------- | +| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | +| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | +| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | +| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | +| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | +| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | +| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | +| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | +| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | +| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | +| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | +| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | +| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | + +### Function application & GroupBy + +| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | +| --------------------------------- | ------------------------------------------------------- | +| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | + +### Computations / descriptive stats + +| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | +| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | +| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | +| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | +| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | +| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | +| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | +| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | +| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | +| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | +| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | +| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | +| [`Series.unique`](series.unique.md) | Return unique values of Series object. | +| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | +| [`Series.value_counts`](series.value_counts.md) | Return a Series containing counts of unique values. | + +### Reindexing / selection / label manipulation + +| | | +| ----------------------------------------------------- | -------------------------------------------------------- | +| [`Series.drop_duplicates`](series.drop_duplicates.md) | Return Series with duplicate values removed. | +| [`Series.head`](series.head.md) | Return the first n rows. | +| [`Series.reset_index`](series.reset_index.md) | Generate a new DataFrame or Series with the index reset. | +| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | +| [`Series.tail`](series.tail.md) | Return the last n rows. | + +### Missing data handling + +| | | +| ------------------------------------- | ------------------------------------------------ | +| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | +| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | +| [`Series.isna`](series.isna.md) | Detect missing values. | +| [`Series.replace`](series.replace.md) | Replace values given in to_replace with value. | + +### Reshaping, sorting + +| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | +| --------------------------------------------- | ------------------------------------------------------------- | +| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | +| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | +| [`Series.sort_values`](series.sort_values.md) | Sort by the values. | + +### Accessors + +Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. + +| Data Type | Accessor | +| --------- | -------- | +| Datetime | dt | +| String | str | + +#### Datetimelike properties + +`Series.dt` can be used to access the values of the series as datetime and return several properties. These can be accessed like `Series.dt.`. + +**Datetime methods** + +| | | +| ------------------------------------------------- | ------------------------------------------------------------------ | +| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | +| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | +| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | +| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | +| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | +| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | +| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | +| [`Series.dt.month_name`](series.dt.month_name.md) | Return the month names of the DateTimeIndex with specified locale. | + +#### String handling + +`Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. + +| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | +| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | +| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | +| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | +| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | +| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | +| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | +| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | +| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | +| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | +| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | +| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | +| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | +| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | +| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | +| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | +| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | +| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | +| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | + +### Plotting + +`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. + +| | | +| ----------------------------------------------------- | ------------------------------------------------------------- | +| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | +| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | +| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | + +### Serialization / IO / conversion + +| | | +| ----------------------------------------------------- | ---------------------------------------------------- | +| [`Series.to_csv`](../dataframe/dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | +| [`Series.to_json`](../dataframe/dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/series/creating-a-series.md b/api-reference-v1-stable/series/creating-a-series.md new file mode 100644 index 0000000..3c8e4ba --- /dev/null +++ b/api-reference-v1-stable/series/creating-a-series.md @@ -0,0 +1,210 @@ +# Creating a Series + +new danfo.**Series**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ +In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. + +### Creating a Series from an object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```javascript +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series from an array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = ["bval1", "bval2", "bval3", "bval4"] +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series and specifying index and dtypes + +You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. + +> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2, 3, 4, 5]; +let index = ["a", "b", "c", "d", "e"]; +let dtypes = ["int32",] + +let df = new Series(data1, { index, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╚═══╧═══╝ +``` + +### Creating a Series and specifying memory mode + +To use less space on Series creation, you can set the low memory mode as demonstrated below: + +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2.3, 3, 4, 5, "girl"]; + +let df = new Series(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the Series. +{% endhint %} + diff --git a/api-reference-v1-stable/series/danfo.series.add.md b/api-reference-v1-stable/series/danfo.series.add.md new file mode 100644 index 0000000..7cd6150 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.add.md @@ -0,0 +1,22 @@ +--- +description: 'Return Addition of series and other, element-wise (binary operator add).' +--- + +# danfo.Series.add + +Return Addition of series and other, element-wise \(binary operator add\). + + **parameter:** {other} Series or Number to add + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 6] +let data2 = [30, 40, 39, 1, 2, 1] +let sf = new Series(data) +let sf2 = new Series(data2) +sf.add(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.apply.md b/api-reference-v1-stable/series/danfo.series.apply.md new file mode 100644 index 0000000..d59a99c --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.apply.md @@ -0,0 +1,63 @@ +--- +description: invoke a function on Series Value +--- + +# danfo.Series.apply + +> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function | Function \(can be anonymous\) to apply | | + +**Returns:** + + ****return **Series** + +\*\*\*\* + +**Example** + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +let apply_func = (x) => { + return x + x +} +sf.apply(apply_func).print() +``` + +**OUTPUT:** + +![](../../.gitbook/assets/series_apply.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +sf.apply(Math.log).print() +``` + +**OUTPUT:** + +![](../../.gitbook/assets/series_apply1.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) + +sf.apply((x)=>{ + return x.toLocaleLowerCase() +}).print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_apply2.png) + + + diff --git a/api-reference-v1-stable/series/danfo.series.copy.md b/api-reference-v1-stable/series/danfo.series.copy.md new file mode 100644 index 0000000..c610c04 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.copy.md @@ -0,0 +1,22 @@ +# danfo.Series.copy + +Make a new copy of Series + + + +**parameter:** + + **return:** {Series} + +**Example** + +```javascript +let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) +sf_copy = sf.copy() + + +let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) +sf = sf.set_index({ "index": ["a", "b", "c", "d"] }) +sf_copy = sf.copy() +``` + diff --git a/api-reference-v1-stable/series/danfo.series.count.md b/api-reference-v1-stable/series/danfo.series.count.md new file mode 100644 index 0000000..50a5789 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.count.md @@ -0,0 +1,24 @@ +--- +description: Return the sum of the values in a series. +--- + +# danfo.Series.count + +Return number of non-NA/null observations in the Series. + +This is equivalent to the method numpy.sum + + **parameter:** + + **return:** {Number}, sum of values in Series + +**Example** + +```javascript +let data = ["boy", "gitl", "woman", NaN] +let sf = new Series(data) +sf.count() +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.describe.md b/api-reference-v1-stable/series/danfo.series.describe.md new file mode 100644 index 0000000..184dbe9 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.describe.md @@ -0,0 +1,26 @@ +# danfo.Series.describe + + + +Generate descriptive statistics. Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding NaN values + + + +**parameter:** + + **return:** {frame} + +**Example** + +```javascript +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three"] }) + + +let data = [1,2,3,4,5,6] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +df.reset_index() +``` + diff --git a/api-reference-v1-stable/series/danfo.series.div.md b/api-reference-v1-stable/series/danfo.series.div.md new file mode 100644 index 0000000..ae2731b --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.div.md @@ -0,0 +1,26 @@ +--- +description: >- + Return Floating division of series and other, element-wise (binary operator + truediv). +--- + +# danfo.Series.div + +Return division of series and other, element-wise \(binary operator div\). + +Equivalent to series / other + + **parameter:** {other} Series, Number to divide with. + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.div(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.head.md b/api-reference-v1-stable/series/danfo.series.head.md new file mode 100644 index 0000000..1bc9d5e --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.head.md @@ -0,0 +1,25 @@ +--- +description: This function returns the first n rows for the object based on position. +--- + +# danfo.Series.head + + + +Prints the first n values in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let cols = ["A"] +let sf = new Series(data, { columns: cols }) +sf.head() +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.map.md b/api-reference-v1-stable/series/danfo.series.map.md new file mode 100644 index 0000000..9d7cad4 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.map.md @@ -0,0 +1,42 @@ +--- +description: Map the value of a series to it representation +--- + +# danfo.Series.map + +> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] + +| Parameter | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function or Object | callable can either be a function or an object\({}\) | | + +**Example** + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1,2,3,4]) +let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } +sf.map(map) + +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_map.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1,2,3,4]) + +sf.map((x)=>{ + return `I have ${x} cat(s)` +}).print() + +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_map1.png) + diff --git a/api-reference-v1-stable/series/danfo.series.max.md b/api-reference-v1-stable/series/danfo.series.max.md new file mode 100644 index 0000000..cac4ba1 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.max.md @@ -0,0 +1,2 @@ +# danfo.Series.max + diff --git a/api-reference-v1-stable/series/danfo.series.maximum.md b/api-reference-v1-stable/series/danfo.series.maximum.md new file mode 100644 index 0000000..9082120 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.maximum.md @@ -0,0 +1,22 @@ +# danfo.Series.maximum + +Return maximum of series and other, element-wise \(binary operator div\). + + + + **parameter:** {other} Series, Numbers to check maximum against + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.maximum(sf2) +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.mean.md b/api-reference-v1-stable/series/danfo.series.mean.md new file mode 100644 index 0000000..6ace487 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.mean.md @@ -0,0 +1,2 @@ +# danfo.Series.mean + diff --git a/api-reference-v1-stable/series/danfo.series.median.md b/api-reference-v1-stable/series/danfo.series.median.md new file mode 100644 index 0000000..077c0ec --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.median.md @@ -0,0 +1,2 @@ +# danfo.Series.median + diff --git a/api-reference-v1-stable/series/danfo.series.min.md b/api-reference-v1-stable/series/danfo.series.min.md new file mode 100644 index 0000000..22f3589 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.min.md @@ -0,0 +1,2 @@ +# danfo.Series.min + diff --git a/api-reference-v1-stable/series/danfo.series.minimum.md b/api-reference-v1-stable/series/danfo.series.minimum.md new file mode 100644 index 0000000..2a9d9c6 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.minimum.md @@ -0,0 +1,22 @@ +# danfo.Series.minimum + + + +Return minimum of series and other, element-wise \(binary operator div\). + + + + **parameter:** {other} Series, Numbers to check minimum against + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.minimum(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.mod.md b/api-reference-v1-stable/series/danfo.series.mod.md new file mode 100644 index 0000000..577014d --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.mod.md @@ -0,0 +1,24 @@ +--- +description: 'Return Modulo of series and other, element-wise (binary operator mod).' +--- + +# danfo.Series.mod + +Return Modulo of series and other, element-wise \(binary operator mod\). + +Equivalent to series % other + + **parameter:** {other} Series, Number + + **return:** Series + +**Example** + +```javascript +let data1 = [2, 30, 4, 5] +let data2 = [1.1, 2.2, 3.3, 2.4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.mod(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.mode.md b/api-reference-v1-stable/series/danfo.series.mode.md new file mode 100644 index 0000000..8d86e6e --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.mode.md @@ -0,0 +1,2 @@ +# danfo.Series.mode + diff --git a/api-reference-v1-stable/series/danfo.series.mul.md b/api-reference-v1-stable/series/danfo.series.mul.md new file mode 100644 index 0000000..6cdac92 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.mul.md @@ -0,0 +1,26 @@ +--- +description: 'Return Multiplication of series and other, element-wise (binary operator mul).' +--- + +# danfo.Series.mul + +Return Multiplication of series and other, element-wise \(binary operator mul\). + +Equivalent to series \* other, but with support to substitute a fill\_value for missing data in one of the inputs. + + **parameter:** {Series, Number to multiply with. + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.mul(sf2) +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.pow.md b/api-reference-v1-stable/series/danfo.series.pow.md new file mode 100644 index 0000000..291a993 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.pow.md @@ -0,0 +1,26 @@ +--- +description: >- + Return Exponential power of series and other, element-wise (binary operator + pow). +--- + +# danfo.Series.pow + +Return Exponential power of series and other, element-wise \(binary operator pow\). + +Equivalent to series \*\* other + + **parameter:** {other} Series, Number to multiply with. + + **return:** Series + +**Example** + +```javascript +let data1 = [2, 3, 4, 5] +let data2 = [1, 2, 3, 0] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.pow(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.reset_index.md b/api-reference-v1-stable/series/danfo.series.reset_index.md new file mode 100644 index 0000000..7a908a9 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.reset_index.md @@ -0,0 +1,31 @@ +# danfo.Series.reset\_index + + + +Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. + + + +**parameter:** {kwargs} {inplace: Modify the Series in place \(do not create a new object, drop: Just reset the index, without inserting it as a column in the new DataFrame.} + + **return:** {Series} + +**Example** + +```javascript +const dfd = require("danfojs") + +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["one", "two", "three"] }) +let df_reset = df_new.reset_index() +df_reset.print() + + +let data = [1,2,3,4,5,6] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +let df_new = df.reset_index() +df_new +``` + diff --git a/api-reference-v1-stable/series/danfo.series.round.md b/api-reference-v1-stable/series/danfo.series.round.md new file mode 100644 index 0000000..2bbacbb --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.round.md @@ -0,0 +1,20 @@ +# danfo.Series.round + +Round each value in a Series to the given number of decimals. + + + + **parameter:** {dp} Number, Numbers of Decimal places to round to + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf = new Series(data1) +sf.round(1) +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.sample.md b/api-reference-v1-stable/series/danfo.series.sample.md new file mode 100644 index 0000000..fa8f326 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.sample.md @@ -0,0 +1,22 @@ +--- +description: Return a random sample of items from an axis of object. +--- + +# danfo.Series.sample + +Gets \[num\] number of random rows in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf = new Series(data) +sf.sample(2) +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.set_index.md b/api-reference-v1-stable/series/danfo.series.set_index.md new file mode 100644 index 0000000..5cb3d28 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.set_index.md @@ -0,0 +1,40 @@ +--- +description: Assign new Index to Series +--- + +# danfo.Series.set\_index + +> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs | Object {} | The object contains the key **index** and assigned an array value of equal length to the Series. format {"index": \[Array\] } | | + +**Example** + +```javascript +const dfd = require("danfojs") + +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["one", "two", "three"] }) +df_new.print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series.reset_index.png) + +```javascript +const dfd = require("danfojs") + +let data = ["Humans","Life","Meaning","Fact","Truth"] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["H", "L", "M","F","T"] }) +df_new.print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_reset_index2.png) + diff --git a/api-reference-v1-stable/series/danfo.series.sort_values.md b/api-reference-v1-stable/series/danfo.series.sort_values.md new file mode 100644 index 0000000..0a0c4e7 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.sort_values.md @@ -0,0 +1,27 @@ +# danfo.Series.sort\_values + + + +Sort a Series in ascending or descending order by some criterion. + + + + **parameter:** {kwargs} Object, {ascending \(Bool\): Whether to return sorted values in ascending order or not, inplace \(Bool\): Whether to perform sorting on the original Series or not} + + **return:** {Number} + +**Example** + +```javascript +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values() + + +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values({ "inplace": true }) + + +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values({ "ascending": false, "inplace": true }) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.std.md b/api-reference-v1-stable/series/danfo.series.std.md new file mode 100644 index 0000000..8f48ef2 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.std.md @@ -0,0 +1,20 @@ +# danfo.Series.std + +Return sample standard deviation over requested axis. + + + + **parameter:** + + **return:** {Number} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.std() +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.sub.md b/api-reference-v1-stable/series/danfo.series.sub.md new file mode 100644 index 0000000..8867c14 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.sub.md @@ -0,0 +1,24 @@ +--- +description: 'Return Subtraction of series and other, element-wise (binary operator sub).' +--- + +# danfo.Series.sub + +Returns the subtraction between a series and other, element-wise \(binary operator subtraction\). + +Equivalent to series - other + + **parameter:** {other} Series, Number to subtract + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 39, 1, 2, 1] +let data2 = [1, 2, 3, 4, 5, 6] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.sub(sf2) +``` + diff --git a/api-reference-v1-stable/series/danfo.series.sum-1.md b/api-reference-v1-stable/series/danfo.series.sum-1.md new file mode 100644 index 0000000..6ec14cb --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.sum-1.md @@ -0,0 +1,22 @@ +--- +description: Return the sum of the values in a series. +--- + +# danfo.Series.sum + +Return the sum of the values for the requested axis. + +This is equivalent to the method numpy.sum. + + **parameter:** + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.sum() +``` + diff --git a/api-reference-v1-stable/series/danfo.series.tail.md b/api-reference-v1-stable/series/danfo.series.tail.md new file mode 100644 index 0000000..e83307d --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.tail.md @@ -0,0 +1,22 @@ +--- +description: Prints the last n values in a Series +--- + +# danfo.Series.tail + +Prints the first n values in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf = new Series(data) +sf.tail() +``` + + + diff --git a/api-reference-v1-stable/series/danfo.series.tostring.md b/api-reference-v1-stable/series/danfo.series.tostring.md new file mode 100644 index 0000000..5807850 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.tostring.md @@ -0,0 +1,18 @@ +# danfo.Series.toString + + + +Prints the data in a Series as a grid of row and columns + + + +**parameter:** + + **return:** {frame} + +**Example** + +```javascript + +``` + diff --git a/api-reference-v1-stable/series/danfo.series.var.md b/api-reference-v1-stable/series/danfo.series.var.md new file mode 100644 index 0000000..822edc7 --- /dev/null +++ b/api-reference-v1-stable/series/danfo.series.var.md @@ -0,0 +1,20 @@ +# danfo.Series.var + + + +Return unbiased variance of Series. + + + + **parameter:** + + **return:** {Number} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.var() +``` + diff --git a/api-reference-v1-stable/series/series.abs.md b/api-reference-v1-stable/series/series.abs.md new file mode 100644 index 0000000..3c9f46a --- /dev/null +++ b/api-reference-v1-stable/series/series.abs.md @@ -0,0 +1,52 @@ +--- +description: Returns the absolute value in a Series +--- + +# Series.abs + +> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| + +**Returns: **Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [-10, 45, 56, -25, 23, -20, 10] +let sf = new dfd.Series(data1) + +sf.abs().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.add.md b/api-reference-v1-stable/series/series.add.md new file mode 100644 index 0000000..e55b1b8 --- /dev/null +++ b/api-reference-v1-stable/series/series.add.md @@ -0,0 +1,86 @@ +--- +description: Return Addition of series and other, element-wise (binary operator add). +--- + +# Series.add + +> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +subtract from values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.add(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 31 ║ +╟───┼──────────────────────╢ +║ 1 │ 42 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 9 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +subtract from a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.add(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 5 ║ +╟───┼──────────────────────╢ +║ 3 │ 6 ║ +╟───┼──────────────────────╢ +║ 4 │ 7 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.and.md b/api-reference-v1-stable/series/series.and.md new file mode 100644 index 0000000..85c22cb --- /dev/null +++ b/api-reference-v1-stable/series/series.and.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical AND between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.and + +> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical AND between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.and(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.append.md b/api-reference-v1-stable/series/series.append.md new file mode 100644 index 0000000..9c84620 --- /dev/null +++ b/api-reference-v1-stable/series/series.append.md @@ -0,0 +1,135 @@ +--- +description: Add a new value or values to the end of a Series. +--- + +# Series.append + +danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | +| newValue | Array, Series | Object to append | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | +| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | + +**Returns:** + +** **return** Series** + +**** + +### **Append new Series to the end of a Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) + +new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) +new_sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ +``` +{% endtab %} +{% endtabs %} + +### **Append new Series to the end of a Series in-place** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) +let newIndex = ["f5", "f6", "f7"] + +sf1.append(sf2, newIndex, { inplace: true }) +sf1.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ +``` + +### **Append an array to the end of Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sfArr = ["a", "b", "c"] + +new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) +new_sf.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.apply.md b/api-reference-v1-stable/series/series.apply.md new file mode 100644 index 0000000..d5feb72 --- /dev/null +++ b/api-reference-v1-stable/series/series.apply.md @@ -0,0 +1,149 @@ +--- +description: Invoke a function on each value in a Series. +--- + +# Series.apply + +> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function | Function (can be anonymous) to apply | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns:** + +** **return** Series** + +**** + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +let apply_func = (x) => { + return x + x +} +sf.apply(apply_func).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 8 ║ +╟───┼──────────────────────╢ +║ 4 │ 10 ║ +╟───┼──────────────────────╢ +║ 5 │ 12 ║ +╟───┼──────────────────────╢ +║ 6 │ 14 ║ +╟───┼──────────────────────╢ +║ 7 │ 16 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +sf.apply(Math.log).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 0.6931471805599453 ║ +╟───┼──────────────────────╢ +║ 2 │ 1.0986122886681096 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.3862943611198906 ║ +╟───┼──────────────────────╢ +║ 4 │ 1.6094379124341003 ║ +╟───┼──────────────────────╢ +║ 5 │ 1.791759469228055 ║ +╟───┼──────────────────────╢ +║ 6 │ 1.9459101490553132 ║ +╟───┼──────────────────────╢ +║ 7 │ 2.0794415416798357 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) + +sf.apply((x)=>{ + return x.toLocaleLowerCase() +}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ rice ║ +╟───┼──────────────────────╢ +║ 1 │ beans ║ +╟───┼──────────────────────╢ +║ 2 │ yam ║ +╟───┼──────────────────────╢ +║ 3 │ banana ║ +╟───┼──────────────────────╢ +║ 4 │ wheat ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.argmax.md b/api-reference-v1-stable/series/series.argmax.md new file mode 100644 index 0000000..d7927d2 --- /dev/null +++ b/api-reference-v1-stable/series/series.argmax.md @@ -0,0 +1,35 @@ +--- +description: Returns the int position of the largest value in the series +--- + +# Series.argmax + +> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] + +**Parameters**: None + +**Returns**: int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,30,20,40,50,70,90,200,10,20,12] +let sf = new dfd.Series(data) + +sf.argmax() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +7 +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.argmin.md b/api-reference-v1-stable/series/series.argmin.md new file mode 100644 index 0000000..dfc661f --- /dev/null +++ b/api-reference-v1-stable/series/series.argmin.md @@ -0,0 +1,35 @@ +--- +description: Returns the int position of the smallest value in the series +--- + +# Series.argmin + +> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] + +**Parameters**: None + +**Returns**: int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,30,20,40,50,70,90,200,10,20,12] +let sf = new dfd.Series(data) + +sf.argmin() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +0 +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.argsort.md b/api-reference-v1-stable/series/series.argsort.md new file mode 100644 index 0000000..443935e --- /dev/null +++ b/api-reference-v1-stable/series/series.argsort.md @@ -0,0 +1,75 @@ +--- +description: Return the integer indices that would sort the Series values +--- + +# Series.argsort + +> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | +| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| + +**Returns: ** Series (int element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [10, 45, 20, 10, 23, 20, 30, 11] +let sf = new dfd.Series(data) + +sf.argsort().print() //defaults to ascending order +sf.argsort({ ascending: false }).print() + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 3 ║ +╟───┼──────────────────────╢ +║ 2 │ 7 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 4 ║ +╟───┼──────────────────────╢ +║ 6 │ 6 ║ +╟───┼──────────────────────╢ +║ 7 │ 1 ║ +╚═══╧══════════════════════╝ + +//sorted in descending order +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 6 ║ +╟───┼───╢ +║ 2 │ 4 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 3 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.astype.md b/api-reference-v1-stable/series/series.astype.md new file mode 100644 index 0000000..15a61ae --- /dev/null +++ b/api-reference-v1-stable/series/series.astype.md @@ -0,0 +1,2 @@ +# Series.astype + diff --git a/api-reference-v1-stable/series/series.copy.md b/api-reference-v1-stable/series/series.copy.md new file mode 100644 index 0000000..9bbdb47 --- /dev/null +++ b/api-reference-v1-stable/series/series.copy.md @@ -0,0 +1,45 @@ +--- +description: Makes a deep copy of a Series +--- + +# Series.copy + +> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] + +**parameter:** + +**Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) +let sf2 = sf1.copy() + +sf2.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30.21091 ║ +╟───┼──────────────────────╢ +║ 1 │ 40.190901 ║ +╟───┼──────────────────────╢ +║ 2 │ 3.564 ║ +╟───┼──────────────────────╢ +║ 3 │ 5.0212 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.corr.md b/api-reference-v1-stable/series/series.corr.md new file mode 100644 index 0000000..ee3263f --- /dev/null +++ b/api-reference-v1-stable/series/series.corr.md @@ -0,0 +1,2 @@ +# Series.corr + diff --git a/api-reference-v1-stable/series/series.count.md b/api-reference-v1-stable/series/series.count.md new file mode 100644 index 0000000..832c794 --- /dev/null +++ b/api-reference-v1-stable/series/series.count.md @@ -0,0 +1,36 @@ +--- +description: Obtain the total number of values in a series +--- + +# Series.count + +> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.count()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +9 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.cummax.md b/api-reference-v1-stable/series/series.cummax.md new file mode 100644 index 0000000..8aded1a --- /dev/null +++ b/api-reference-v1-stable/series/series.cummax.md @@ -0,0 +1,51 @@ +--- +description: Returns cumulative maximum over a series +--- + +# Series.cummax + +> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cummax().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 56 ║ +╟───┼──────────────────────╢ +║ 5 │ 56 ║ +╟───┼──────────────────────╢ +║ 6 │ 56 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cummin.md b/api-reference-v1-stable/series/series.cummin.md new file mode 100644 index 0000000..736cee5 --- /dev/null +++ b/api-reference-v1-stable/series/series.cummin.md @@ -0,0 +1,51 @@ +--- +description: Returns the cumulative min of a Series +--- + +# Series.cummin + +> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 5, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cummin().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 10 ║ +╟───┼──────────────────────╢ +║ 2 │ 10 ║ +╟───┼──────────────────────╢ +║ 3 │ 5 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 5 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumprod.md b/api-reference-v1-stable/series/series.cumprod.md new file mode 100644 index 0000000..84ec0e7 --- /dev/null +++ b/api-reference-v1-stable/series/series.cumprod.md @@ -0,0 +1,51 @@ +--- +description: Return the cumulative product of a series +--- + +# Series.cumprod + +> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cumprod().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 450 ║ +╟───┼──────────────────────╢ +║ 2 │ 25200 ║ +╟───┼──────────────────────╢ +║ 3 │ 630000 ║ +╟───┼──────────────────────╢ +║ 4 │ 14490000 ║ +╟───┼──────────────────────╢ +║ 5 │ 289800000 ║ +╟───┼──────────────────────╢ +║ 6 │ 2898000000 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumsum.md b/api-reference-v1-stable/series/series.cumsum.md new file mode 100644 index 0000000..7b7a19a --- /dev/null +++ b/api-reference-v1-stable/series/series.cumsum.md @@ -0,0 +1,74 @@ +--- +description: Return a cumulative sum of a series +--- + +# Series.cumsum + +> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cumsum().print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 55 ║ +╟───┼──────────────────────╢ +║ 2 │ 111 ║ +╟───┼──────────────────────╢ +║ 3 │ 136 ║ +╟───┼──────────────────────╢ +║ 4 │ 159 ║ +╟───┼──────────────────────╢ +║ 5 │ 179 ║ +╟───┼──────────────────────╢ +║ 6 │ 189 ║ +╚═══╧══════════════════════╝ +``` diff --git a/api-reference-v1-stable/series/series.describe.md b/api-reference-v1-stable/series/series.describe.md new file mode 100644 index 0000000..f532bac --- /dev/null +++ b/api-reference-v1-stable/series/series.describe.md @@ -0,0 +1,57 @@ +--- +description: >- + Generate descriptive statistics. Descriptive statistics include those that + summarize the central tendency, dispersion and shape of a dataset’s + distribution, excluding NaN values +--- + +# Series.describe + +> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] + +**Parameters: **No parameter + +**return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,2,3,4,5,6] +let sf = new dfd.Series(data) +sf.describe().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔══════════╤══════════════════════╗ +║ │ 0 ║ +╟──────────┼──────────────────────╢ +║ count │ 6 ║ +╟──────────┼──────────────────────╢ +║ mean │ 3.5 ║ +╟──────────┼──────────────────────╢ +║ std │ 1.8708286933869707 ║ +╟──────────┼──────────────────────╢ +║ min │ 1 ║ +╟──────────┼──────────────────────╢ +║ median │ 3.5 ║ +╟──────────┼──────────────────────╢ +║ max │ 6 ║ +╟──────────┼──────────────────────╢ +║ variance │ 3.5 ║ +╚══════════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.div.md b/api-reference-v1-stable/series/series.div.md new file mode 100644 index 0000000..656a796 --- /dev/null +++ b/api-reference-v1-stable/series/series.div.md @@ -0,0 +1,87 @@ +--- +description: >- + Return Floating division of series and other, element-wise (binary operator + truediv). +--- + +# Series.div + +> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +divide with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.div(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 20 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### divide with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.div(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0.5 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 1.5 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 2.5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dot.md b/api-reference-v1-stable/series/series.dot.md new file mode 100644 index 0000000..61a8bc2 --- /dev/null +++ b/api-reference-v1-stable/series/series.dot.md @@ -0,0 +1,2 @@ +# Series.dot + diff --git a/api-reference-v1-stable/series/series.drop_duplicates.md b/api-reference-v1-stable/series/series.drop_duplicates.md new file mode 100644 index 0000000..c169043 --- /dev/null +++ b/api-reference-v1-stable/series/series.drop_duplicates.md @@ -0,0 +1,121 @@ +--- +description: Remove duplicate rows +--- + +# Series.drop_duplicates + +> danfo.Series.**drop_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | +| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| + +**Returns: **Series + +**Examples** + +### Drop duplicate by keeping the first occurrence of the duplicate value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 10, 23, 20, 10, 10] +let sf = new dfd.Series(data1) +let sf_drop = sf.drop_duplicates() + +sf_drop.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop duplicate and keep only the last duplicated value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 10, 23, 20, 10, 10] +let sf = new dfd.Series(data1) +let sf_drop = sf.drop_duplicates({keep:"last"}) + +sf_drop.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Remove duplicate value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] +let sf = new dfd.Series(data1) +sf.drop_duplicates({inplace:true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ A ║ +╟───┼──────────────────────╢ +║ 3 │ B ║ +╟───┼──────────────────────╢ +║ 5 │ C ║ +╟───┼──────────────────────╢ +║ 7 │ D ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dropna.md b/api-reference-v1-stable/series/series.dropna.md new file mode 100644 index 0000000..2fab716 --- /dev/null +++ b/api-reference-v1-stable/series/series.dropna.md @@ -0,0 +1,91 @@ +--- +description: Remove missing values from Series +--- + +# Series.dropna + +> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| + +**Returns**: Series + +**Examples** + +### Drop all nan value and then return New Series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] +let sf = new dfd.Series(data1) +let sf_rep = sf.dropna() + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 3 │ 10 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop nan values in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] +let sf = new dfd.Series(data1) +sf.dropna({inplace:true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 3 │ 10 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.day.md b/api-reference-v1-stable/series/series.dt.day.md new file mode 100644 index 0000000..d3722c4 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.day.md @@ -0,0 +1,55 @@ +--- +description: Obtain the numerical representation of the week day. +--- + +# Series.dt.day + +> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] + +**Parameters**: None + +**Returns: **Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) +let sf = new dfd.Series(data) + +sf.dt.day().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ +``` diff --git a/api-reference-v1-stable/series/series.dt.hour.md b/api-reference-v1-stable/series/series.dt.hour.md new file mode 100644 index 0000000..9656aff --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.hour.md @@ -0,0 +1,52 @@ +--- +description: Obtain the hours in a time series +--- + +# Series.dt.hour + +> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] + +**Parameters: **None + +**Returns: **Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) +let sf = new dfd.Series(data) +// print series +sf.print() +// print hour series +sf.dt.hours().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 2:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.minute.md b/api-reference-v1-stable/series/series.dt.minute.md new file mode 100644 index 0000000..97baa73 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.minute.md @@ -0,0 +1,60 @@ +--- +description: Obtain the minutes in a Time Series +--- + +# Series.dt.minutes + +> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] + +**Parameters**: None + +**Returns: **Series (int Elements) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) +let sf = new dfd.Series(data) +//print the series +sf.print() +//print the minutes series +sf.dt.minutes().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 1:01:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2000, 1:02:00 AM ║ +╚═══╧══════════════════════╝ + +//print the minutes series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.month.md b/api-reference-v1-stable/series/series.dt.month.md new file mode 100644 index 0000000..09841bc --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.month.md @@ -0,0 +1,47 @@ +--- +description: Obtain the month in a date time series +--- + +# Series.dt.month + +> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] + +**Parameters**: None + +**Returns: **Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) +let sf = new dfd.Series(data) + +sf.dt.month().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 0 │ 6 ║ +╟───┼────╢ +║ 1 │ 7 ║ +╟───┼────╢ +║ 2 │ 9 ║ +╟───┼────╢ +║ 3 │ 9 ║ +╟───┼────╢ +║ 4 │ 11 ║ +╟───┼────╢ +║ 5 │ 11 ║ +╚═══╧════╝ +``` diff --git a/api-reference-v1-stable/series/series.dt.month_name.md b/api-reference-v1-stable/series/series.dt.month_name.md new file mode 100644 index 0000000..2deb259 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.month_name.md @@ -0,0 +1,55 @@ +--- +description: obtain the month name in a Time Series +--- + +# Series.dt.month_name + +> danfo.Series.dt.month_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] + +**Parameters**: None + +**Returns: **Series (String elements) + +**Examples** + +{% tabs %} +{% tab title="Output" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print month names +sf.dt.month_name().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2018, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 2/1/2018, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 3/1/2018, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═════╗ +║ 0 │ Jan ║ +╟───┼─────╢ +║ 1 │ Feb ║ +╟───┼─────╢ +║ 2 │ Mar ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.monthday.md b/api-reference-v1-stable/series/series.dt.monthday.md new file mode 100644 index 0000000..70026a5 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.monthday.md @@ -0,0 +1,55 @@ +--- +description: Obtain the day of the month +--- + +# Series.dt.monthday + +> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] + +**Parameters: **None + +**Returns**: Series (Int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print monthdays +sf.dt.monthday().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/2/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/3/2000, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.second.md b/api-reference-v1-stable/series/series.dt.second.md new file mode 100644 index 0000000..68d63b3 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.second.md @@ -0,0 +1,60 @@ +--- +description: Obtain the seconds in Date series +--- + +# Series.dt.seconds + +> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] + +**Parameters**: None + +**Returns: **Series (Int elements) + +**Example** + +Obtain the seconds of the datetime + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) +let sf = new dfd.Series(data) +//print the series frame +sf.print() + +//print the seconds obtained +sf.dt.seconds().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 1:00:01 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2000, 1:00:02 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.weekdays.md b/api-reference-v1-stable/series/series.dt.weekdays.md new file mode 100644 index 0000000..101bd50 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.weekdays.md @@ -0,0 +1,79 @@ +--- +description: Obtain the days of the weeks +--- + +# Series.dt.weekdays + +> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] + +**Parameters**: None + +**Returns: **Series (String elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print days of the week +sf.dt.weekdays().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ + +╔═══╤══════╗ +║ 0 │ Sat ║ +╟───┼──────╢ +║ 1 │ Sun ║ +╟───┼──────╢ +║ 2 │ Mon ║ +╟───┼──────╢ +║ 3 │ Tue ║ +╟───┼──────╢ +║ 4 │ Wed ║ +╟───┼──────╢ +║ 5 │ Thur ║ +╟───┼──────╢ +║ 6 │ Fri ║ +╟───┼──────╢ +║ 7 │ Sat ║ +╟───┼──────╢ +║ 8 │ Sun ║ +╟───┼──────╢ +║ 9 │ Mon ║ +╚═══╧══════╝ +``` diff --git a/api-reference-v1-stable/series/series.dt.year.md b/api-reference-v1-stable/series/series.dt.year.md new file mode 100644 index 0000000..db495d9 --- /dev/null +++ b/api-reference-v1-stable/series/series.dt.year.md @@ -0,0 +1,45 @@ +--- +description: Obtain the year in a date time series +--- + +# Series.dt.year + +> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] + +**Parameters**: None + +**Returns: **Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) +let sf = new dfd.Series(data) +sf.print() +sf.dt.year().print() +``` +{% endtab %} +{% endtabs %} + +``` +//print date time series +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2001, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2002, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤══════╗ +║ 0 │ 2000 ║ +╟───┼──────╢ +║ 1 │ 2001 ║ +╟───┼──────╢ +║ 2 │ 2002 ║ +╚═══╧══════╝ +``` diff --git a/api-reference-v1-stable/series/series.dtype.md b/api-reference-v1-stable/series/series.dtype.md new file mode 100644 index 0000000..c4634cb --- /dev/null +++ b/api-reference-v1-stable/series/series.dtype.md @@ -0,0 +1,34 @@ +--- +description: Obtain the dtype of a series +--- + +# Series.dtype + +> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] + +**Parameters**: None + +**Returns: **String + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.dtype) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.eq.md b/api-reference-v1-stable/series/series.eq.md new file mode 100644 index 0000000..43a3ece --- /dev/null +++ b/api-reference-v1-stable/series/series.eq.md @@ -0,0 +1,95 @@ +--- +description: Check all the values in a series is equal to another value +--- + +# Series.eq + +> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | + +**Returns**: Series (Boolean element) + +**Examples** + +Compare all the values in a series to another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.eq(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Check it all the values are equal to a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.eq(10).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.fillna.md b/api-reference-v1-stable/series/series.fillna.md new file mode 100644 index 0000000..a1db3a8 --- /dev/null +++ b/api-reference-v1-stable/series/series.fillna.md @@ -0,0 +1,106 @@ +--- +description: Replace all NaN value with specified value +--- + +# Series.fillna + +> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| + +**Examples** + +### Fill nan value and then return new series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] +let sf = new dfd.Series(data1) + +let sf_rep = sf.fillna({ value: -999}) + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -999 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 33 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 5 │ -999 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 7 ║ +╟───┼──────────────────────╢ +║ 9 │ 8 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Fill nan value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] +let sf = new dfd.Series(data1) +sf.fillna({ value: -999, inplace: true }) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -999 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 33 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 5 │ -999 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 7 ║ +╟───┼──────────────────────╢ +║ 9 │ 8 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ge.md b/api-reference-v1-stable/series/series.ge.md new file mode 100644 index 0000000..ec83ef9 --- /dev/null +++ b/api-reference-v1-stable/series/series.ge.md @@ -0,0 +1,95 @@ +--- +description: Check if all the values in a series is greater than or equal a value +--- + +# Series.ge + +> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns: **Series (Boolean element) + +**Example** + +Compare all the value in a Series to the values in another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.ge(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Check if all the value in a Series is greater than or equal a value. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.ge(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.gt.md b/api-reference-v1-stable/series/series.gt.md new file mode 100644 index 0000000..184ca28 --- /dev/null +++ b/api-reference-v1-stable/series/series.gt.md @@ -0,0 +1,95 @@ +--- +description: Check if all the value in a series is greater than a value +--- + +# Series.gt + +> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns**: Series (boolean element) + +**Example** + +Check if all the values in a series are greater than a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.gt(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are greater than values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.gt(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.head.md b/api-reference-v1-stable/series/series.head.md new file mode 100644 index 0000000..2892263 --- /dev/null +++ b/api-reference-v1-stable/series/series.head.md @@ -0,0 +1,51 @@ +--- +description: Obtain the first n rows for the object based on position. +--- + +# Series.head + +> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| rows | Int | number of first n values | 5 | + + **Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf1 = new dfd.Series(data1) + +sf1.head().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference-v1-stable/series/series.iloc.md b/api-reference-v1-stable/series/series.iloc.md new file mode 100644 index 0000000..ab578cf --- /dev/null +++ b/api-reference-v1-stable/series/series.iloc.md @@ -0,0 +1,158 @@ +# Series.iloc + +danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | + +**Returns:** + +** **return** Series** + +## **Examples** + +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). + +Allowed inputs are: + +* An integer, e.g. `5`. +* A list or array of integers, e.g. `[4, 3, 0]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `"1:7"` + +_**Note: **only** **the start label is included, and the end label is ignored. _ + +`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. + +### **Indexing specific rows by index** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc([0,5]).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 5 │ 30 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row** + +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(["0:5"]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 2.2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 30 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +By specifying a start index in a slice, all values after that index are returned. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(["5:"]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 5 │ 30 ║ +╟───┼──────────────────────╢ +║ 6 │ 2.1 ║ +╟───┼──────────────────────╢ +║ 7 │ 7 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference-v1-stable/series/series.index.md b/api-reference-v1-stable/series/series.index.md new file mode 100644 index 0000000..1cc95da --- /dev/null +++ b/api-reference-v1-stable/series/series.index.md @@ -0,0 +1,33 @@ +--- +description: Obtain the index of a Series +--- + +# Series.index + +> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] + +**Returns**: Array + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.index) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 0, 1, 2, 3 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.isna.md b/api-reference-v1-stable/series/series.isna.md new file mode 100644 index 0000000..cdf6343 --- /dev/null +++ b/api-reference-v1-stable/series/series.isna.md @@ -0,0 +1,45 @@ +--- +description: Detect Missing values +--- + +# Series.isna + +> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] + +**Parameters**: None + +**Returns**: Series \(Boolean element\) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, undefined, "girl", "Man"] +let sf = new dfd.Series(data1) + +sf.isna().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.le.md b/api-reference-v1-stable/series/series.le.md new file mode 100644 index 0000000..4571b72 --- /dev/null +++ b/api-reference-v1-stable/series/series.le.md @@ -0,0 +1,96 @@ +--- +description: Check if all the values in a series is less than or equal to a value +--- + +# Series.le + +> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns: **Series (Boolean Element) + +**Example** + +Check if all the values in a series is less than or equal to a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.le(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are less than equal to values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.le(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.loc.md b/api-reference-v1-stable/series/series.loc.md new file mode 100644 index 0000000..aa36e72 --- /dev/null +++ b/api-reference-v1-stable/series/series.loc.md @@ -0,0 +1,198 @@ +--- +description: Access a group of rows by label(s) or a boolean array. +--- + +# Series.loc + +danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | + +**Returns:** + +** **return** Series** + +## **Examples** + +`.loc()` is label position based (from `0` to `length-1` of the row axis). + +Allowed inputs are: + +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` + +_**Note: **only** **the start label is included, and the end label is ignored. _ + +`.loc` will raise a `ValueEror` if a requested label is not found. + +### **Indexing by specific row index** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc(["a", "g"]).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╟───┼─────╢ +║ e │ 30 ║ +╟───┼─────╢ +║ f │ 30 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╟───┼─────╢ +║ h │ 7 ║ +╚═══╧═════╝ + +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc([`"a":"e"`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +`s.loc([a:e]).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +`s.loc(["a":"e"]).print()`\ +\ +_**Inner quotes are not needed for numeric indices!**_ +{% endhint %} + +### By specifying a start index in a slice, all values after that index are returned. + +{% tabs %} +{% tab title="Node" %} +```javascript +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +let s = new dfd.Series(data) + +s.loc([`1:`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 1 │ 34 ║ +╟───┼─────╢ +║ 2 │ 2.2 ║ +╟───┼─────╢ +║ 3 │ 2 ║ +╟───┼─────╢ +║ 4 │ 30 ║ +╟───┼─────╢ +║ 5 │ 30 ║ +╟───┼─────╢ +║ 6 │ 2.1 ║ +╟───┼─────╢ +║ 7 │ 7 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} + +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.loc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference-v1-stable/series/series.lt.md b/api-reference-v1-stable/series/series.lt.md new file mode 100644 index 0000000..7af18bc --- /dev/null +++ b/api-reference-v1-stable/series/series.lt.md @@ -0,0 +1,96 @@ +--- +description: Check if all values in a Series are less than a value. +--- + +# Series.lt + +> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns**: Series (boolean element) + +**Example** + +Check if all the values in a series are less than a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.lt(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are less than values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.lt(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.map.md b/api-reference-v1-stable/series/series.map.md new file mode 100644 index 0000000..0e0850a --- /dev/null +++ b/api-reference-v1-stable/series/series.map.md @@ -0,0 +1,92 @@ +--- +description: Map the value of a series to a function or Object +--- + +# Series.map + +> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] + +| Parameter | Type | Description | Default | +| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function or Object | A function or object({}) | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Example** + +Mapping the element in a Series words in an Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4]) +let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } +sf.map(map).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ ok ║ +╟───┼──────────────────────╢ +║ 1 │ okie ║ +╟───┼──────────────────────╢ +║ 2 │ frit ║ +╟───┼──────────────────────╢ +║ 3 │ gop ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Mapping values in a Series to a representation using functions. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1,2,3,4]) + +sf.map((x)=>{ + return `I have ${x} cat(s)` +}).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ I have 1 cat(s) ║ +╟───┼──────────────────────╢ +║ 1 │ I have 2 cat(s) ║ +╟───┼──────────────────────╢ +║ 2 │ I have 3 cat(s) ║ +╟───┼──────────────────────╢ +║ 3 │ I have 4 cat(s) ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.max.md b/api-reference-v1-stable/series/series.max.md new file mode 100644 index 0000000..4f7193a --- /dev/null +++ b/api-reference-v1-stable/series/series.max.md @@ -0,0 +1,36 @@ +--- +description: Obtain the maximum value in a Series +--- + +# Series.max + +> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.max()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +89 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.maximum.md b/api-reference-v1-stable/series/series.maximum.md new file mode 100644 index 0000000..afc5a48 --- /dev/null +++ b/api-reference-v1-stable/series/series.maximum.md @@ -0,0 +1,50 @@ +--- +description: Obtain the maximum number between two series +--- + +# Series.maximum + +> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series | series to match | | + +**Return:** {Series} + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.maximum(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 41 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference-v1-stable/series/series.mean.md b/api-reference-v1-stable/series/series.mean.md new file mode 100644 index 0000000..17d97e6 --- /dev/null +++ b/api-reference-v1-stable/series/series.mean.md @@ -0,0 +1,36 @@ +--- +description: Obtain the mean of a series +--- + +# Series.mean + +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.mean()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +23.000001907348633 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.median.md b/api-reference-v1-stable/series/series.median.md new file mode 100644 index 0000000..d1cde75 --- /dev/null +++ b/api-reference-v1-stable/series/series.median.md @@ -0,0 +1,36 @@ +--- +description: Obtain the median of a series +--- + +# Series.median + +> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.median()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +4 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.min.md b/api-reference-v1-stable/series/series.min.md new file mode 100644 index 0000000..6e11a67 --- /dev/null +++ b/api-reference-v1-stable/series/series.min.md @@ -0,0 +1,36 @@ +--- +description: Obtain the minimum value in a series +--- + +# Series.min + +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.min()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +0 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.minimum.md b/api-reference-v1-stable/series/series.minimum.md new file mode 100644 index 0000000..a06ba69 --- /dev/null +++ b/api-reference-v1-stable/series/series.minimum.md @@ -0,0 +1,48 @@ +--- +description: Obtain the minimum value between two series (element wise) +--- + +# Series.minimum + +> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series | series to match | | + +**Return:** {Series} + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.minimum(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 40 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.mod.md b/api-reference-v1-stable/series/series.mod.md new file mode 100644 index 0000000..fdf0555 --- /dev/null +++ b/api-reference-v1-stable/series/series.mod.md @@ -0,0 +1,85 @@ +--- +description: Return Modulo of series and other, element-wise (binary operator mod). +--- + +# Series.mod + +> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] + +| Parameters | Type | Description | Default | +| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\|float | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +Modulus with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [2, 30, 4, 5] +let data2 = [1.1, 2.2, 3.3, 2.4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.mod(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0.8999999761581421 ║ +╟───┼──────────────────────╢ +║ 1 │ 1.3999993801116943 ║ +╟───┼──────────────────────╢ +║ 2 │ 0.7000000476837158 ║ +╟───┼──────────────────────╢ +║ 3 │ 0.19999980926513672 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Modulo with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.mod(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.mode.md b/api-reference-v1-stable/series/series.mode.md new file mode 100644 index 0000000..6077686 --- /dev/null +++ b/api-reference-v1-stable/series/series.mode.md @@ -0,0 +1,36 @@ +--- +description: Obtain the center value in a series +--- + +# Series.mode + +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.mode()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ 4 ] +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.mul.md b/api-reference-v1-stable/series/series.mul.md new file mode 100644 index 0000000..d5d33de --- /dev/null +++ b/api-reference-v1-stable/series/series.mul.md @@ -0,0 +1,86 @@ +--- +description: Return Multiplication of series and other, element-wise (binary operator mul). +--- + +# Series.mul + +> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +multiplication with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.mul(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 80 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 20 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +multiply with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.mul(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 8 ║ +╟───┼──────────────────────╢ +║ 4 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.ndim.md b/api-reference-v1-stable/series/series.ndim.md new file mode 100644 index 0000000..8258e46 --- /dev/null +++ b/api-reference-v1-stable/series/series.ndim.md @@ -0,0 +1,34 @@ +--- +description: Obtain the dimension of a series +--- + +# Series.ndim + +> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] + +**Parameters: **None + +**Returns: **int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.ndim) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +1 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ne.md b/api-reference-v1-stable/series/series.ne.md new file mode 100644 index 0000000..16cf1dc --- /dev/null +++ b/api-reference-v1-stable/series/series.ne.md @@ -0,0 +1,95 @@ +--- +description: Check if all values in a series is not equal to a value(s) +--- + +# Series.ne + +> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | + +**Returns**: Series (Boolean element) + +**Example** + +Compare all the values in a series to that in another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.ne(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Compare all the values in a Series to a value. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.ne(10).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.nunique.md b/api-reference-v1-stable/series/series.nunique.md new file mode 100644 index 0000000..1adfe98 --- /dev/null +++ b/api-reference-v1-stable/series/series.nunique.md @@ -0,0 +1,34 @@ +--- +description: Returns the number of unique values in a series +--- + +# Series.nunique + +> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] + +**Parameters**: None + +**Returns: **int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +console.log(sf.nunique()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Ouptut" %} +``` +9 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.or.md b/api-reference-v1-stable/series/series.or.md new file mode 100644 index 0000000..948c61d --- /dev/null +++ b/api-reference-v1-stable/series/series.or.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical OR between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.or + +> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical OR between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.or(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.pow.md b/api-reference-v1-stable/series/series.pow.md new file mode 100644 index 0000000..2fbe542 --- /dev/null +++ b/api-reference-v1-stable/series/series.pow.md @@ -0,0 +1,87 @@ +--- +description: >- + Return Exponential power of series and other, element-wise (binary operator + pow). +--- + +# Series.pow + +> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +Exponential power with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [2, 3, 4, 5] +let data2 = [1, 2, 3, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.pow(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 9 ║ +╟───┼──────────────────────╢ +║ 2 │ 64 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Exponential value with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.pow(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 16 ║ +╟───┼──────────────────────╢ +║ 4 │ 25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.replace.md b/api-reference-v1-stable/series/series.replace.md new file mode 100644 index 0000000..8a1f48b --- /dev/null +++ b/api-reference-v1-stable/series/series.replace.md @@ -0,0 +1,89 @@ +--- +description: Replace values given in replace param with value +--- + +# Series.replace + +> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| + +**Returns**: Series + +**Examples** + +### Replace a value in a series and return a new series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf = new dfd.Series(data1) +let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} + +### Replace a value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf = new dfd.Series(data1) +sf.replace({ oldValue: 10, newValue: -50, inplace: true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + +``` diff --git a/api-reference-v1-stable/series/series.reset_index.md b/api-reference-v1-stable/series/series.reset_index.md new file mode 100644 index 0000000..7ff93af --- /dev/null +++ b/api-reference-v1-stable/series/series.reset_index.md @@ -0,0 +1,113 @@ +--- +description: Reset the index of a series. +--- + +# Series.reset_index + +> danfo.series.reset_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object | **inplace: **Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | + +**Returns : **Series + +`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. + +### **Reset index to default values** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [20, 30, 40] +let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) +sf.print() + +let sf_reset = sf.reset_index() +sf_reset.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ a │ 20 ║ +╟───┼────╢ +║ b │ 30 ║ +╟───┼────╢ +║ c │ 40 ║ +╚═══╧════╝ + +╔═══╤════╗ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 2 │ 40 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Reset index to new values in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) +sf.print() + +sf.reset_index({ inplace: true }) +sf.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╟───┼───╢ +║ f │ 6 ║ +╚═══╧═══╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 4 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 6 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.round.md b/api-reference-v1-stable/series/series.round.md new file mode 100644 index 0000000..7b7ed7c --- /dev/null +++ b/api-reference-v1-stable/series/series.round.md @@ -0,0 +1,48 @@ +--- +description: round off floating values in series +--- + +# Series.round + +> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| dp | int | decimal place to round off to | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns: **Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +sf1.round(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30.21 ║ +╟───┼──────────────────────╢ +║ 1 │ 40.19 ║ +╟───┼──────────────────────╢ +║ 2 │ 3.56 ║ +╟───┼──────────────────────╢ +║ 3 │ 5.02 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.sample.md b/api-reference-v1-stable/series/series.sample.md new file mode 100644 index 0000000..762e635 --- /dev/null +++ b/api-reference-v1-stable/series/series.sample.md @@ -0,0 +1,65 @@ +--- +description: Return a random sample of items from an axis of object. +--- + +# Series.sample + +> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| num | Int | The number of rows to return. | | +| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| + +**Returns:** + +** **return** {Promies} resolves to Series** + +**Example** + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5) + sample.print() + +} +load_data() +``` + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤════╗ +║ 2 │ 3 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 0 │ 1 ║ +╟───┼────╢ +║ 7 │ 40 ║ +╟───┼────╢ +║ 6 │ 30 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Specify a seed when sampling + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5, { seed: 2 }) + sample.print() + +} +load_data() + +``` diff --git a/api-reference-v1-stable/series/series.set_index.md b/api-reference-v1-stable/series/series.set_index.md new file mode 100644 index 0000000..0b9cad9 --- /dev/null +++ b/api-reference-v1-stable/series/series.set_index.md @@ -0,0 +1,136 @@ +--- +description: Assign new Index to Series +--- + +# Series.set_index + +> danfo.series.**set_index(**options**) **\[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] + +| Parameter | Type | Description | Default | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| index | Array | new index values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns: **Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let sf = new dfd.Series(data) +sf.print() + +let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) +sf_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════════════════════════╗ +║ 0 │ {"alpha":"A","count":1} ║ +╟───┼─────────────────────────╢ +║ 1 │ {"alpha":"B","count":2} ║ +╟───┼─────────────────────────╢ +║ 2 │ {"alpha":"C","count":3} ║ +╚═══╧═════════════════════════╝ + +╔═══════╤═════════════════════════╗ +║ one │ {"alpha":"A","count":1} ║ +╟───────┼─────────────────────────╢ +║ two │ {"alpha":"B","count":2} ║ +╟───────┼─────────────────────────╢ +║ three │ {"alpha":"C","count":3} ║ +╚═══════╧═════════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["Humans","Life","Meaning","Fact","Truth"] +let sf = new dfd.Series(data) +let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) +sf_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ H │ Humans ║ +╟───┼──────────────────────╢ +║ L │ Life ║ +╟───┼──────────────────────╢ +║ M │ Meaning ║ +╟───┼──────────────────────╢ +║ F │ Fact ║ +╟───┼──────────────────────╢ +║ T │ Truth ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Set index in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data) +sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) +sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══════╤═══╗ +║ one │ 1 ║ +╟───────┼───╢ +║ two │ 2 ║ +╟───────┼───╢ +║ three │ 3 ║ +╟───────┼───╢ +║ four │ 4 ║ +╟───────┼───╢ +║ five │ 5 ║ +╟───────┼───╢ +║ six │ 6 ║ +╚═══════╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.shape.md b/api-reference-v1-stable/series/series.shape.md new file mode 100644 index 0000000..9eb5031 --- /dev/null +++ b/api-reference-v1-stable/series/series.shape.md @@ -0,0 +1,35 @@ +--- +description: Obtain the shape of a Series +--- + +# Series.shape + +> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] + +**Parameters**: None + +**Returns**: Array \[int, int\] + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.shape) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 4, 1 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.size.md b/api-reference-v1-stable/series/series.size.md new file mode 100644 index 0000000..9665b65 --- /dev/null +++ b/api-reference-v1-stable/series/series.size.md @@ -0,0 +1,37 @@ +--- +description: Obtain the size of a series +--- + +# Series.size + +> danfo.Series.size \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] + +**Parameters**: None + +**Returns:** int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.size) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +4 +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference-v1-stable/series/series.sort_values.md b/api-reference-v1-stable/series/series.sort_values.md new file mode 100644 index 0000000..5c7e5fa --- /dev/null +++ b/api-reference-v1-stable/series/series.sort_values.md @@ -0,0 +1,140 @@ +--- +description: Sorts a Series in ascending or descending order +--- + +# Series.sort_values + +> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| + + **Return:** Series + +### Sort values in a Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +let sf2 = sf1.sort_values() + +sf2.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Sort Series in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +sf1.sort_values({ inplace: true }) + +sf1.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ + +``` +{% endtab %} +{% endtabs %} + +Sort Series values in descending order + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +sf1.sort_values({ "ascending": false, "inplace": true }) + +sf1.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 6 │ 89 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 7 │ 0 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.std.md b/api-reference-v1-stable/series/series.std.md new file mode 100644 index 0000000..8d83e32 --- /dev/null +++ b/api-reference-v1-stable/series/series.std.md @@ -0,0 +1,39 @@ +--- +description: Obtain the standard deviation for a series +--- + +# Series.std + +> danfo.Series.std\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)\] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.std()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +31.11671576500322 +``` +{% endtab %} +{% endtabs %} + + **** + + + diff --git a/api-reference-v1-stable/series/series.str.capitalize.md b/api-reference-v1-stable/series/series.str.capitalize.md new file mode 100644 index 0000000..aea9e91 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.capitalize.md @@ -0,0 +1,52 @@ +--- +description: Capitalize the first character of each string +--- + +# Series.str.capitalize + +> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (String element) + +**Example** + +Convert the first character of a string to capital letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'capitals', 'sentence', 'swApCaSe'] +let sf = new dfd.Series(data) +sf.str.capitalize().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Lower boy ║ +╟───┼──────────────────────╢ +║ 1 │ Capitals ║ +╟───┼──────────────────────╢ +║ 2 │ Sentence ║ +╟───┼──────────────────────╢ +║ 3 │ Swapcase ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.charat.md b/api-reference-v1-stable/series/series.str.charat.md new file mode 100644 index 0000000..931bb48 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.charat.md @@ -0,0 +1,53 @@ +--- +description: Obtain the character at the specified index (position) +--- + +# Series.str.charAt + +> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| index | int | the index at which to obtain the character | 0 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (Character element) + +**Example** + +Obtain the character at index 2 of all string elements in the series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.charAt(2).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ w ║ +╟───┼──────────────────────╢ +║ 1 │ P ║ +╟───┼──────────────────────╢ +║ 2 │ n ║ +╟───┼──────────────────────╢ +║ 3 │ A ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.concat.md b/api-reference-v1-stable/series/series.str.concat.md new file mode 100644 index 0000000..2fa49d4 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.concat.md @@ -0,0 +1,165 @@ +--- +description: Joins two or more strings/arrays +--- + +# Series.str.concat + +> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] + +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| other | string or Array | string or list of strings to add to each string element of the series | "" | +| position | Int | The position to add the **other **(string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns: **Series (String element) + +**Examples** + +Add the strings from an Array to the start of each of the String element in Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat(data2,0).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ XXlower boy ║ +╟───┼──────────────────────╢ +║ 1 │ YYCAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ BBsentence ║ +╟───┼──────────────────────╢ +║ 3 │ 01SwApCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add the strings from an Array to the end of each of the String element in Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat(data2,1).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boyXX ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALSYY ║ +╟───┼──────────────────────╢ +║ 2 │ sentenceBB ║ +╟───┼──────────────────────╢ +║ 3 │ SwApCaSe01 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add a string to the start of each string element in a Series + +{% tabs %} +{% tab title="Output" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat("pre",0).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ prelower boy ║ +╟───┼──────────────────────╢ +║ 1 │ preCAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ presentence ║ +╟───┼──────────────────────╢ +║ 3 │ preSwApCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add a string to the end of each string element in a series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat("post",1).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boypost ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALSpost ║ +╟───┼──────────────────────╢ +║ 2 │ sentencepost ║ +╟───┼──────────────────────╢ +║ 3 │ SwApCaSepost ║ +╚═══╧══════════════════════╝ +``` diff --git a/api-reference-v1-stable/series/series.str.endswith.md b/api-reference-v1-stable/series/series.str.endswith.md new file mode 100644 index 0000000..2fb44cc --- /dev/null +++ b/api-reference-v1-stable/series/series.str.endswith.md @@ -0,0 +1,51 @@ +--- +description: Checks whether a string ends with specified characters +--- + +# Series.str.endsWith + +> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (Boolean element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.endsWith("e").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.includes.md b/api-reference-v1-stable/series/series.str.includes.md new file mode 100644 index 0000000..8918773 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.includes.md @@ -0,0 +1,51 @@ +--- +description: Checks whether a string contains the specified string/characters +--- + +# Series.str.includes + +> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (boolean element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.includes("C").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.indexof.md b/api-reference-v1-stable/series/series.str.indexof.md new file mode 100644 index 0000000..8328d8b --- /dev/null +++ b/api-reference-v1-stable/series/series.str.indexof.md @@ -0,0 +1,51 @@ +--- +description: the position of the first found occurrence of a specified value in a string +--- + +# Series.str.indexOf + +> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to obtain its index | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns: **Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.indexOf("C").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.join.md b/api-reference-v1-stable/series/series.str.join.md new file mode 100644 index 0000000..386da02 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.join.md @@ -0,0 +1,52 @@ +--- +description: Join a new string value to all string elements in a Series. +--- + +# Series.str.join + +> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| valToJoin | String | the string value you want to | "" | +| joinChar | String | The delimiter to specify the joining | " " | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + +** **return **Series** + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part', 'CAPITALS city', 'this is a sentence', 'SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.join("new", "_").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════════════════════════╗ +║ 0 │ lower part_new ║ +╟───┼────────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼────────────────────────╢ +║ 2 │ this is a sentence_new ║ +╟───┼────────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧════════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.lastindexof.md b/api-reference-v1-stable/series/series.str.lastindexof.md new file mode 100644 index 0000000..889a1f4 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.lastindexof.md @@ -0,0 +1,54 @@ +--- +description: >- + Obtain the position of the last found occurrence of a specified value in a + string +--- + +# Series.str.lastIndexOf + +danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.lastIndexOf("r").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4 ║ +╟───┼──────────────────────╢ +║ 1 │ -1 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.str.len.md b/api-reference-v1-stable/series/series.str.len.md new file mode 100644 index 0000000..0ef06b2 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.len.md @@ -0,0 +1,52 @@ +--- +description: Obtain the length of each string element in a Series +--- + +# Series.str.len + +> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Examples** + +Returns the length (number of character) of a string, and also return the length (number of elements) of Array + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["dog", 5,"cat","fog","mug","animals"] +let sf = new dfd.Series(data) +sf.str.len().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.repeat.md b/api-reference-v1-stable/series/series.str.repeat.md new file mode 100644 index 0000000..76f9073 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.repeat.md @@ -0,0 +1,51 @@ +--- +description: Repeat the the character(s) in a string for a specified number of time +--- + +# Series.str.repeat + +> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] + +| Parameters | Type | Description | Default | +| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | +| num | integer | the string to search for | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns: **Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['a', 'b', 'c', 'd'] +let sf = new dfd.Series(data) +sf.str.repeat(4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ aaaa ║ +╟───┼──────────────────────╢ +║ 1 │ bbbb ║ +╟───┼──────────────────────╢ +║ 2 │ cccc ║ +╟───┼──────────────────────╢ +║ 3 │ dddd ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.replace.md b/api-reference-v1-stable/series/series.str.replace.md new file mode 100644 index 0000000..da02575 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.replace.md @@ -0,0 +1,50 @@ +--- +description: Replace a word or character(s) in a String element +--- + +# Series.str.replace + +> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] + +| Parameters | Type | Description | Default | +| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| searchValue | string | String \| Character value to replace. Supports regex. | "" | +| replaceValue | String | string to replace the searched string | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns: **Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.replace("A", "XXX").print() +``` +{% endtab %} + +{% tab title="Browse" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower ║ +╟───┼──────────────────────╢ +║ 1 │ CXXXPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentence ║ +╟───┼──────────────────────╢ +║ 3 │ SwXXXpCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.search.md b/api-reference-v1-stable/series/series.str.search.md new file mode 100644 index 0000000..9dc48e0 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.search.md @@ -0,0 +1,94 @@ +--- +description: Obtain the index position of a searched character in a String +--- + +# Series.str.search + +> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] + + + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | String | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + +** **return Series: Series of index position + +**Example** + +obtain the index position for a character + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.search("S").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 8 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Obtain the index position for a searched word + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower city ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.search("city").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 10 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.slice.md b/api-reference-v1-stable/series/series.str.slice.md new file mode 100644 index 0000000..a807a36 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.slice.md @@ -0,0 +1,54 @@ +--- +description: Obtain the substring of each element in a series +--- + +# Series.str.slice + +> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + +** **return Series. + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.slice(2, 4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ we ║ +╟───┼──────────────────────╢ +║ 1 │ AP ║ +╟───┼──────────────────────╢ +║ 2 │ hi ║ +╟───┼──────────────────────╢ +║ 3 │ Sw ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.split.md b/api-reference-v1-stable/series/series.str.split.md new file mode 100644 index 0000000..8ba84b6 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.split.md @@ -0,0 +1,74 @@ +--- +description: >- + Split string around a given separator/delimiter. The array of strings are then + converted to a string. +--- + +# Series.str.split + +> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | +| splitVal | String | separator or delimiter used to split the string | " " | +| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| + +**Returns** + + return **Series** + +**Examples** + +Split the string value in the Series by space and obtain the Series values + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["king of the music","the lamba queen","I love the hat"] +let sf = new dfd.Series(data) +console.log(sf.str.split().values) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +**OUTPUT: **`[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["king_of_the_music","the_lamba_queen","I_love_the_hat"] +let sf = new dfd.Series(data) +sf.str.split("_").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ king,of,the,music ║ +╟───┼──────────────────────╢ +║ 1 │ the,lamba,queen ║ +╟───┼──────────────────────╢ +║ 2 │ I,love,the,hat ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.startswith.md b/api-reference-v1-stable/series/series.str.startswith.md new file mode 100644 index 0000000..6290122 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.startswith.md @@ -0,0 +1,51 @@ +--- +description: Test whether a string begins with specified characters +--- + +# Series.str.startsWith + +> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns: **Series (Boolean element) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.startsWith("S").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substr.md b/api-reference-v1-stable/series/series.str.substr.md new file mode 100644 index 0000000..bb58cfd --- /dev/null +++ b/api-reference-v1-stable/series/series.str.substr.md @@ -0,0 +1,50 @@ +--- +description: >- + Obtain the substring from a String element in a Series, by specifying the + number of string to obtain starting from a specific index. +--- + +# Series.str.substr + +> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| num | Number | The number of character to obtain starting from the startIndex | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + +** **return Series + +**Example** + +Obtain substring( containing 4 characters) starting from the third character (2nd index). + +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.substr(2, 4).print() +``` + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ wer ║ +╟───┼──────────────────────╢ +║ 1 │ APIT ║ +╟───┼──────────────────────╢ +║ 2 │ his ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substring.md b/api-reference-v1-stable/series/series.str.substring.md new file mode 100644 index 0000000..39bd460 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.substring.md @@ -0,0 +1,56 @@ +--- +description: Obtain the substring of each element in a series +--- + +# Series.str.substring + +> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns** + +** **return **Series** + +**Example** + +Obtain the substring from index 2 to index 4 of the string elements in a Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.substring(2, 4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ we ║ +╟───┼──────────────────────╢ +║ 1 │ AP ║ +╟───┼──────────────────────╢ +║ 2 │ hi ║ +╟───┼──────────────────────╢ +║ 3 │ Sw ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.tolowercase.md b/api-reference-v1-stable/series/series.str.tolowercase.md new file mode 100644 index 0000000..9abe0f5 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.tolowercase.md @@ -0,0 +1,50 @@ +--- +description: Converts all characters to lower case. +--- + +# Series.str.toLowerCase + +> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +Convert all characters in each string element to small letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['LOWER BOY', 'CAPITALS', 'SENTENCE', 'SWAPCASE'] +let sf = new dfd.Series(data) +sf.str.toLowerCase().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boy ║ +╟───┼──────────────────────╢ +║ 1 │ capitals ║ +╟───┼──────────────────────╢ +║ 2 │ sentence ║ +╟───┼──────────────────────╢ +║ 3 │ swapcase ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.touppercase.md b/api-reference-v1-stable/series/series.str.touppercase.md new file mode 100644 index 0000000..f484390 --- /dev/null +++ b/api-reference-v1-stable/series/series.str.touppercase.md @@ -0,0 +1,52 @@ +--- +description: Converts all characters to uppercase. +--- + +# Series.str.toUpperCase + +> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (String element) + +**Example** + +Convert all characters in each string element to capital letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.toUpperCase().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ LOWER BOY ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ SENTENCE ║ +╟───┼──────────────────────╢ +║ 3 │ SWAPCASE ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.trim.md b/api-reference-v1-stable/series/series.str.trim.md new file mode 100644 index 0000000..c5df92a --- /dev/null +++ b/api-reference-v1-stable/series/series.str.trim.md @@ -0,0 +1,50 @@ +--- +description: Remove leading and trailing Whitespace from a String element +--- + +# Series.str.trim + +> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + +** **return Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.trim().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower part ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS city ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentence ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp CaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.sub.md b/api-reference-v1-stable/series/series.sub.md new file mode 100644 index 0000000..e281d06 --- /dev/null +++ b/api-reference-v1-stable/series/series.sub.md @@ -0,0 +1,86 @@ +--- +description: Return Subtraction of series and other, element-wise (binary operator sub). +--- + +# Series.sub + +> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +subtract from values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.sub(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 29 ║ +╟───┼──────────────────────╢ +║ 1 │ 38 ║ +╟───┼──────────────────────╢ +║ 2 │ 0 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +subtract from a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.sub(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.sum.md b/api-reference-v1-stable/series/series.sum.md new file mode 100644 index 0000000..fabcba7 --- /dev/null +++ b/api-reference-v1-stable/series/series.sum.md @@ -0,0 +1,36 @@ +--- +description: Return the sum of the values in a series. +--- + +# Series.sum + +> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.sum()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +207 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference-v1-stable/series/series.tail.md b/api-reference-v1-stable/series/series.tail.md new file mode 100644 index 0000000..7f986a1 --- /dev/null +++ b/api-reference-v1-stable/series/series.tail.md @@ -0,0 +1,49 @@ +--- +description: Prints the last n values in a Series +--- + +# Series.tail + +> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| rows | Int | number of last n values | 5 | + + **Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf1 = new dfd.Series(data1) + +sf1.tail().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔════╤══════════════════════╗ +║ │ 0 ║ +╟────┼──────────────────────╢ +║ 6 │ 30 ║ +╟────┼──────────────────────╢ +║ 7 │ 40 ║ +╟────┼──────────────────────╢ +║ 8 │ 39 ║ +╟────┼──────────────────────╢ +║ 9 │ 89 ║ +╟────┼──────────────────────╢ +║ 10 │ 78 ║ +╚════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.tensor.md b/api-reference-v1-stable/series/series.tensor.md new file mode 100644 index 0000000..a5c112c --- /dev/null +++ b/api-reference-v1-stable/series/series.tensor.md @@ -0,0 +1,46 @@ +--- +description: Obtain the tensor representation of the values in a Series +--- + +# Series.tensor + +> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] + +**Parameters**: None + +**Returns**: Tensorflow tensor + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.tensor) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 4 ], + dtype: 'float32', + size: 4, + strides: [], + dataId: {}, + id: 2, + rankType: '1', + scopeId: 0 +} +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.unique.md b/api-reference-v1-stable/series/series.unique.md new file mode 100644 index 0000000..c89d187 --- /dev/null +++ b/api-reference-v1-stable/series/series.unique.md @@ -0,0 +1,55 @@ +--- +description: Obtain the unique value in a Series +--- + +# Series.unique + +> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] + +**Parameters**: None + +**Returns**: Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +sf.unique().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 6 ║ +╟───┼──────────────────────╢ +║ 6 │ 7 ║ +╟───┼──────────────────────╢ +║ 7 │ 8 ║ +╟───┼──────────────────────╢ +║ 8 │ 22 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.value_counts.md b/api-reference-v1-stable/series/series.value_counts.md new file mode 100644 index 0000000..e8d0ad7 --- /dev/null +++ b/api-reference-v1-stable/series/series.value_counts.md @@ -0,0 +1,54 @@ +--- +description: Count the number of occurrence for each element in a Series +--- + +# Series.value_counts + +> danfo.Series.value_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] + +**Parameters: **None + +**Returns: **Series (int element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +sf.value_counts().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤══════════════════════╗ +║ │ 0 ║ +╟────┼──────────────────────╢ +║ 1 │ 3 ║ +╟────┼──────────────────────╢ +║ 2 │ 1 ║ +╟────┼──────────────────────╢ +║ 3 │ 1 ║ +╟────┼──────────────────────╢ +║ 4 │ 1 ║ +╟────┼──────────────────────╢ +║ 5 │ 4 ║ +╟────┼──────────────────────╢ +║ 6 │ 1 ║ +╟────┼──────────────────────╢ +║ 7 │ 1 ║ +╟────┼──────────────────────╢ +║ 8 │ 2 ║ +╟────┼──────────────────────╢ +║ 22 │ 1 ║ +╚════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference-v1-stable/series/series.values.md b/api-reference-v1-stable/series/series.values.md new file mode 100644 index 0000000..4857487 --- /dev/null +++ b/api-reference-v1-stable/series/series.values.md @@ -0,0 +1,35 @@ +--- +description: Obtain the values in a series +--- + +# Series.values + +> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] + +**Parameters:** None + +**Returns**: Array + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.values) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 30.21091, 40.190901, 3.564, 5.0212 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference-v1-stable/series/series.var.md b/api-reference-v1-stable/series/series.var.md new file mode 100644 index 0000000..4fdcbc2 --- /dev/null +++ b/api-reference-v1-stable/series/series.var.md @@ -0,0 +1,35 @@ +--- +description: Calculate the variance of a Series +--- + +# Series.var + +> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.var()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +968.25 +``` +{% endtab %} +{% endtabs %} + From d736a00de23865ce18d0b805c5ca8eaab2468c59 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 2 Jan 2022 19:44:31 +0000 Subject: [PATCH 155/202] GitBook: No commit message --- .gitbook/assets/419Nr0T2ZmL.jpeg | Bin 0 -> 27488 bytes .gitbook/assets/B17076_Cover.jpg | Bin 0 -> 788502 bytes .../Screen Shot 2020-08-11 at 12.34.08 AM.png | Bin 0 -> 122541 bytes .../Screen Shot 2020-08-11 at 12.38.30 AM.png | Bin 0 -> 153263 bytes .../Screen Shot 2021-02-14 at 7.22.16 PM.png | Bin 0 -> 45524 bytes .gitbook/assets/image (2).png | Bin 0 -> 20104 bytes .gitbook/assets/newplot (1) (1).png | Bin 0 -> 25882 bytes .gitbook/assets/newplot (10).png | Bin 0 -> 14915 bytes .gitbook/assets/newplot (11).png | Bin 0 -> 25611 bytes .gitbook/assets/newplot (12).png | Bin 0 -> 22859 bytes .gitbook/assets/newplot (13).png | Bin 0 -> 39004 bytes .gitbook/assets/newplot (14).png | Bin 0 -> 12931 bytes .gitbook/assets/newplot (15).png | Bin 0 -> 10876 bytes .gitbook/assets/newplot (19).png | Bin 0 -> 55001 bytes .gitbook/assets/newplot (2).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot (20).png | Bin 0 -> 22185 bytes .gitbook/assets/newplot (21).png | Bin 0 -> 20622 bytes .gitbook/assets/newplot (22).png | Bin 0 -> 24563 bytes .gitbook/assets/newplot (23).png | Bin 0 -> 13536 bytes .gitbook/assets/newplot (24).png | Bin 0 -> 15366 bytes .gitbook/assets/newplot (25).png | Bin 0 -> 17992 bytes .gitbook/assets/newplot (26).png | Bin 0 -> 19369 bytes .gitbook/assets/newplot (27).png | Bin 0 -> 21985 bytes .gitbook/assets/newplot (3).png | Bin 0 -> 24476 bytes .gitbook/assets/newplot (32).png | Bin 0 -> 67128 bytes .gitbook/assets/newplot (4).png | Bin 0 -> 23001 bytes .gitbook/assets/newplot (5).png | Bin 0 -> 26223 bytes .gitbook/assets/newplot (6).png | Bin 0 -> 12968 bytes .gitbook/assets/newplot (7).png | Bin 0 -> 17397 bytes .gitbook/assets/newplot (9).png | Bin 0 -> 18874 bytes .gitbook/assets/newplot-29-.png | Bin 0 -> 50358 bytes api-reference/dataframe/README.md | 52 ++++++++-------- .../dataframe/danfo.dataframe.abs.md | 2 +- .../dataframe/danfo.dataframe.add.md | 10 +-- .../dataframe/danfo.dataframe.apply.md | 2 +- .../dataframe/danfo.dataframe.column.md | 2 +- .../dataframe/danfo.dataframe.copy.md | 2 +- .../dataframe/danfo.dataframe.count.md | 2 +- .../dataframe/danfo.dataframe.cummax.md | 2 +- .../dataframe/danfo.dataframe.cummin.md | 2 +- .../dataframe/danfo.dataframe.cumprod.md | 2 +- .../dataframe/danfo.dataframe.cumsum.md | 2 +- .../dataframe/danfo.dataframe.describe.md | 4 +- .../dataframe/danfo.dataframe.div.md | 10 +-- .../dataframe/danfo.dataframe.dropna.md | 8 +-- api-reference/dataframe/danfo.dataframe.eq.md | 8 +-- .../dataframe/danfo.dataframe.fillna.md | 8 +-- api-reference/dataframe/danfo.dataframe.ge.md | 10 +-- .../dataframe/danfo.dataframe.groupby.md | 4 +- api-reference/dataframe/danfo.dataframe.gt.md | 10 +-- .../dataframe/danfo.dataframe.head.md | 2 +- .../dataframe/danfo.dataframe.iloc.md | 4 +- .../dataframe/danfo.dataframe.isna.md | 2 +- api-reference/dataframe/danfo.dataframe.it.md | 10 +-- api-reference/dataframe/danfo.dataframe.le.md | 10 +-- .../dataframe/danfo.dataframe.loc.md | 12 ++-- .../dataframe/danfo.dataframe.max.md | 2 +- .../dataframe/danfo.dataframe.mean.md | 2 +- .../dataframe/danfo.dataframe.median.md | 2 +- .../dataframe/danfo.dataframe.min.md | 2 +- .../dataframe/danfo.dataframe.mod.md | 10 +-- .../dataframe/danfo.dataframe.mul.md | 10 +-- api-reference/dataframe/danfo.dataframe.ne.md | 8 +-- .../dataframe/danfo.dataframe.pow.md | 10 +-- .../dataframe/danfo.dataframe.replace.md | 6 +- .../dataframe/danfo.dataframe.round.md | 2 +- .../dataframe/danfo.dataframe.sample.md | 4 +- .../dataframe/danfo.dataframe.std.md | 2 +- .../dataframe/danfo.dataframe.sub.md | 10 +-- .../dataframe/danfo.dataframe.sum.md | 2 +- .../dataframe/danfo.dataframe.tail.md | 2 +- .../dataframe/danfo.dataframe.var.md | 2 +- api-reference/dataframe/dataframe.append.md | 3 +- .../dataframe/dataframe.apply_map.md | 8 +-- api-reference/dataframe/dataframe.astype.md | 4 +- api-reference/dataframe/dataframe.axes.md | 4 +- api-reference/dataframe/dataframe.drop.md | 4 +- api-reference/dataframe/dataframe.dtypes.md | 6 +- api-reference/dataframe/dataframe.index.md | 2 +- api-reference/dataframe/dataframe.ndim.md | 4 +- .../dataframe/dataframe.nunique-1.md | 4 +- api-reference/dataframe/dataframe.rename.md | 6 +- .../dataframe/dataframe.reset_index.md | 8 +-- .../dataframe/dataframe.select_dtypes.md | 6 +- api-reference/dataframe/dataframe.shape.md | 2 +- .../dataframe/dataframe.sort_index.md | 7 ++- .../dataframe/dataframe.sort_values.md | 8 +-- api-reference/dataframe/dataframe.tensor.md | 11 ++-- api-reference/dataframe/dataframe.to_csv.md | 20 +++--- api-reference/dataframe/dataframe.to_json.md | 19 +++--- api-reference/dataframe/dataframe.values.md | 4 +- .../general-functions/danfo.concat.md | 8 +-- .../general-functions/danfo.date_range.md | 6 +- .../general-functions/danfo.get_dummies.md | 6 +- .../general-functions/danfo.labelencoder.md | 8 +-- .../general-functions/danfo.merge.md | 4 +- .../general-functions/danfo.minmaxscaler.md | 4 +- .../general-functions/danfo.onehotencoder.md | 8 +-- .../general-functions/danfo.standardscaler.md | 4 +- api-reference/groupby/groupby.agg.md | 2 +- api-reference/groupby/groupby.max.md | 2 +- api-reference/input-output/danfo.read_csv.md | 21 +++---- api-reference/input-output/danfo.read_json.md | 19 +++--- api-reference/input-output/danfo.to_csv.md | 18 +++--- api-reference/input-output/danfo.to_json.md | 20 +++--- api-reference/plotting/bar-charts.md | 9 +-- api-reference/plotting/box-plots.md | 12 +--- .../plotting/configuring-your-plots.md | 9 ++- api-reference/plotting/histograms.md | 11 ++-- api-reference/plotting/line-charts.md | 11 ++-- api-reference/plotting/pie-charts.md | 12 ++-- api-reference/plotting/scatter-plots.md | 9 +-- api-reference/plotting/tables.md | 8 +-- api-reference/plotting/violin-plots.md | 10 +-- api-reference/series/README.md | 58 +++++++++--------- api-reference/series/series.abs.md | 2 +- api-reference/series/series.append.md | 2 +- api-reference/series/series.apply.md | 2 +- api-reference/series/series.argsort.md | 2 +- api-reference/series/series.describe.md | 2 +- .../series/series.drop_duplicates.md | 6 +- api-reference/series/series.dt.day.md | 2 +- api-reference/series/series.dt.hour.md | 4 +- api-reference/series/series.dt.minute.md | 2 +- api-reference/series/series.dt.month.md | 2 +- api-reference/series/series.dt.month_name.md | 6 +- api-reference/series/series.dt.monthday.md | 2 +- api-reference/series/series.dt.second.md | 2 +- api-reference/series/series.dt.weekdays.md | 2 +- api-reference/series/series.dt.year.md | 2 +- api-reference/series/series.dtype.md | 2 +- api-reference/series/series.ge.md | 2 +- api-reference/series/series.iloc.md | 10 +-- api-reference/series/series.le.md | 2 +- api-reference/series/series.loc.md | 10 +-- api-reference/series/series.ndim.md | 4 +- api-reference/series/series.nunique.md | 2 +- api-reference/series/series.reset_index.md | 8 +-- api-reference/series/series.round.md | 2 +- api-reference/series/series.sample.md | 2 +- api-reference/series/series.set_index.md | 6 +- api-reference/series/series.std.md | 8 +-- api-reference/series/series.str.concat.md | 4 +- api-reference/series/series.str.indexof.md | 2 +- api-reference/series/series.str.join.md | 2 +- api-reference/series/series.str.repeat.md | 2 +- api-reference/series/series.str.replace.md | 4 +- api-reference/series/series.str.search.md | 2 +- api-reference/series/series.str.slice.md | 2 +- api-reference/series/series.str.split.md | 4 +- api-reference/series/series.str.startswith.md | 2 +- api-reference/series/series.str.substr.md | 2 +- api-reference/series/series.str.substring.md | 2 +- api-reference/series/series.str.trim.md | 2 +- api-reference/series/series.value_counts.md | 8 +-- ...-driven-applications-with-danfo.js-book.md | 4 +- contributing-guide.md | 30 ++++----- examples/using-danfojs-in-react.md | 10 +-- getting-started.md | 34 +++++----- 159 files changed, 425 insertions(+), 456 deletions(-) create mode 100644 .gitbook/assets/419Nr0T2ZmL.jpeg create mode 100644 .gitbook/assets/B17076_Cover.jpg create mode 100644 .gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png create mode 100644 .gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png create mode 100644 .gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png create mode 100644 .gitbook/assets/image (2).png create mode 100644 .gitbook/assets/newplot (1) (1).png create mode 100644 .gitbook/assets/newplot (10).png create mode 100644 .gitbook/assets/newplot (11).png create mode 100644 .gitbook/assets/newplot (12).png create mode 100644 .gitbook/assets/newplot (13).png create mode 100644 .gitbook/assets/newplot (14).png create mode 100644 .gitbook/assets/newplot (15).png create mode 100644 .gitbook/assets/newplot (19).png create mode 100644 .gitbook/assets/newplot (2).png create mode 100644 .gitbook/assets/newplot (20).png create mode 100644 .gitbook/assets/newplot (21).png create mode 100644 .gitbook/assets/newplot (22).png create mode 100644 .gitbook/assets/newplot (23).png create mode 100644 .gitbook/assets/newplot (24).png create mode 100644 .gitbook/assets/newplot (25).png create mode 100644 .gitbook/assets/newplot (26).png create mode 100644 .gitbook/assets/newplot (27).png create mode 100644 .gitbook/assets/newplot (3).png create mode 100644 .gitbook/assets/newplot (32).png create mode 100644 .gitbook/assets/newplot (4).png create mode 100644 .gitbook/assets/newplot (5).png create mode 100644 .gitbook/assets/newplot (6).png create mode 100644 .gitbook/assets/newplot (7).png create mode 100644 .gitbook/assets/newplot (9).png create mode 100644 .gitbook/assets/newplot-29-.png diff --git a/.gitbook/assets/419Nr0T2ZmL.jpeg b/.gitbook/assets/419Nr0T2ZmL.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..971413ad50071b608398c7551e0239d86f2cabb1 GIT binary patch literal 27488 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/B17076_Cover.jpg b/.gitbook/assets/B17076_Cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..726b93975fa0f4ce1e945caadf90e2a89afa4306 GIT binary patch literal 788502 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

3asbLQP(U=Va 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%0A1Do4PB|KJ7fY5$?~Ays309W$8lRSdi$Di&m)=e} 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 YkSyyJ-CW^8lxx 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∓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

MihNsF=}1(*i3IoR)b$eqC>v?SjgKtRD0G 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

;+Yw>6)E$AqpJ0RVL>e+~fgb48lgWwX*n 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 aFSDGi+O`do{m;UG_T&E<4q*qs7XAzW9T^`0 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png b/.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png new file mode 100644 index 0000000000000000000000000000000000000000..c3bd79132eabdb3aff195ef0a4d9e6d2586cec1c GIT binary patch literal 122541 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png b/.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2cff59ec8ea308050242ca275b83c7658e545f GIT binary patch literal 153263 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


&$}-i#F~ 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 z

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace: **false} | +| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace:** false} | **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Drop rows (axis=0) with missing values +### Drop rows (axis=0) with missing values {% tabs %} {% tab title="Node" %} @@ -53,7 +53,7 @@ df_drop.print() {% endtab %} {% endtabs %} -### Drop columns (axis=1) with missing values +### Drop columns (axis=1) with missing values {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.eq.md b/api-reference/dataframe/danfo.dataframe.eq.md index a43fbd0..5f3cf2a 100644 --- a/api-reference/dataframe/danfo.dataframe.eq.md +++ b/api-reference/dataframe/danfo.dataframe.eq.md @@ -17,7 +17,7 @@ danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/da ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -102,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -147,7 +147,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing **** DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.fillna.md b/api-reference/dataframe/danfo.dataframe.fillna.md index 49aa13d..2ddb860 100644 --- a/api-reference/dataframe/danfo.dataframe.fillna.md +++ b/api-reference/dataframe/danfo.dataframe.fillna.md @@ -15,11 +15,11 @@ danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/openso **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Fill missing values in specified columns with specified values +### Fill missing values in specified columns with specified values Missing values are NaN, undefined or null values @@ -84,7 +84,7 @@ df_filled.print() {% endtab %} {% endtabs %} -### Fill all columns with NaNs with a specified value +### Fill all columns with NaNs with a specified value {% tabs %} {% tab title="Node" %} @@ -130,7 +130,7 @@ df_filled.print() {% endtab %} {% endtabs %} -### Fill NaNs inplace +### Fill NaNs inplace {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.ge.md b/api-reference/dataframe/danfo.dataframe.ge.md index 3b41ec3..8e5401b 100644 --- a/api-reference/dataframe/danfo.dataframe.ge.md +++ b/api-reference/dataframe/danfo.dataframe.ge.md @@ -15,11 +15,11 @@ danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/da **Returns:** -** DataFrame** + **DataFrame** ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -61,7 +61,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -106,7 +106,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -152,7 +152,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing **** DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.groupby.md b/api-reference/dataframe/danfo.dataframe.groupby.md index a31f095..e7d084f 100644 --- a/api-reference/dataframe/danfo.dataframe.groupby.md +++ b/api-reference/dataframe/danfo.dataframe.groupby.md @@ -12,7 +12,7 @@ danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja **Returns:** -** **return** DataFrame.groups** + **** return **DataFrame.groups** ## **Examples** @@ -78,7 +78,7 @@ A groupby operation will return a GroupBy class object. You can apply any of the 3. [std](danfo.dataframe.std.md) 4. [var](danfo.dataframe.var.md) 5. [mean](danfo.dataframe.mean.md) -6. [cumsum](danfo.dataframe.cumsum.md) +6. [cumsum](danfo.dataframe.cumsum.md) 7. [cummax](danfo.dataframe.cummax.md) 8. [cumprod](danfo.dataframe.cumprod.md) 9. [cummin](danfo.dataframe.cummin.md) diff --git a/api-reference/dataframe/danfo.dataframe.gt.md b/api-reference/dataframe/danfo.dataframe.gt.md index 121c7e7..ec3f7ba 100644 --- a/api-reference/dataframe/danfo.dataframe.gt.md +++ b/api-reference/dataframe/danfo.dataframe.gt.md @@ -13,11 +13,11 @@ danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9j **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -102,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -148,7 +148,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing **** DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.head.md b/api-reference/dataframe/danfo.dataframe.head.md index 10ae0f2..3fe62c4 100644 --- a/api-reference/dataframe/danfo.dataframe.head.md +++ b/api-reference/dataframe/danfo.dataframe.head.md @@ -12,7 +12,7 @@ danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfo **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index f8e0f4c..ffd7e25 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -12,7 +12,7 @@ danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfo **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** @@ -72,7 +72,7 @@ sub_df.print() ### **Index by a slice of row and return all columns** -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.isna.md b/api-reference/dataframe/danfo.dataframe.isna.md index b919db5..830bda5 100644 --- a/api-reference/dataframe/danfo.dataframe.isna.md +++ b/api-reference/dataframe/danfo.dataframe.isna.md @@ -11,7 +11,7 @@ danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.it.md b/api-reference/dataframe/danfo.dataframe.it.md index 69093a2..3759197 100644 --- a/api-reference/dataframe/danfo.dataframe.it.md +++ b/api-reference/dataframe/danfo.dataframe.it.md @@ -13,11 +13,11 @@ danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9j **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -104,7 +104,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -150,7 +150,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with an Array +### Comparing **** DataFrame with an Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.le.md b/api-reference/dataframe/danfo.dataframe.le.md index 0b88ff1..31ce3f7 100644 --- a/api-reference/dataframe/danfo.dataframe.le.md +++ b/api-reference/dataframe/danfo.dataframe.le.md @@ -15,11 +15,11 @@ danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -61,7 +61,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -106,7 +106,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -151,7 +151,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with an Array +### Comparing **** DataFrame with an Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index 88d7556..abdcdd9 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -12,7 +12,7 @@ danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfoj **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** @@ -25,7 +25,7 @@ Allowed inputs for are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` -_**Note: **only** **the start label is included, and the end label is ignored. _ +_**Note:** only **** the start label is included, and the end label is ignored._ `.loc` will raise a `ValueEror` if a requested label is not found. @@ -198,7 +198,7 @@ sub_df.print() ## **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. {% tabs %} {% tab title="Node" %} @@ -257,7 +257,7 @@ df``.loc({ row: [`"a":"e"`]}).print()``\ _**Inner**_ _**quotes are not needed for numeric indices!**_ {% endhint %} -### Slice DataFrame rows by boolean condition +### Slice DataFrame rows by boolean condition {% tabs %} {% tab title="Node" %} @@ -294,7 +294,7 @@ sub_df.print() ### Slice DataFrame rows by multiple boolean conditions {% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame._ {% endhint %} {% tabs %} @@ -330,7 +330,7 @@ sub_df.print() ### Slice DataFrame with boolean mask {% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ {% endhint %} {% tabs %} diff --git a/api-reference/dataframe/danfo.dataframe.max.md b/api-reference/dataframe/danfo.dataframe.max.md index f8e9124..a5c2119 100644 --- a/api-reference/dataframe/danfo.dataframe.max.md +++ b/api-reference/dataframe/danfo.dataframe.max.md @@ -12,7 +12,7 @@ danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.mean.md b/api-reference/dataframe/danfo.dataframe.mean.md index fbc005e..172cff5 100644 --- a/api-reference/dataframe/danfo.dataframe.mean.md +++ b/api-reference/dataframe/danfo.dataframe.mean.md @@ -12,7 +12,7 @@ danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.median.md b/api-reference/dataframe/danfo.dataframe.median.md index e75519f..3e33583 100644 --- a/api-reference/dataframe/danfo.dataframe.median.md +++ b/api-reference/dataframe/danfo.dataframe.median.md @@ -12,7 +12,7 @@ danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/ **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.min.md b/api-reference/dataframe/danfo.dataframe.min.md index 93b9bf8..49a13d6 100644 --- a/api-reference/dataframe/danfo.dataframe.min.md +++ b/api-reference/dataframe/danfo.dataframe.min.md @@ -12,7 +12,7 @@ danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index 8cd7e9f..18558e6 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -13,11 +13,11 @@ danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Modulo of** scalar with **DataFrame along default axis 1 +### Modulo of **scalar with** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -63,7 +63,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Modulo of** Series with **DataFrame along axis 0 +### Modulo of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -111,7 +111,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Modulo of** **DataFrame with a DataFrame +### Modulo of **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -161,7 +161,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Modulo of** ** Array with DataFrame along axis 0 +### Modulo of **** Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 3627b59..3303d77 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -13,11 +13,11 @@ danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Multiplication of** scalar to **DataFrame along default axis 1 +### Multiplication of **scalar to** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Multiplication of** Series to **DataFrame along axis 0 +### Multiplication of **Series to** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -106,7 +106,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Multiplication of** **DataFrame to a DataFrame +### Multiplication of **** DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -155,7 +155,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Multiplication of** ** Array to DataFrame along axis 0 +### Multiplication of **** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.ne.md b/api-reference/dataframe/danfo.dataframe.ne.md index 1996400..dd45cf0 100644 --- a/api-reference/dataframe/danfo.dataframe.ne.md +++ b/api-reference/dataframe/danfo.dataframe.ne.md @@ -17,7 +17,7 @@ danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/da ## **Examples** -### Comparing** **DataFrame with a scalar value: +### Comparing **** DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a Series along the column axis: +### Comparing **** DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -102,7 +102,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a DataFrame +### Comparing **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -148,7 +148,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing** **DataFrame with a JavaScript Array +### Comparing **** DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index 634e6e2..e6f1e6c 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -15,11 +15,11 @@ danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Exponential of** scalar with **DataFrame along default axis 1 +### Exponential of **scalar with** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -65,7 +65,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** Series with **DataFrame along axis 0 +### Exponential of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -113,7 +113,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** **DataFrame with a DataFrame +### Exponential of **** DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -163,7 +163,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Exponential of** ** Array with DataFrame along axis 0 +### Exponential of **** Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.replace.md b/api-reference/dataframe/danfo.dataframe.replace.md index 9a0b39f..82fa16d 100644 --- a/api-reference/dataframe/danfo.dataframe.replace.md +++ b/api-reference/dataframe/danfo.dataframe.replace.md @@ -10,11 +10,11 @@ description: Replaces values in a DataFrame with specified values | ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | | oldValue | String, boolean, Number | The value you want to replace | | | newValue | String, boolean, Number | The new value you want to replace the old value with | | -| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | +| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | **Returns:** -** **return** DataFrame** + **** return **DataFrame** **** @@ -63,7 +63,7 @@ df_rep.print() {% endtab %} {% endtabs %} -By not specifying a** **column**, **the** **replace works on all columns ** ** +By not specifying a **** column**,** the **** replace works on all columns **** {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.round.md b/api-reference/dataframe/danfo.dataframe.round.md index 32e7c8a..e12cb52 100644 --- a/api-reference/dataframe/danfo.dataframe.round.md +++ b/api-reference/dataframe/danfo.dataframe.round.md @@ -13,7 +13,7 @@ danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index 73e057a..b8a4c96 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -13,7 +13,7 @@ danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9j **Returns:** -** **return** {Promies} resolves to DataFrame** + **** return **{Promies} resolves to DataFrame** **** @@ -63,7 +63,7 @@ load_data() ## Sample a DataFrame randomly with seed -By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. +By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.std.md b/api-reference/dataframe/danfo.dataframe.std.md index b94372e..1a37e2e 100644 --- a/api-reference/dataframe/danfo.dataframe.std.md +++ b/api-reference/dataframe/danfo.dataframe.std.md @@ -12,7 +12,7 @@ danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index aded5cb..e36ddcc 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -13,11 +13,11 @@ danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Subtraction of** scalar to **DataFrame along default axis 1 +### Subtraction of **scalar to** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** Series to **DataFrame along axis 0 +### Subtraction of **Series to** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -106,7 +106,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** **DataFrame to a DataFrame +### Subtraction of **** DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -154,7 +154,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of** ** Array to DataFrame along axis 0 +### Subtraction of **** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.sum.md b/api-reference/dataframe/danfo.dataframe.sum.md index 515788b..3937d3f 100644 --- a/api-reference/dataframe/danfo.dataframe.sum.md +++ b/api-reference/dataframe/danfo.dataframe.sum.md @@ -12,7 +12,7 @@ danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.tail.md b/api-reference/dataframe/danfo.dataframe.tail.md index f317ba2..165acac 100644 --- a/api-reference/dataframe/danfo.dataframe.tail.md +++ b/api-reference/dataframe/danfo.dataframe.tail.md @@ -12,7 +12,7 @@ danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfo **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.var.md b/api-reference/dataframe/danfo.dataframe.var.md index b95bb1a..ea0daf2 100644 --- a/api-reference/dataframe/danfo.dataframe.var.md +++ b/api-reference/dataframe/danfo.dataframe.var.md @@ -12,7 +12,7 @@ danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index ae84a8b..bc2e29d 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -1,6 +1,7 @@ --- description: Adds new row to the end of a DataFrame --- + # DataFrame.append danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] @@ -13,7 +14,7 @@ danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danf **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/dataframe.apply_map.md b/api-reference/dataframe/dataframe.apply_map.md index 986566f..3819821 100644 --- a/api-reference/dataframe/dataframe.apply_map.md +++ b/api-reference/dataframe/dataframe.apply_map.md @@ -2,9 +2,9 @@ description: Apply a function to a Dataframe values element-wise. --- -# DataFrame.apply_map +# DataFrame.apply\_map -danfo.DataFrame.**apply_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.**apply\_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] | Parameters | Type | Description | Default | | ---------- | -------- | --------------------------------------------------------------------- | --------- | @@ -13,14 +13,14 @@ danfo.DataFrame.**apply_map**(callable, options) \[[source](https://github.com/o **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** ### Apply a function to all values in a DataFrame {% hint style="info" %} -Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. +Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. {% endhint %} {% tabs %} diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index fb388a3..e6434dc 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -12,7 +12,7 @@ danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/ **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** @@ -162,7 +162,7 @@ df_new.ctypes.print() {% endtab %} {% endtabs %} -**Note: **Casting a string column of alphabets/words to numeric form will return NaNs as values +**Note:** Casting a string column of alphabets/words to numeric form will return NaNs as values {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.axes.md b/api-reference/dataframe/dataframe.axes.md index 4bdc319..399a0a4 100644 --- a/api-reference/dataframe/dataframe.axes.md +++ b/api-reference/dataframe/dataframe.axes.md @@ -5,13 +5,13 @@ description: >- order. --- -# DataFrame.axes +# DataFrame.axis danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** -** **return** Object** + **** return **Object** ## **Examples** diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index 2376308..0b742aa 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -14,13 +14,13 @@ danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** ### Drop columns by specifying the names -By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.dtypes.md b/api-reference/dataframe/dataframe.dtypes.md index 6e856d5..791d296 100644 --- a/api-reference/dataframe/dataframe.dtypes.md +++ b/api-reference/dataframe/dataframe.dtypes.md @@ -11,11 +11,11 @@ danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/b **Returns:** -** **return** Series** + **** return **Series** ## **Examples** -Returns auto-generated** **index of a** **DataFrame +Returns auto-generated **** index of a **** DataFrame {% tabs %} {% tab title="Node" %} @@ -97,4 +97,4 @@ df.ctypes.print() {% endtab %} {% endtabs %} -**Note**: To cast a type, use the [astype](dataframe.astype.md) method. +**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference/dataframe/dataframe.index.md b/api-reference/dataframe/dataframe.index.md index 0983db8..a185e63 100644 --- a/api-reference/dataframe/dataframe.index.md +++ b/api-reference/dataframe/dataframe.index.md @@ -8,7 +8,7 @@ danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/bl ## **Examples** -Returns auto-generated** **index of a** **DataFrame +Returns auto-generated **** index of a **** DataFrame {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.ndim.md b/api-reference/dataframe/dataframe.ndim.md index 002da15..c64dd09 100644 --- a/api-reference/dataframe/dataframe.ndim.md +++ b/api-reference/dataframe/dataframe.ndim.md @@ -10,9 +10,9 @@ danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blo **Returns:** -** **return** Int** + **** return **Int** -**Note:** To get the **shape **of the DataFrame use the .[shape](dataframe.shape.md) property. +**Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. ## **Examples** diff --git a/api-reference/dataframe/dataframe.nunique-1.md b/api-reference/dataframe/dataframe.nunique-1.md index f06d4ed..8166904 100644 --- a/api-reference/dataframe/dataframe.nunique-1.md +++ b/api-reference/dataframe/dataframe.nunique-1.md @@ -8,7 +8,7 @@ danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** Series** + **** return **Series** ## **Examples** @@ -95,4 +95,4 @@ df.nunique(axis=0).print() {% endtab %} {% endtabs %} -**Note: **To get the unique elements along an axis, use** **[DataFrame.unique.](dataframe.nunique-1.md) +**Note:** To get the unique elements along an axis, use **** [DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference/dataframe/dataframe.rename.md b/api-reference/dataframe/dataframe.rename.md index 6625bc1..c33ce99 100644 --- a/api-reference/dataframe/dataframe.rename.md +++ b/api-reference/dataframe/dataframe.rename.md @@ -15,13 +15,13 @@ danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Rename columns +### Rename columns -By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.reset_index.md b/api-reference/dataframe/dataframe.reset_index.md index 00239fc..ddee8e0 100644 --- a/api-reference/dataframe/dataframe.reset_index.md +++ b/api-reference/dataframe/dataframe.reset_index.md @@ -2,17 +2,17 @@ description: Reset the index of the DataFrame, and use the default one instead. --- -# DataFrame.reset_index +# DataFrame.reset\_index -danfo.DataFrame.**reset_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**reset\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] | Parameters | Type | Description | Default | | ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | +| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/dataframe.select_dtypes.md b/api-reference/dataframe/dataframe.select_dtypes.md index 127b433..ba5044e 100644 --- a/api-reference/dataframe/dataframe.select_dtypes.md +++ b/api-reference/dataframe/dataframe.select_dtypes.md @@ -2,9 +2,9 @@ description: Return a subset of the DataFrame’s columns based on the column dtypes. --- -# DataFrame.select_dtypes +# DataFrame.select\_dtypes -danfo.DataFrame.**select_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] +danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] | Parameters | Type | Description | Default | | ---------- | ----- | -------------------------------- | ------- | @@ -12,7 +12,7 @@ danfo.DataFrame.**select_dtypes** \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/dataframe.shape.md b/api-reference/dataframe/dataframe.shape.md index 3e8486f..746491d 100644 --- a/api-reference/dataframe/dataframe.shape.md +++ b/api-reference/dataframe/dataframe.shape.md @@ -8,7 +8,7 @@ danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/bl **Returns:** -** **return** Int** + **** return **Int** ## **Examples** diff --git a/api-reference/dataframe/dataframe.sort_index.md b/api-reference/dataframe/dataframe.sort_index.md index 0829afe..81d5b7f 100644 --- a/api-reference/dataframe/dataframe.sort_index.md +++ b/api-reference/dataframe/dataframe.sort_index.md @@ -1,9 +1,10 @@ --- description: Sort DataFrame by index --- -# DataFrame.sort_index -DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] +# DataFrame.sort\_index + +DataFrame.**sort\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | @@ -11,7 +12,7 @@ DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/da **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 8da51fe..54345b1 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -2,17 +2,17 @@ description: Sort a Dataframe in ascending or descending order by a specified column name. --- -# DataFrame.sort_values +# DataFrame.sort\_values -danfo.DataFrame.**sort_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] | Parameters | Type | Description | Default | | ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | +| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/dataframe.tensor.md b/api-reference/dataframe/dataframe.tensor.md index 125198f..822886e 100644 --- a/api-reference/dataframe/dataframe.tensor.md +++ b/api-reference/dataframe/dataframe.tensor.md @@ -1,15 +1,18 @@ --- -description: Return a Tensorflow tensor representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. +description: >- + Return a Tensorflow tensor representation of the DataFrame. Only the values in + the DataFrame will be returned, the axes labels will be removed. --- + # DataFrame.tensor danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] **Returns:** -** **return** tf.tensor** + **** return **tf.tensor** -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. +> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. ## **Examples** @@ -52,7 +55,7 @@ Tensor {% endtab %} {% endtabs %} -String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. +String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index ee31a5e..8e84e9a 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -1,17 +1,19 @@ --- description: Convert DataFrame data to a comma-separated values (csv) --- -# DataFrame.to_csv -DataFrame.**to_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +# DataFrame.to\_csv -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| +DataFrame.**to\_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. +| | | | | +| -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| -**** +The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +*** ### Convert DataFrame to CSV string and return value @@ -69,7 +71,6 @@ Abs,Count,country code - ``` {% endtab %} {% endtabs %} @@ -98,7 +99,7 @@ df.to_csv({ filePath: "testOut.csv"}); ### Convert DataFrame to CSV string and download file in browser -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript let data = { @@ -111,4 +112,3 @@ let df = new dfd.DataFrame(data); df.to_csv({ fileName: "testOut.csv", download: true}); ``` - diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 59f7e34..326f422 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -1,15 +1,17 @@ --- description: Convert DataFrame to JSON format --- -# DataFrame.to_json -> DataFrame.**to_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] +# DataFrame.to\_json -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| +> DataFrame.**to\_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] -The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. +| | | | | +| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. ### Convert DataFrame/Series to JSON and return value @@ -82,12 +84,11 @@ console.log(jsonObj); - ``` {% endtab %} {% endtabs %} -### Convert DataFrame/Series to JSON and write to file path +### Convert DataFrame/Series to JSON and write to file path Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment @@ -111,7 +112,7 @@ df.to_json({ filePath: "./testOutput.json" }); ### Convert DataFrame/Series to JSON and download file in browser -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript let data = { diff --git a/api-reference/dataframe/dataframe.values.md b/api-reference/dataframe/dataframe.values.md index 6b7ea1d..598e395 100644 --- a/api-reference/dataframe/dataframe.values.md +++ b/api-reference/dataframe/dataframe.values.md @@ -8,9 +8,9 @@ danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/b **Returns:** -** **return** Array** + **** return **Array** -**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. +**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. ## **Examples** diff --git a/api-reference/general-functions/danfo.concat.md b/api-reference/general-functions/danfo.concat.md index 19c3d8e..e248f46 100644 --- a/api-reference/general-functions/danfo.concat.md +++ b/api-reference/general-functions/danfo.concat.md @@ -12,11 +12,11 @@ danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blo **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### **Concatenate two DataFrames along column axis (1) ** +### **Concatenate two DataFrames along column axis (1)** {% tabs %} {% tab title="Node" %} @@ -66,7 +66,7 @@ com_df.print() {% endtab %} {% endtabs %} -### **Concatenate two DataFrames along row axis (0) ** +### **Concatenate two DataFrames along row axis (0)** {% tabs %} {% tab title="Node" %} @@ -125,7 +125,7 @@ com_df.print(10) {% endtab %} {% endtabs %} -### **Concatenate two Series along row axis (0) ** +### **Concatenate two Series along row axis (0)** {% tabs %} {% tab title="Node" %} diff --git a/api-reference/general-functions/danfo.date_range.md b/api-reference/general-functions/danfo.date_range.md index 32d18b8..9c4a337 100644 --- a/api-reference/general-functions/danfo.date_range.md +++ b/api-reference/general-functions/danfo.date_range.md @@ -2,9 +2,9 @@ description: Return a fixed frequency Dates spread between start and end parameters. --- -# danfo.date_range +# danfo.date\_range -danfo.**date_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] | Parameters | Type | Description | Default | | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | @@ -12,7 +12,7 @@ danfo.**date_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index 793aa58..e53fd81 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -2,9 +2,9 @@ description: Convert categorical variable into dummy/indicator variables. --- -# danfo.get_dummies +# danfo.get\_dummies -danfo.**get_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**get\_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] | Parameters | Type | Description | Default | | ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | @@ -13,7 +13,7 @@ danfo.**get_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfoj **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/general-functions/danfo.labelencoder.md b/api-reference/general-functions/danfo.labelencoder.md index 12d57ee..b0745a8 100644 --- a/api-reference/general-functions/danfo.labelencoder.md +++ b/api-reference/general-functions/danfo.labelencoder.md @@ -4,11 +4,11 @@ description: Encode target labels with value between 0 and n_classes-1. # danfo.LabelEncoder -class danfo.**LabelEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. +danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. +The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. ## **Examples** @@ -137,4 +137,4 @@ LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } {% endtab %} {% endtabs %} -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) +See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference/general-functions/danfo.merge.md b/api-reference/general-functions/danfo.merge.md index 82a9a3d..0c4b760 100644 --- a/api-reference/general-functions/danfo.merge.md +++ b/api-reference/general-functions/danfo.merge.md @@ -14,7 +14,7 @@ danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** @@ -22,7 +22,7 @@ danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. -For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. +For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user\_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. ### **Merging by a single key found in both axis** diff --git a/api-reference/general-functions/danfo.minmaxscaler.md b/api-reference/general-functions/danfo.minmaxscaler.md index 06add63..d58af8b 100644 --- a/api-reference/general-functions/danfo.minmaxscaler.md +++ b/api-reference/general-functions/danfo.minmaxscaler.md @@ -4,13 +4,13 @@ description: Transform features by scaling each feature to a range of max and mi # danfo.MinMaxScaler -class danfo.**MinMaxScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). -The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. +The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index fdb8d4a..81c913d 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] -danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. +danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** @@ -145,4 +145,4 @@ new_sf.print() {% endtab %} {% endtabs %} -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) +See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 298d86e..89ce861 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -4,7 +4,7 @@ description: Standardize features by removing the mean and scaling to unit varia # danfo.StandardScaler -class danfo.**StandScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: @@ -12,7 +12,7 @@ danfo.js provides the StandardScaler class for the standardization of DataFrame where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. -The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. +The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. ## **Examples** diff --git a/api-reference/groupby/groupby.agg.md b/api-reference/groupby/groupby.agg.md index f9d6a5f..fae8802 100644 --- a/api-reference/groupby/groupby.agg.md +++ b/api-reference/groupby/groupby.agg.md @@ -10,7 +10,7 @@ description: Obtain data aggregate per groups for each column | ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | | kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | -**Return: **DataFrame +**Return:** DataFrame **Examples** diff --git a/api-reference/groupby/groupby.max.md b/api-reference/groupby/groupby.max.md index 6bebae5..43470f6 100644 --- a/api-reference/groupby/groupby.max.md +++ b/api-reference/groupby/groupby.max.md @@ -6,7 +6,7 @@ description: Obtain the maximum value of columns per groups > danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] -**Parameters: **None +**Parameters:** None **Returns**: DataFrame diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 79644f3..a291533 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -4,20 +4,21 @@ description: >- reading of CSV files in chunks. --- -# danfo.read_csv +# danfo.read\_csv -> danfo.**read_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] +> danfo.**read\_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] -| **Parameters** | Type | Description | Default | -| -------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | -| **configs**: | object, optional |

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

|

{

dynamicTyping: true,

header: true

}

| +| | | | | +| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | +| **configs**: | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

dynamicTyping: true,

header: true

}

| **Returns:** -** **_**Promise**_. Resolves to DataFrame +\*\* \*\*_**Promise**_. Resolves to DataFrame -The **read_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. +The **read\_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. ### **Reading files from local disk** @@ -42,7 +43,7 @@ dfd.read_csv("./user_names.csv") //assumes file is in CWD ### **Reading files from a URL** -By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: +By specifying a valid URL, you can load CSV files from any location into Danfo\*\*'\*\*s data structure: {% tabs %} {% tab title="Node.js" %} @@ -92,7 +93,6 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c - ``` {% endtab %} {% endtabs %} @@ -129,7 +129,6 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 85412ea..3c17457 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -2,20 +2,21 @@ description: Reads a JSON file into DataFrame. --- -# danfo.read_json +# danfo.read\_json -> danfo.**read_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] +> danfo.**read\_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] -| **Parameters** | Type | Description | Default | -| -------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| _**source**_ | Input file object, string file** **path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | -| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| +| | | | | +| -------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**source**_ | Input file object, string file\*\* \*\*path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | +| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| **Returns:** -** **_**Promise**_. Resolves to DataFrame +\*\* \*\*_**Promise**_. Resolves to DataFrame -The **read_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. +The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. ### **Reading JSON files from local disk** @@ -85,7 +86,6 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple - ``` {% endtab %} {% endtabs %} @@ -122,7 +122,6 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index 5bd4105..c3403cf 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -2,16 +2,17 @@ description: Writes a DataFrame or Series to CSV format. --- -# danfo.to_csv +# danfo.to\_csv -> danfo.**to_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] +> danfo.**to\_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| +| | | | | +| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| -The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. +The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. ### Convert DataFrame to CSV string and return value @@ -69,7 +70,6 @@ Abs,Count,country code - ``` {% endtab %} {% endtabs %} @@ -98,7 +98,7 @@ dfd.to_csv(df, { filePath: "testOut.csv"}); ### Convert DataFrame to CSV string and download file in Client-side lib -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript const dfd = require("danfojs") diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 80eaa04..baac615 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -1,13 +1,14 @@ -# danfo.to_json +# danfo.to\_json -> danfo.**to_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] +> danfo.**to\_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| +| | | | | +| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| -The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. +The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. ### Convert DataFrame/Series to JSON and return value @@ -80,12 +81,11 @@ console.log(jsonObj); - ``` {% endtab %} {% endtabs %} -### Convert DataFrame/Series to JSON and write to file path +### Convert DataFrame/Series to JSON and write to file path Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment @@ -109,7 +109,7 @@ dfd.to_json(df, { filePath: "./testOutput.json" }); ### Convert DataFrame/Series to JSON and download file in browser -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. ```javascript let data = { diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index aee82cd..6606bdc 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -8,7 +8,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti ## Examples -The **bar** plot is exposed by the .**plot\(\)** function called on a Series or DataFrame. The **.plot\(\)** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. +The **bar** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. ### Bar plot on Series @@ -36,10 +36,9 @@ The **bar** plot is exposed by the .**plot\(\)** function called on a Series or - ``` -![](../../.gitbook/assets/newplot-6-.png) +![](<../../.gitbook/assets/newplot (6).png>) ### Bar plot on DataFrame @@ -67,12 +66,10 @@ The **bar** plot is exposed by the .**plot\(\)** function called on a Series or - ``` -![](../../.gitbook/assets/newplot-7-.png) +![](<../../.gitbook/assets/newplot (7).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/plotting/box-plots.md b/api-reference/plotting/box-plots.md index 8a6e490..2adb60a 100644 --- a/api-reference/plotting/box-plots.md +++ b/api-reference/plotting/box-plots.md @@ -34,10 +34,9 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - ``` -![](../../.gitbook/assets/newplot-23-.png) +![](<../../.gitbook/assets/newplot (23).png>) ### Box plots on a DataFrame @@ -72,10 +71,9 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - ``` -![](../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am%20%281%29%20%281%29.png) +![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) ### Box plot for selected columns in a DataFrame @@ -109,14 +107,10 @@ Make a box-and-whisker plot from DataFrame columns, optionally grouped by some o - ``` -![](../../.gitbook/assets/newplot-24-.png) - - +![](<../../.gitbook/assets/newplot (24).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/plotting/configuring-your-plots.md b/api-reference/plotting/configuring-your-plots.md index 7d96b4d..4cedbb2 100644 --- a/api-reference/plotting/configuring-your-plots.md +++ b/api-reference/plotting/configuring-your-plots.md @@ -1,10 +1,10 @@ # Configuring your plots -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. -For example in the following code, we show how to set some basic configuration as well as layout for a line plot. +For example in the following code, we show how to set some basic configuration as well as layout for a line plot. ```markup @@ -65,5 +65,4 @@ For example in the following code, we show how to set some basic configuration a ``` -![](../../.gitbook/assets/newplot-32-.png) - +![](<../../.gitbook/assets/newplot (32).png>) diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 12497e3..adabd84 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -1,5 +1,5 @@ --- -description: 'Draw one histogram of the DataFrame’s columns, or single histogram for Series' +description: Draw one histogram of the DataFrame’s columns, or single histogram for Series --- # Histograms @@ -42,10 +42,9 @@ In the example below, we use the titanic dataset, to show a close to a real-worl - ``` -![](../../.gitbook/assets/newplot-10-.png) +![](<../../.gitbook/assets/newplot (10).png>) ### Customized Histogram plots on DataFrame @@ -89,14 +88,13 @@ In the example below, we use the titanic dataset, to show a close to a real-worl - ``` -![](../../.gitbook/assets/newplot-20-.png) +![](<../../.gitbook/assets/newplot (20).png>) ### Configuring your plots -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: @@ -117,4 +115,3 @@ df.plot("div_tag").histogram({layout: layout}) {% hint style="info" %} For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. {% endhint %} - diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 73326f4..79fe4d3 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -10,7 +10,7 @@ description: >- ### Basic Line plot on Series -The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. +The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. ```markup @@ -36,10 +36,9 @@ The **line** plot is exposed by the .**plot()** function called on a Series or D - ``` -![](../../.gitbook/assets/newplot-4-.png) +![](<../../.gitbook/assets/newplot (4).png>) ### Line plots on DataFrame @@ -70,10 +69,9 @@ The example below shows the plot of column values against a common x-axis (index - ``` -![](<../../.gitbook/assets/newplot-2- (1) (1) (2) (2).png>) +![](<../../.gitbook/assets/newplot (2).png>) The example below shows how to plot two columns in a DataFrame against each other. @@ -102,10 +100,9 @@ The example below shows how to plot two columns in a DataFrame against each othe - ``` -![](../../.gitbook/assets/newplot-3-.png) +![](<../../.gitbook/assets/newplot (3).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index c355bcb..6dce73d 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -39,10 +39,9 @@ A pie plot is a proportional representation of the numerical data in a column - ``` -![](../../.gitbook/assets/newplot-12-.png) +![](<../../.gitbook/assets/newplot (12).png>) ### Multiple Pie Chart from Columns in a DataFrame @@ -76,14 +75,13 @@ A pie plot is a proportional representation of the numerical data in a column - ``` -![](../../.gitbook/assets/newplot-21-.png) +![](<../../.gitbook/assets/newplot (21).png>) ### Configure Position of Pie Charts -If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. +If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. ```markup @@ -116,12 +114,10 @@ If you have more than one pie charts displayed, you can set the grid parameter, - ``` -![](../../.gitbook/assets/newplot-22-.png) +![](<../../.gitbook/assets/newplot (22).png>) {% hint style="info" %} For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. {% endhint %} - diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 739a49f..77649d1 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -4,7 +4,7 @@ description: Create a scatter plot of columns in a DataFrame # Scatter Plots -The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. +The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. ## Examples @@ -42,10 +42,9 @@ In the example below, we use the titanic dataset, to show a close to real-world - ``` -![](../../.gitbook/assets/newplot-8-%20%281%29.png) +![](<../../.gitbook/assets/newplot-8- (1) (1).png>) ### More Examples @@ -80,12 +79,10 @@ In the example below, we use the titanic dataset, to show a close to real-world - ``` -![](../../.gitbook/assets/newplot-19-.png) +![](<../../.gitbook/assets/newplot (19).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/plotting/tables.md b/api-reference/plotting/tables.md index efa1fbb..c67f0e2 100644 --- a/api-reference/plotting/tables.md +++ b/api-reference/plotting/tables.md @@ -43,11 +43,11 @@ description: Turn DataFrame/Series in D3.js-based tables ``` -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png) +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) ### Configure the header and cell of a table -To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. +To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. ```markup @@ -90,8 +90,6 @@ To configure the header and cell of a table, you can pass header/cell styles to - ``` -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png) - +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index e0c1c8f..a3e6c11 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -30,10 +30,9 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - ``` -![](../../.gitbook/assets/newplot-25-.png) +![](<../../.gitbook/assets/newplot (25).png>) ### Box plots on a DataFrame @@ -68,10 +67,9 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - ``` -![](../../.gitbook/assets/newplot-26-.png) +![](<../../.gitbook/assets/newplot (26).png>) ### Box plot for selected columns in a DataFrame @@ -105,12 +103,10 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu - ``` -![](../../.gitbook/assets/newplot-27-.png) +![](<../../.gitbook/assets/newplot (27).png>) {% hint style="info" %} To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} - diff --git a/api-reference/series/README.md b/api-reference/series/README.md index 7eefaa7..421bc63 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -4,7 +4,7 @@ description: One-dimensional ndarray with axis labels (including time series). # Series -> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ],** index: **\[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] +> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ], **index:** \[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] ### Attributes @@ -77,17 +77,17 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | | [`Series.unique`](series.unique.md) | Return unique values of Series object. | | [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value_counts.md) | Return a Series containing counts of unique values. | +| [`Series.value_counts`](series.value\_counts.md) | Return a Series containing counts of unique values. | ### Reindexing / selection / label manipulation -| | | -| ----------------------------------------------------- | -------------------------------------------------------- | -| [`Series.drop_duplicates`](series.drop_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | +| | | +| ------------------------------------------------------ | -------------------------------------------------------- | +| [`Series.drop_duplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | +| [`Series.head`](series.head.md) | Return the first n rows. | +| [`Series.reset_index`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | +| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | +| [`Series.tail`](series.tail.md) | Return the last n rows. | ### Missing data handling @@ -96,15 +96,15 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | | [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | | [`Series.isna`](series.isna.md) | Detect missing values. | -| [`Series.replace`](series.replace.md) | Replace values given in to_replace with value. | +| [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | ### Reshaping, sorting -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| --------------------------------------------- | ------------------------------------------------------------- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort_values.md) | Sort by the values. | +| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | +| ---------------------------------------------- | ------------------------------------------------------------- | +| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | +| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | +| [`Series.sort_values`](series.sort\_values.md) | Sort by the values. | ### Accessors @@ -121,16 +121,16 @@ Danfo provides dtype-specific methods under various accessors. These are separat **Datetime methods** -| | | -| ------------------------------------------------- | ------------------------------------------------------------------ | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | -| [`Series.dt.month_name`](series.dt.month_name.md) | Return the month names of the DateTimeIndex with specified locale. | +| | | +| -------------------------------------------------- | ------------------------------------------------------------------ | +| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | +| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | +| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | +| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | +| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | +| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | +| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | +| [`Series.dt.month_name`](series.dt.month\_name.md) | Return the month names of the DateTimeIndex with specified locale. | #### String handling @@ -176,7 +176,7 @@ Danfo provides dtype-specific methods under various accessors. These are separat ### Serialization / IO / conversion -| | | -| ----------------------------------------------------- | ---------------------------------------------------- | -| [`Series.to_csv`](../dataframe/dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | -| [`Series.to_json`](../dataframe/dataframe.to_json.md) | Convert the object to a JSON string. | +| | | +| ------------------------------------------------------ | ---------------------------------------------------- | +| [`Series.to_csv`](../dataframe/dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | +| [`Series.to_json`](../dataframe/dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index 3c9f46a..843dd5e 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -10,7 +10,7 @@ description: Returns the absolute value in a Series | ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | | options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Example** diff --git a/api-reference/series/series.append.md b/api-reference/series/series.append.md index 9c84620..53e8f03 100644 --- a/api-reference/series/series.append.md +++ b/api-reference/series/series.append.md @@ -14,7 +14,7 @@ danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/ **Returns:** -** **return** Series** + **** return **Series** **** diff --git a/api-reference/series/series.apply.md b/api-reference/series/series.apply.md index d5feb72..7f7050e 100644 --- a/api-reference/series/series.apply.md +++ b/api-reference/series/series.apply.md @@ -13,7 +13,7 @@ description: Invoke a function on each value in a Series. **Returns:** -** **return** Series** + **** return **Series** **** diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index 443935e..b4608a4 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -10,7 +10,7 @@ description: Return the integer indices that would sort the Series values | ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | | options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| -**Returns: ** Series (int element) +**Returns:** Series (int element) **Example** diff --git a/api-reference/series/series.describe.md b/api-reference/series/series.describe.md index f532bac..ce52246 100644 --- a/api-reference/series/series.describe.md +++ b/api-reference/series/series.describe.md @@ -9,7 +9,7 @@ description: >- > danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] -**Parameters: **No parameter +**Parameters:** No parameter **return:** Series diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index c169043..08edf09 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -2,15 +2,15 @@ description: Remove duplicate rows --- -# Series.drop_duplicates +# Series.drop\_duplicates -> danfo.Series.**drop_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] +> danfo.Series.**drop\_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] | Parameters | Type | Description | Default | | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | | options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Examples** diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index d3722c4..6461fa5 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -8,7 +8,7 @@ description: Obtain the numerical representation of the week day. **Parameters**: None -**Returns: **Series (int elements) +**Returns:** Series (int elements) **Examples** diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 9656aff..16369bb 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -6,9 +6,9 @@ description: Obtain the hours in a time series > danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] -**Parameters: **None +**Parameters:** None -**Returns: **Series (int elements) +**Returns:** Series (int elements) **Examples** diff --git a/api-reference/series/series.dt.minute.md b/api-reference/series/series.dt.minute.md index 97baa73..ea8bfee 100644 --- a/api-reference/series/series.dt.minute.md +++ b/api-reference/series/series.dt.minute.md @@ -8,7 +8,7 @@ description: Obtain the minutes in a Time Series **Parameters**: None -**Returns: **Series (int Elements) +**Returns:** Series (int Elements) **Example** diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index 09841bc..e21eeda 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -8,7 +8,7 @@ description: Obtain the month in a date time series **Parameters**: None -**Returns: **Series (int elements) +**Returns:** Series (int elements) **Examples** diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index 2deb259..4e83618 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -2,13 +2,13 @@ description: obtain the month name in a Time Series --- -# Series.dt.month_name +# Series.dt.month\_name -> danfo.Series.dt.month_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] +> danfo.Series.dt.month\_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] **Parameters**: None -**Returns: **Series (String elements) +**Returns:** Series (String elements) **Examples** diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index 70026a5..b385f17 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -6,7 +6,7 @@ description: Obtain the day of the month > danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] -**Parameters: **None +**Parameters:** None **Returns**: Series (Int elements) diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index 68d63b3..43330be 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -8,7 +8,7 @@ description: Obtain the seconds in Date series **Parameters**: None -**Returns: **Series (Int elements) +**Returns:** Series (Int elements) **Example** diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index 101bd50..04dbe18 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -8,7 +8,7 @@ description: Obtain the days of the weeks **Parameters**: None -**Returns: **Series (String elements) +**Returns:** Series (String elements) **Examples** diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index db495d9..ed1117f 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -8,7 +8,7 @@ description: Obtain the year in a date time series **Parameters**: None -**Returns: **Series (int elements) +**Returns:** Series (int elements) **Examples** diff --git a/api-reference/series/series.dtype.md b/api-reference/series/series.dtype.md index c4634cb..75b4614 100644 --- a/api-reference/series/series.dtype.md +++ b/api-reference/series/series.dtype.md @@ -8,7 +8,7 @@ description: Obtain the dtype of a series **Parameters**: None -**Returns: **String +**Returns:** String **Example** diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index ec83ef9..0fb1aeb 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -10,7 +10,7 @@ description: Check if all the values in a series is greater than or equal a valu | ---------- | ----------------------- | ------------------- | ------- | | other | Series, Array or number | value(s) to compare | | -**Returns: **Series (Boolean element) +**Returns:** Series (Boolean element) **Example** diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index ab578cf..ab7d1f3 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -8,7 +8,7 @@ danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob **Returns:** -** **return** Series** + **** return **Series** ## **Examples** @@ -21,7 +21,7 @@ Allowed inputs are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `"1:7"` -_**Note: **only** **the start label is included, and the end label is ignored. _ +_**Note:** only **** the start label is included, and the end label is ignored._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -61,7 +61,7 @@ s.iloc([0,5]).print() ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. {% tabs %} {% tab title="Node" %} @@ -99,7 +99,7 @@ s.iloc(["0:5"]).print() {% endtab %} {% endtabs %} -By specifying a start index in a slice, all values after that index are returned. +By specifying a start index in a slice, all values after that index are returned. {% tabs %} {% tab title="Node" %} @@ -133,7 +133,7 @@ s.iloc(["5:"]).print() {% endtab %} {% endtabs %} -### Slice Series by boolean condition +### Slice Series by boolean condition {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index 4571b72..44006e2 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -10,7 +10,7 @@ description: Check if all the values in a series is less than or equal to a valu | ---------- | ----------------------- | ------------------- | ------- | | other | Series, Array or number | value(s) to compare | | -**Returns: **Series (Boolean Element) +**Returns:** Series (Boolean Element) **Example** diff --git a/api-reference/series/series.loc.md b/api-reference/series/series.loc.md index aa36e72..13772ab 100644 --- a/api-reference/series/series.loc.md +++ b/api-reference/series/series.loc.md @@ -12,7 +12,7 @@ danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/ **Returns:** -** **return** Series** + **** return **Series** ## **Examples** @@ -25,7 +25,7 @@ Allowed inputs are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` -_**Note: **only** **the start label is included, and the end label is ignored. _ +_**Note:** only **** the start label is included, and the end label is ignored._ `.loc` will raise a `ValueEror` if a requested label is not found. @@ -85,7 +85,7 @@ s.loc(["a", "g"]).print() ### **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. {% tabs %} {% tab title="Node" %} @@ -132,7 +132,7 @@ For the slice above to work, you must quote each slice, e.g:\ _**Inner quotes are not needed for numeric indices!**_ {% endhint %} -### By specifying a start index in a slice, all values after that index are returned. +### By specifying a start index in a slice, all values after that index are returned. {% tabs %} {% tab title="Node" %} @@ -173,7 +173,7 @@ s.loc([`1:`]).print() {% endtab %} {% endtabs %} -### Slice Series by boolean condition +### Slice Series by boolean condition {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.ndim.md b/api-reference/series/series.ndim.md index 8258e46..8623e80 100644 --- a/api-reference/series/series.ndim.md +++ b/api-reference/series/series.ndim.md @@ -6,9 +6,9 @@ description: Obtain the dimension of a series > danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] -**Parameters: **None +**Parameters:** None -**Returns: **int +**Returns:** int **Example** diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 1adfe98..092a2eb 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -8,7 +8,7 @@ description: Returns the number of unique values in a series **Parameters**: None -**Returns: **int +**Returns:** int **Example** diff --git a/api-reference/series/series.reset_index.md b/api-reference/series/series.reset_index.md index 7ff93af..c51497a 100644 --- a/api-reference/series/series.reset_index.md +++ b/api-reference/series/series.reset_index.md @@ -2,15 +2,15 @@ description: Reset the index of a series. --- -# Series.reset_index +# Series.reset\_index -> danfo.series.reset_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] +> danfo.series.reset\_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] | Parameters | Type | Description | Default | | ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object | **inplace: **Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | -**Returns : **Series +**Returns :** Series `reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. diff --git a/api-reference/series/series.round.md b/api-reference/series/series.round.md index 7b7ed7c..b6f0d82 100644 --- a/api-reference/series/series.round.md +++ b/api-reference/series/series.round.md @@ -11,7 +11,7 @@ description: round off floating values in series | dp | int | decimal place to round off to | | | options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Example** diff --git a/api-reference/series/series.sample.md b/api-reference/series/series.sample.md index 762e635..a28298d 100644 --- a/api-reference/series/series.sample.md +++ b/api-reference/series/series.sample.md @@ -13,7 +13,7 @@ description: Return a random sample of items from an axis of object. **Returns:** -** **return** {Promies} resolves to Series** + **** return **{Promies} resolves to Series** **Example** diff --git a/api-reference/series/series.set_index.md b/api-reference/series/series.set_index.md index 0b9cad9..3de352f 100644 --- a/api-reference/series/series.set_index.md +++ b/api-reference/series/series.set_index.md @@ -2,16 +2,16 @@ description: Assign new Index to Series --- -# Series.set_index +# Series.set\_index -> danfo.series.**set_index(**options**) **\[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] +> danfo.series.**set\_index(**options**)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] | Parameter | Type | Description | Default | | --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | | index | Array | new index values | | | options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Example** diff --git a/api-reference/series/series.std.md b/api-reference/series/series.std.md index 8d83e32..aa05018 100644 --- a/api-reference/series/series.std.md +++ b/api-reference/series/series.std.md @@ -4,7 +4,7 @@ description: Obtain the standard deviation for a series # Series.std -> danfo.Series.std\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)\] +> danfo.Series.std() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)] **Parameter:** None @@ -27,13 +27,11 @@ console.log(sf1.std()) {% tabs %} {% tab title="Output" %} -```text +``` 31.11671576500322 ``` {% endtab %} {% endtabs %} - **** - - + **** diff --git a/api-reference/series/series.str.concat.md b/api-reference/series/series.str.concat.md index 2fa49d4..e3abe54 100644 --- a/api-reference/series/series.str.concat.md +++ b/api-reference/series/series.str.concat.md @@ -9,10 +9,10 @@ description: Joins two or more strings/arrays | Parameters | Type | Description | Default | | ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | | other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other **(string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +| position | Int | The position to add the **other** (string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | | options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns: **Series (String element) +**Returns:** Series (String element) **Examples** diff --git a/api-reference/series/series.str.indexof.md b/api-reference/series/series.str.indexof.md index 8328d8b..1d9e64f 100644 --- a/api-reference/series/series.str.indexof.md +++ b/api-reference/series/series.str.indexof.md @@ -11,7 +11,7 @@ description: the position of the first found occurrence of a specified value in | str | string | the string to obtain its index | "" | | options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Example** diff --git a/api-reference/series/series.str.join.md b/api-reference/series/series.str.join.md index 386da02..5bb77fe 100644 --- a/api-reference/series/series.str.join.md +++ b/api-reference/series/series.str.join.md @@ -14,7 +14,7 @@ description: Join a new string value to all string elements in a Series. **Returns:** -** **return **Series** + **** return **Series** **Examples** diff --git a/api-reference/series/series.str.repeat.md b/api-reference/series/series.str.repeat.md index 76f9073..703be26 100644 --- a/api-reference/series/series.str.repeat.md +++ b/api-reference/series/series.str.repeat.md @@ -11,7 +11,7 @@ description: Repeat the the character(s) in a string for a specified number of t | num | integer | the string to search for | 1 | | options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series **Example** diff --git a/api-reference/series/series.str.replace.md b/api-reference/series/series.str.replace.md index da02575..2b06b1f 100644 --- a/api-reference/series/series.str.replace.md +++ b/api-reference/series/series.str.replace.md @@ -4,7 +4,7 @@ description: Replace a word or character(s) in a String element # Series.str.replace -> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] +> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] | Parameters | Type | Description | Default | | ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | @@ -12,7 +12,7 @@ description: Replace a word or character(s) in a String element | replaceValue | String | string to replace the searched string | "" | | options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns: **Series +**Returns:** Series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.str.search.md b/api-reference/series/series.str.search.md index 9dc48e0..99fc428 100644 --- a/api-reference/series/series.str.search.md +++ b/api-reference/series/series.str.search.md @@ -15,7 +15,7 @@ description: Obtain the index position of a searched character in a String **Returns:** -** **return Series: Series of index position + **** return Series: Series of index position **Example** diff --git a/api-reference/series/series.str.slice.md b/api-reference/series/series.str.slice.md index a807a36..cef7a86 100644 --- a/api-reference/series/series.str.slice.md +++ b/api-reference/series/series.str.slice.md @@ -14,7 +14,7 @@ description: Obtain the substring of each element in a series **Returns:** -** **return Series. + **** return Series. **Example** diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 8ba84b6..006795d 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -15,7 +15,7 @@ description: >- **Returns** - return **Series** + return **Series** **Examples** @@ -38,7 +38,7 @@ console.log(sf.str.split().values) {% endtab %} {% endtabs %} -**OUTPUT: **`[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` +**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` {% tabs %} {% tab title="JavaScript" %} diff --git a/api-reference/series/series.str.startswith.md b/api-reference/series/series.str.startswith.md index 6290122..835809e 100644 --- a/api-reference/series/series.str.startswith.md +++ b/api-reference/series/series.str.startswith.md @@ -11,7 +11,7 @@ description: Test whether a string begins with specified characters | str | string | the character(s) to check | "" | | options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| -**Returns: **Series (Boolean element) +**Returns:** Series (Boolean element) **Examples** diff --git a/api-reference/series/series.str.substr.md b/api-reference/series/series.str.substr.md index bb58cfd..0a391bb 100644 --- a/api-reference/series/series.str.substr.md +++ b/api-reference/series/series.str.substr.md @@ -16,7 +16,7 @@ description: >- **Returns:** -** **return Series + **** return Series **Example** diff --git a/api-reference/series/series.str.substring.md b/api-reference/series/series.str.substring.md index 39bd460..b54702e 100644 --- a/api-reference/series/series.str.substring.md +++ b/api-reference/series/series.str.substring.md @@ -14,7 +14,7 @@ description: Obtain the substring of each element in a series **Returns** -** **return **Series** + **** return **Series** **Example** diff --git a/api-reference/series/series.str.trim.md b/api-reference/series/series.str.trim.md index c5df92a..58b7b16 100644 --- a/api-reference/series/series.str.trim.md +++ b/api-reference/series/series.str.trim.md @@ -12,7 +12,7 @@ description: Remove leading and trailing Whitespace from a String element **Returns:** -** **return Series + **** return Series {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.value_counts.md b/api-reference/series/series.value_counts.md index e8d0ad7..338064f 100644 --- a/api-reference/series/series.value_counts.md +++ b/api-reference/series/series.value_counts.md @@ -2,13 +2,13 @@ description: Count the number of occurrence for each element in a Series --- -# Series.value_counts +# Series.value\_counts -> danfo.Series.value_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] +> danfo.Series.value\_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] -**Parameters: **None +**Parameters:** None -**Returns: **Series (int element) +**Returns:** Series (int element) **Example** diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index 0bfd0a3..cf3e174 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -1,6 +1,6 @@ # Building Data Driven Applications with Danfo.js - Book -## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo _ code before 31st December 2020 and get 25% discount. +## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo_ code before 31st December 2020 and get 25% discount. ## What this book is about @@ -8,7 +8,7 @@ The book then shows you how to load different datasets, combine and analyze them By the end of this app development book, you'll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser. -![Danfo.js book cover](.gitbook/assets/b17076\_cover.jpg) +![Danfo.js book cover](.gitbook/assets/B17076\_Cover.jpg) ## **What you will learn** diff --git a/contributing-guide.md b/contributing-guide.md index 05d635b..4fedc98 100644 --- a/contributing-guide.md +++ b/contributing-guide.md @@ -29,9 +29,9 @@ description: >- ## TL:DR -All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome. +All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome. -For contributors familiar with open-source, below is a quick guide to setting up danfojs locally. +For contributors familiar with open-source, below is a quick guide to setting up danfojs locally. ``` git clone https://github.com/opensource9ja/danfojs.git @@ -39,7 +39,7 @@ cd danfojs git checkout -b ``` -There are two folders, **danfojs-browser** and **danfojs-node**. If you are contributing a new feature, then you should include it in both versions. If you are doing a bug fix for a single version, then open that folder and install packages. +There are two folders, **danfojs-browser** and **danfojs-node**. If you are contributing a new feature, then you should include it in both versions. If you are doing a bug fix for a single version, then open that folder and install packages. For instance, if I want to do some bug fixes in danfojs-node. I can do the following: @@ -87,11 +87,11 @@ cd danfojs This creates the directory danfojs and connects your repository to the upstream (main project) repository. -> **All development are done in two folders--**[**danfojs-browser**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-browser)** and **[**danfojs-node**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-node)** folders. The two folders are similar and it is always recommended to pull latest changes from master before development in any of the folder. ** +> **All development are done in two folders--**[**danfojs-browser**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-browser) **and** [**danfojs-node**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-node) **folders. The two folders are similar and it is always recommended to pull latest changes from master before development in any of the folder.** -Some Javascript features are supported both in the browser and node environment, and it is recommended to add these to both versions. +Some Javascript features are supported both in the browser and node environment, and it is recommended to add these to both versions. -For features that work only in NodeJs environment, especially file related issues, these should be developed and tested in the danfojs-node folder, and the corresponding tests are written there. +For features that work only in NodeJs environment, especially file related issues, these should be developed and tested in the danfojs-node folder, and the corresponding tests are written there. ## **Creating a development environment** @@ -205,7 +205,7 @@ describe("Name of the class|module", function(){ }); ``` -**Example**: Let write a test, to test if the values in a dataframe are off a certain length. Assuming the method to obtain length is values_len() +**Example**: Let write a test, to test if the values in a dataframe are off a certain length. Assuming the method to obtain length is values\_len() ```javascript import { assert } from "chai" @@ -236,7 +236,7 @@ describe("DataFrame", function(){ To run the test for the module you created, -**1)** Open the package.json +**1)** Open the package.json **2)** change the name of the test file to the file name you want. and don't forget the file is in the test folder @@ -245,7 +245,7 @@ To run the test for the module you created, "test": "....... danfojs/tests/sub_directory_name/filename", ``` -**3) **run the test, in the danfojs directory terminal +**3)** run the test, in the danfojs directory terminal ```python yarn test @@ -300,29 +300,29 @@ This request then goes to the repository maintainers, and they will review the c In other to contribute to the code base of danfojs, there are some functions and properties provided to make implementation easy. -The main exposed modules are the **Frame** and **Series** module. This module inherits from the **Generic **module. +The main exposed modules are the **Frame** and **Series** module. This module inherits from the **Generic** module. The **Generic** module consists of the following methods and properties * `.dtypes` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L213)] is used to obtain the dtype for each column * `.index` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L250)] to obtain the index for Dataframe or Series -* `.__set_index(label) ` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L257)] to set the index value +* `.__set_index(label)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L257)] to set the index value * `.__reset_index()` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L271)] to reset the index in DataFrame and Series -* `.values ` Obtain the values in DataFrame and Series per rows +* `.values` Obtain the values in DataFrame and Series per rows * `.col_data` Obtain the values in DataFrame and Series per columns * `.column_names` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)] Obtain the list of column names * `.__set_col_types` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L165)] set the dtype for a column or infer the dtype from it * `.columns` to access the column names directly * `row_data_tensor` store the tensor representation of the data in DataFrame and Series -The **Frame **module consists of the following methods and properties to aid implementation. +The **Frame** module consists of the following methods and properties to aid implementation. * `__frame_is_compactible_for_operation` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1754)]: check if all the values in a DataFrame are numerical. This helps to check if the numerical operation can be done using the dataframe. * `.__get_ops_tensors(tensors, axis)` \[[source\]](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1767) : obtain tensors from dataframes along axis 0 or 1. -* `.__get_df_from_tensor(val, col_names) ` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1741)]: Obtain dataframe from tensor. +* `.__get_df_from_tensor(val, col_names)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1741)]: Obtain dataframe from tensor. * `.__get_tensor_and_idx(df, axis)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L928)]: Obtain tensors, their index value and their axis from dataframe. -The **Series **module contains mostly Generic properties and less special internal properties. +The **Series** module contains mostly Generic properties and less special internal properties. * `__check_series_op_compactibility(other)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L666)] check if two series are compatible for numerical operation diff --git a/examples/using-danfojs-in-react.md b/examples/using-danfojs-in-react.md index b11ca0c..3f97b10 100644 --- a/examples/using-danfojs-in-react.md +++ b/examples/using-danfojs-in-react.md @@ -1,10 +1,10 @@ # Using Danfojs in React -**TL:DR **See Example react application using danfojs [here](https://github.com/opensource9ja/Data-aRT) +**TL:DR** See Example react application using danfojs [here](https://github.com/opensource9ja/Data-aRT) -Danfojs works for both browser and NodeJs environment, and as such is available to frontend frameworks like React and Vue. +Danfojs works for both browser and NodeJs environment, and as such is available to frontend frameworks like React and Vue. -In order to use Danfojs in a library like React, you must install the [browser side version ](https://www.npmjs.com/package/danfojs)from npm. +In order to use Danfojs in a library like React, you must install the [browser side version ](https://www.npmjs.com/package/danfojs)from npm. ```bash npm install danfojs @@ -58,7 +58,7 @@ export default App; On running the app, we get the following output in the console: -![](../.gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png) +![](<../.gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png>) Note that you can also import specific modules. For instance, in the code below we import only the DataFrame module: @@ -66,4 +66,4 @@ Note that you can also import specific modules. For instance, in the code below import { DataFrame } from "danfojs/src/index"; ``` -Following these steps, you can use danfojs in any client-side library. +Following these steps, you can use danfojs in any client-side library. diff --git a/getting-started.md b/getting-started.md index 438fddd..9388ab0 100644 --- a/getting-started.md +++ b/getting-started.md @@ -42,7 +42,7 @@ To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://d ## 10 minutes to danfo.js -This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html#min) +This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user\_guide/10min.html#min) We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. @@ -392,7 +392,7 @@ df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The columns of the resulting [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) have different [dtypes](https://pandas.pydata.org/pandas-docs/stable/user_guide/basics.html#basics-dtypes). +The columns of the resulting [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) have different [dtypes](https://pandas.pydata.org/pandas-docs/stable/user\_guide/basics.html#basics-dtypes). ```javascript df.ctypes.print() @@ -578,9 +578,9 @@ console.log(df.columns); [ 'A', 'B', 'C', 'D', 'E' ] ``` -[`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy) returns a Tensorflow tensor representation of the underlying data. Note that **Tensorflow tensors have one dtype for the entire array, while danfo DataFrames have one dtype per column**. +[`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to\_numpy.html#pandas.DataFrame.to\_numpy) returns a Tensorflow tensor representation of the underlying data. Note that **Tensorflow tensors have one dtype for the entire array, while danfo DataFrames have one dtype per column**. -For `df`, our [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) of all floating-point values, [`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy)is fast and doesn’t require copying data. +For `df`, our [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame) of all floating-point values, [`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to\_numpy.html#pandas.DataFrame.to\_numpy)is fast and doesn’t require copying data. {% tabs %} {% tab title="Node" %} @@ -660,7 +660,7 @@ Tensor **Note** -[`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy) does _not_ include the index or column labels in the output. +[`DataFrame.tensor`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to\_numpy.html#pandas.DataFrame.to\_numpy) does _not_ include the index or column labels in the output. [`describe()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.describe.html#pandas.DataFrame.describe) shows a quick statistic summary of your data: @@ -1130,7 +1130,7 @@ sub_df.print() #### Selection with Boolean Mask -You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. +You can select subsections from a DataFrame by a booelan condition mask. E.g. In the following code, we select and return only rows where the column `Count` is greater than 10. ```javascript let data = { @@ -1156,7 +1156,7 @@ sub_df.print() ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. +A Boolean mask for filtering also works for multiple conditions using `and` & `or` functions. E.g, In the following code, we select and return only rows where the column `Count` is greater than 10 and column `Name` is equal to `Apples`. ```javascript let sub_df = df.iloc({ @@ -1296,7 +1296,6 @@ query_df.print() //after query ║ 0 │ Ng │ 34 │ 20 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` #### Adding a new column @@ -1391,7 +1390,7 @@ df.print() ### Missing data - **NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +**NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. To drop any rows that have missing data: @@ -1513,7 +1512,6 @@ df_drop.print() ╟────────────┼───────────────────╢ ║ 3 │ 78 ║ ╚════════════╧═══════════════════╝ - ``` Filling missing data: @@ -1802,7 +1800,7 @@ df_new.print() Applying Element wise operations to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1975,7 +1973,7 @@ com_df.print() #### Join -SQL style merges. See the Pandas [Database style joining](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html#merging-join) section for more info. +SQL style merges. See the Pandas [Database style joining](https://pandas.pydata.org/pandas-docs/stable/user\_guide/merging.html#merging-join) section for more info. ```javascript const dfd = require("danfojs-node") @@ -2333,9 +2331,9 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe #### CSV -[Writing to a CSV file.](api-reference/dataframe/dataframe.to_csv.md) +[Writing to a CSV file.](api-reference/dataframe/dataframe.to\_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. ```javascript const dfd = require("danfojs-node") @@ -2362,7 +2360,6 @@ df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version - ``` ``` @@ -2372,9 +2369,9 @@ Abs,Count,country code 47.3,5,GH ``` -[Reading from a CSV file.](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-read-csv-table) +[Reading from a CSV file.](https://pandas.pydata.org/pandas-docs/stable/user\_guide/io.html#io-read-csv-table) -The **read_csv** method can read CSV file from local disk, or over the internet. If the file is to be read from a local disk in Node environment, you have to prefix the full path name with a "**file://**" prefix. For instance, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: +The **read\_csv** method can read CSV file from local disk, or over the internet. If the file is to be read from a local disk in Node environment, you have to prefix the full path name with a "**file://**" prefix. For instance, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: {% tabs %} {% tab title="JavaScript" %} @@ -2429,7 +2426,7 @@ dfd.read_csv("file:///home/Desktop/titanic.csv") #### JSON -Writing to [JSON](api-reference/dataframe/dataframe.to_json.md) format +Writing to [JSON](api-reference/dataframe/dataframe.to\_json.md) format ```javascript const dfd = require("danfojs-node") @@ -2461,5 +2458,4 @@ console.log(json); Count: [ 34, 4, 5 ], 'country code': [ 'NG', 'FR', 'GH' ] } - ``` From 3c4ff683ce05c67bfc0081f49aac1d92db16d1ce Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 2 Jan 2022 21:14:35 +0100 Subject: [PATCH 156/202] clean up --- api-reference-v1-stable/README.md | 54 --- .../configuration-options.md | 128 ----- api-reference-v1-stable/dataframe/README.md | 145 ------ .../dataframe/creating-a-dataframe.md | 355 -------------- .../dataframe/danfo.dataframe.abs.md | 74 --- .../dataframe/danfo.dataframe.add.md | 246 ---------- .../dataframe/danfo.dataframe.addcolumn.md | 118 ----- .../dataframe/danfo.dataframe.apply.md | 106 ---- .../dataframe/danfo.dataframe.column.md | 72 --- .../dataframe/danfo.dataframe.copy.md | 53 -- .../dataframe/danfo.dataframe.count.md | 100 ---- .../dataframe/danfo.dataframe.cummax.md | 99 ---- .../dataframe/danfo.dataframe.cummin.md | 99 ---- .../dataframe/danfo.dataframe.cumprod.md | 99 ---- .../dataframe/danfo.dataframe.cumsum.md | 99 ---- .../dataframe/danfo.dataframe.describe.md | 61 --- .../dataframe/danfo.dataframe.div.md | 254 ---------- .../dataframe/danfo.dataframe.dropna.md | 96 ---- .../dataframe/danfo.dataframe.eq.md | 190 -------- .../dataframe/danfo.dataframe.fillna.md | 178 ------- .../dataframe/danfo.dataframe.ge.md | 195 -------- .../dataframe/danfo.dataframe.groupby.md | 148 ------ .../dataframe/danfo.dataframe.gt.md | 191 -------- .../dataframe/danfo.dataframe.head.md | 53 -- .../dataframe/danfo.dataframe.iloc.md | 331 ------------- .../dataframe/danfo.dataframe.isna.md | 54 --- .../dataframe/danfo.dataframe.it.md | 194 -------- .../dataframe/danfo.dataframe.le.md | 194 -------- .../dataframe/danfo.dataframe.loc.md | 367 -------------- .../dataframe/danfo.dataframe.max.md | 118 ----- .../dataframe/danfo.dataframe.mean.md | 120 ----- .../dataframe/danfo.dataframe.median.md | 120 ----- .../dataframe/danfo.dataframe.min.md | 120 ----- .../dataframe/danfo.dataframe.mod.md | 258 ---------- .../dataframe/danfo.dataframe.mul.md | 252 ---------- .../dataframe/danfo.dataframe.ne.md | 187 -------- .../dataframe/danfo.dataframe.pow.md | 260 ---------- .../dataframe/danfo.dataframe.query.md | 278 ----------- .../dataframe/danfo.dataframe.replace.md | 102 ---- .../dataframe/danfo.dataframe.round.md | 128 ----- .../dataframe/danfo.dataframe.sample.md | 112 ----- .../dataframe/danfo.dataframe.std.md | 94 ---- .../dataframe/danfo.dataframe.sub.md | 250 ---------- .../dataframe/danfo.dataframe.sum.md | 121 ----- .../dataframe/danfo.dataframe.tail.md | 53 -- .../dataframe/danfo.dataframe.var.md | 94 ---- .../dataframe/dataframe.append.md | 75 --- .../dataframe/dataframe.apply_map.md | 68 --- .../dataframe/dataframe.astype.md | 222 --------- .../dataframe/dataframe.axes.md | 47 -- .../dataframe/dataframe.drop.md | 143 ------ .../dataframe/dataframe.dtypes.md | 100 ---- .../dataframe/dataframe.index.md | 69 --- .../dataframe/dataframe.ndim.md | 46 -- .../dataframe/dataframe.nunique-1.md | 98 ---- .../dataframe/dataframe.print.md | 105 ---- .../dataframe/dataframe.rename.md | 148 ------ .../dataframe/dataframe.reset_index.md | 73 --- .../dataframe/dataframe.select_dtypes.md | 94 ---- .../dataframe/dataframe.set_index.md | 176 ------- .../dataframe/dataframe.shape.md | 43 -- .../dataframe/dataframe.sort_index.md | 73 --- .../dataframe/dataframe.sort_values.md | 99 ---- .../dataframe/dataframe.tensor.md | 107 ----- .../dataframe/dataframe.to_csv.md | 114 ----- .../dataframe/dataframe.to_excel.md | 53 -- .../dataframe/dataframe.to_json.md | 126 ----- .../dataframe/dataframe.values.md | 50 -- .../general-functions/README.md | 27 -- .../general-functions/danfo.concat.md | 187 -------- .../general-functions/danfo.date_range.md | 111 ----- .../general-functions/danfo.get_dummies.md | 188 -------- .../general-functions/danfo.labelencoder.md | 140 ------ .../general-functions/danfo.merge.md | 453 ------------------ .../general-functions/danfo.minmaxscaler.md | 125 ----- .../general-functions/danfo.onehotencoder.md | 148 ------ .../general-functions/danfo.standardscaler.md | 132 ----- .../general-functions/danfo.to_datetime.md | 141 ------ api-reference-v1-stable/groupby.md | 122 ----- api-reference-v1-stable/groupby/README.md | 34 -- .../groupby/groupby.agg.md | 93 ---- .../groupby/groupby.apply.md | 84 ---- .../groupby/groupby.col.md | 105 ---- .../groupby/groupby.count.md | 175 ------- .../groupby/groupby.cummax.md | 258 ---------- .../groupby/groupby.cummin.md | 258 ---------- .../groupby/groupby.cumprod.md | 258 ---------- .../groupby/groupby.cumsum.md | 259 ---------- .../groupby/groupby.get_groups.md | 129 ----- .../groupby/groupby.max.md | 170 ------- .../groupby/groupby.mean.md | 173 ------- .../groupby/groupby.min.md | 171 ------- .../groupby/groupby.std.md | 175 ------- .../groupby/groupby.sum.md | 172 ------- .../groupby/groupby.var.md | 175 ------- .../input-output/README.md | 18 - .../input-output/danfo.read_csv.md | 135 ------ .../input-output/danfo.read_excel.md | 68 --- .../input-output/danfo.read_json.md | 128 ----- .../input-output/danfo.to_csv.md | 115 ----- .../input-output/danfo.to_excel.md | 54 --- .../input-output/danfo.to_json.md | 124 ----- api-reference-v1-stable/input-output/read.md | 138 ------ api-reference-v1-stable/plotting/README.md | 19 - .../plotting/bar-charts.md | 78 --- api-reference-v1-stable/plotting/box-plots.md | 122 ----- .../plotting/configuring-your-plots.md | 69 --- .../plotting/histograms.md | 120 ----- .../plotting/line-charts.md | 112 ----- .../plotting/pie-charts.md | 127 ----- .../plotting/scatter-plots.md | 91 ---- api-reference-v1-stable/plotting/tables.md | 97 ---- .../plotting/timeseries-plots.md | 58 --- .../plotting/violin-plots.md | 116 ----- api-reference-v1-stable/series/README.md | 182 ------- .../series/creating-a-series.md | 210 -------- .../series/danfo.series.add.md | 22 - .../series/danfo.series.apply.md | 63 --- .../series/danfo.series.copy.md | 22 - .../series/danfo.series.count.md | 24 - .../series/danfo.series.describe.md | 26 - .../series/danfo.series.div.md | 26 - .../series/danfo.series.head.md | 25 - .../series/danfo.series.map.md | 42 -- .../series/danfo.series.max.md | 2 - .../series/danfo.series.maximum.md | 22 - .../series/danfo.series.mean.md | 2 - .../series/danfo.series.median.md | 2 - .../series/danfo.series.min.md | 2 - .../series/danfo.series.minimum.md | 22 - .../series/danfo.series.mod.md | 24 - .../series/danfo.series.mode.md | 2 - .../series/danfo.series.mul.md | 26 - .../series/danfo.series.pow.md | 26 - .../series/danfo.series.reset_index.md | 31 -- .../series/danfo.series.round.md | 20 - .../series/danfo.series.sample.md | 22 - .../series/danfo.series.set_index.md | 40 -- .../series/danfo.series.sort_values.md | 27 -- .../series/danfo.series.std.md | 20 - .../series/danfo.series.sub.md | 24 - .../series/danfo.series.sum-1.md | 22 - .../series/danfo.series.tail.md | 22 - .../series/danfo.series.tostring.md | 18 - .../series/danfo.series.var.md | 20 - api-reference-v1-stable/series/series.abs.md | 52 -- api-reference-v1-stable/series/series.add.md | 86 ---- api-reference-v1-stable/series/series.and.md | 132 ----- .../series/series.append.md | 135 ------ .../series/series.apply.md | 149 ------ .../series/series.argmax.md | 35 -- .../series/series.argmin.md | 35 -- .../series/series.argsort.md | 75 --- .../series/series.astype.md | 2 - api-reference-v1-stable/series/series.copy.md | 45 -- api-reference-v1-stable/series/series.corr.md | 2 - .../series/series.count.md | 36 -- .../series/series.cummax.md | 51 -- .../series/series.cummin.md | 51 -- .../series/series.cumprod.md | 51 -- .../series/series.cumsum.md | 74 --- .../series/series.describe.md | 57 --- api-reference-v1-stable/series/series.div.md | 87 ---- api-reference-v1-stable/series/series.dot.md | 2 - .../series/series.drop_duplicates.md | 121 ----- .../series/series.dropna.md | 91 ---- .../series/series.dt.day.md | 55 --- .../series/series.dt.hour.md | 52 -- .../series/series.dt.minute.md | 60 --- .../series/series.dt.month.md | 47 -- .../series/series.dt.month_name.md | 55 --- .../series/series.dt.monthday.md | 55 --- .../series/series.dt.second.md | 60 --- .../series/series.dt.weekdays.md | 79 --- .../series/series.dt.year.md | 45 -- .../series/series.dtype.md | 34 -- api-reference-v1-stable/series/series.eq.md | 95 ---- .../series/series.fillna.md | 106 ---- api-reference-v1-stable/series/series.ge.md | 95 ---- api-reference-v1-stable/series/series.gt.md | 95 ---- api-reference-v1-stable/series/series.head.md | 51 -- api-reference-v1-stable/series/series.iloc.md | 158 ------ .../series/series.index.md | 33 -- api-reference-v1-stable/series/series.isna.md | 45 -- api-reference-v1-stable/series/series.le.md | 96 ---- api-reference-v1-stable/series/series.loc.md | 198 -------- api-reference-v1-stable/series/series.lt.md | 96 ---- api-reference-v1-stable/series/series.map.md | 92 ---- api-reference-v1-stable/series/series.max.md | 36 -- .../series/series.maximum.md | 50 -- api-reference-v1-stable/series/series.mean.md | 36 -- .../series/series.median.md | 36 -- api-reference-v1-stable/series/series.min.md | 36 -- .../series/series.minimum.md | 48 -- api-reference-v1-stable/series/series.mod.md | 85 ---- api-reference-v1-stable/series/series.mode.md | 36 -- api-reference-v1-stable/series/series.mul.md | 86 ---- api-reference-v1-stable/series/series.ndim.md | 34 -- api-reference-v1-stable/series/series.ne.md | 95 ---- .../series/series.nunique.md | 34 -- api-reference-v1-stable/series/series.or.md | 132 ----- api-reference-v1-stable/series/series.pow.md | 87 ---- .../series/series.replace.md | 89 ---- .../series/series.reset_index.md | 113 ----- .../series/series.round.md | 48 -- .../series/series.sample.md | 65 --- .../series/series.set_index.md | 136 ------ .../series/series.shape.md | 35 -- api-reference-v1-stable/series/series.size.md | 37 -- .../series/series.sort_values.md | 140 ------ api-reference-v1-stable/series/series.std.md | 39 -- .../series/series.str.capitalize.md | 52 -- .../series/series.str.charat.md | 53 -- .../series/series.str.concat.md | 165 ------- .../series/series.str.endswith.md | 51 -- .../series/series.str.includes.md | 51 -- .../series/series.str.indexof.md | 51 -- .../series/series.str.join.md | 52 -- .../series/series.str.lastindexof.md | 54 --- .../series/series.str.len.md | 52 -- .../series/series.str.repeat.md | 51 -- .../series/series.str.replace.md | 50 -- .../series/series.str.search.md | 94 ---- .../series/series.str.slice.md | 54 --- .../series/series.str.split.md | 74 --- .../series/series.str.startswith.md | 51 -- .../series/series.str.substr.md | 50 -- .../series/series.str.substring.md | 56 --- .../series/series.str.tolowercase.md | 50 -- .../series/series.str.touppercase.md | 52 -- .../series/series.str.trim.md | 50 -- api-reference-v1-stable/series/series.sub.md | 86 ---- api-reference-v1-stable/series/series.sum.md | 36 -- api-reference-v1-stable/series/series.tail.md | 49 -- .../series/series.tensor.md | 46 -- .../series/series.unique.md | 55 --- .../series/series.value_counts.md | 54 --- .../series/series.values.md | 35 -- api-reference-v1-stable/series/series.var.md | 35 -- 239 files changed, 22652 deletions(-) delete mode 100644 api-reference-v1-stable/README.md delete mode 100644 api-reference-v1-stable/configuration-options.md delete mode 100644 api-reference-v1-stable/dataframe/README.md delete mode 100644 api-reference-v1-stable/dataframe/creating-a-dataframe.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.abs.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.add.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.apply.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.column.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.copy.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.count.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.describe.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.div.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.eq.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ge.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.gt.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.head.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.isna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.it.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.le.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.loc.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.max.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mean.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.median.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.min.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mod.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mul.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ne.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.pow.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.query.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.replace.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.round.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sample.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.std.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sub.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sum.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.tail.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.var.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.append.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.apply_map.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.astype.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.axes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.drop.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.dtypes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.ndim.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.nunique-1.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.print.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.rename.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.reset_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.select_dtypes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.set_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.shape.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_values.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.tensor.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_csv.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_excel.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_json.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.values.md delete mode 100644 api-reference-v1-stable/general-functions/README.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.concat.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.date_range.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.get_dummies.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.labelencoder.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.merge.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.minmaxscaler.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.onehotencoder.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.standardscaler.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.to_datetime.md delete mode 100644 api-reference-v1-stable/groupby.md delete mode 100644 api-reference-v1-stable/groupby/README.md delete mode 100644 api-reference-v1-stable/groupby/groupby.agg.md delete mode 100644 api-reference-v1-stable/groupby/groupby.apply.md delete mode 100644 api-reference-v1-stable/groupby/groupby.col.md delete mode 100644 api-reference-v1-stable/groupby/groupby.count.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cummax.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cummin.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cumprod.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cumsum.md delete mode 100644 api-reference-v1-stable/groupby/groupby.get_groups.md delete mode 100644 api-reference-v1-stable/groupby/groupby.max.md delete mode 100644 api-reference-v1-stable/groupby/groupby.mean.md delete mode 100644 api-reference-v1-stable/groupby/groupby.min.md delete mode 100644 api-reference-v1-stable/groupby/groupby.std.md delete mode 100644 api-reference-v1-stable/groupby/groupby.sum.md delete mode 100644 api-reference-v1-stable/groupby/groupby.var.md delete mode 100644 api-reference-v1-stable/input-output/README.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_csv.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_excel.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_json.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_csv.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_excel.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_json.md delete mode 100644 api-reference-v1-stable/input-output/read.md delete mode 100644 api-reference-v1-stable/plotting/README.md delete mode 100644 api-reference-v1-stable/plotting/bar-charts.md delete mode 100644 api-reference-v1-stable/plotting/box-plots.md delete mode 100644 api-reference-v1-stable/plotting/configuring-your-plots.md delete mode 100644 api-reference-v1-stable/plotting/histograms.md delete mode 100644 api-reference-v1-stable/plotting/line-charts.md delete mode 100644 api-reference-v1-stable/plotting/pie-charts.md delete mode 100644 api-reference-v1-stable/plotting/scatter-plots.md delete mode 100644 api-reference-v1-stable/plotting/tables.md delete mode 100644 api-reference-v1-stable/plotting/timeseries-plots.md delete mode 100644 api-reference-v1-stable/plotting/violin-plots.md delete mode 100644 api-reference-v1-stable/series/README.md delete mode 100644 api-reference-v1-stable/series/creating-a-series.md delete mode 100644 api-reference-v1-stable/series/danfo.series.add.md delete mode 100644 api-reference-v1-stable/series/danfo.series.apply.md delete mode 100644 api-reference-v1-stable/series/danfo.series.copy.md delete mode 100644 api-reference-v1-stable/series/danfo.series.count.md delete mode 100644 api-reference-v1-stable/series/danfo.series.describe.md delete mode 100644 api-reference-v1-stable/series/danfo.series.div.md delete mode 100644 api-reference-v1-stable/series/danfo.series.head.md delete mode 100644 api-reference-v1-stable/series/danfo.series.map.md delete mode 100644 api-reference-v1-stable/series/danfo.series.max.md delete mode 100644 api-reference-v1-stable/series/danfo.series.maximum.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mean.md delete mode 100644 api-reference-v1-stable/series/danfo.series.median.md delete mode 100644 api-reference-v1-stable/series/danfo.series.min.md delete mode 100644 api-reference-v1-stable/series/danfo.series.minimum.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mod.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mode.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mul.md delete mode 100644 api-reference-v1-stable/series/danfo.series.pow.md delete mode 100644 api-reference-v1-stable/series/danfo.series.reset_index.md delete mode 100644 api-reference-v1-stable/series/danfo.series.round.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sample.md delete mode 100644 api-reference-v1-stable/series/danfo.series.set_index.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sort_values.md delete mode 100644 api-reference-v1-stable/series/danfo.series.std.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sub.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sum-1.md delete mode 100644 api-reference-v1-stable/series/danfo.series.tail.md delete mode 100644 api-reference-v1-stable/series/danfo.series.tostring.md delete mode 100644 api-reference-v1-stable/series/danfo.series.var.md delete mode 100644 api-reference-v1-stable/series/series.abs.md delete mode 100644 api-reference-v1-stable/series/series.add.md delete mode 100644 api-reference-v1-stable/series/series.and.md delete mode 100644 api-reference-v1-stable/series/series.append.md delete mode 100644 api-reference-v1-stable/series/series.apply.md delete mode 100644 api-reference-v1-stable/series/series.argmax.md delete mode 100644 api-reference-v1-stable/series/series.argmin.md delete mode 100644 api-reference-v1-stable/series/series.argsort.md delete mode 100644 api-reference-v1-stable/series/series.astype.md delete mode 100644 api-reference-v1-stable/series/series.copy.md delete mode 100644 api-reference-v1-stable/series/series.corr.md delete mode 100644 api-reference-v1-stable/series/series.count.md delete mode 100644 api-reference-v1-stable/series/series.cummax.md delete mode 100644 api-reference-v1-stable/series/series.cummin.md delete mode 100644 api-reference-v1-stable/series/series.cumprod.md delete mode 100644 api-reference-v1-stable/series/series.cumsum.md delete mode 100644 api-reference-v1-stable/series/series.describe.md delete mode 100644 api-reference-v1-stable/series/series.div.md delete mode 100644 api-reference-v1-stable/series/series.dot.md delete mode 100644 api-reference-v1-stable/series/series.drop_duplicates.md delete mode 100644 api-reference-v1-stable/series/series.dropna.md delete mode 100644 api-reference-v1-stable/series/series.dt.day.md delete mode 100644 api-reference-v1-stable/series/series.dt.hour.md delete mode 100644 api-reference-v1-stable/series/series.dt.minute.md delete mode 100644 api-reference-v1-stable/series/series.dt.month.md delete mode 100644 api-reference-v1-stable/series/series.dt.month_name.md delete mode 100644 api-reference-v1-stable/series/series.dt.monthday.md delete mode 100644 api-reference-v1-stable/series/series.dt.second.md delete mode 100644 api-reference-v1-stable/series/series.dt.weekdays.md delete mode 100644 api-reference-v1-stable/series/series.dt.year.md delete mode 100644 api-reference-v1-stable/series/series.dtype.md delete mode 100644 api-reference-v1-stable/series/series.eq.md delete mode 100644 api-reference-v1-stable/series/series.fillna.md delete mode 100644 api-reference-v1-stable/series/series.ge.md delete mode 100644 api-reference-v1-stable/series/series.gt.md delete mode 100644 api-reference-v1-stable/series/series.head.md delete mode 100644 api-reference-v1-stable/series/series.iloc.md delete mode 100644 api-reference-v1-stable/series/series.index.md delete mode 100644 api-reference-v1-stable/series/series.isna.md delete mode 100644 api-reference-v1-stable/series/series.le.md delete mode 100644 api-reference-v1-stable/series/series.loc.md delete mode 100644 api-reference-v1-stable/series/series.lt.md delete mode 100644 api-reference-v1-stable/series/series.map.md delete mode 100644 api-reference-v1-stable/series/series.max.md delete mode 100644 api-reference-v1-stable/series/series.maximum.md delete mode 100644 api-reference-v1-stable/series/series.mean.md delete mode 100644 api-reference-v1-stable/series/series.median.md delete mode 100644 api-reference-v1-stable/series/series.min.md delete mode 100644 api-reference-v1-stable/series/series.minimum.md delete mode 100644 api-reference-v1-stable/series/series.mod.md delete mode 100644 api-reference-v1-stable/series/series.mode.md delete mode 100644 api-reference-v1-stable/series/series.mul.md delete mode 100644 api-reference-v1-stable/series/series.ndim.md delete mode 100644 api-reference-v1-stable/series/series.ne.md delete mode 100644 api-reference-v1-stable/series/series.nunique.md delete mode 100644 api-reference-v1-stable/series/series.or.md delete mode 100644 api-reference-v1-stable/series/series.pow.md delete mode 100644 api-reference-v1-stable/series/series.replace.md delete mode 100644 api-reference-v1-stable/series/series.reset_index.md delete mode 100644 api-reference-v1-stable/series/series.round.md delete mode 100644 api-reference-v1-stable/series/series.sample.md delete mode 100644 api-reference-v1-stable/series/series.set_index.md delete mode 100644 api-reference-v1-stable/series/series.shape.md delete mode 100644 api-reference-v1-stable/series/series.size.md delete mode 100644 api-reference-v1-stable/series/series.sort_values.md delete mode 100644 api-reference-v1-stable/series/series.std.md delete mode 100644 api-reference-v1-stable/series/series.str.capitalize.md delete mode 100644 api-reference-v1-stable/series/series.str.charat.md delete mode 100644 api-reference-v1-stable/series/series.str.concat.md delete mode 100644 api-reference-v1-stable/series/series.str.endswith.md delete mode 100644 api-reference-v1-stable/series/series.str.includes.md delete mode 100644 api-reference-v1-stable/series/series.str.indexof.md delete mode 100644 api-reference-v1-stable/series/series.str.join.md delete mode 100644 api-reference-v1-stable/series/series.str.lastindexof.md delete mode 100644 api-reference-v1-stable/series/series.str.len.md delete mode 100644 api-reference-v1-stable/series/series.str.repeat.md delete mode 100644 api-reference-v1-stable/series/series.str.replace.md delete mode 100644 api-reference-v1-stable/series/series.str.search.md delete mode 100644 api-reference-v1-stable/series/series.str.slice.md delete mode 100644 api-reference-v1-stable/series/series.str.split.md delete mode 100644 api-reference-v1-stable/series/series.str.startswith.md delete mode 100644 api-reference-v1-stable/series/series.str.substr.md delete mode 100644 api-reference-v1-stable/series/series.str.substring.md delete mode 100644 api-reference-v1-stable/series/series.str.tolowercase.md delete mode 100644 api-reference-v1-stable/series/series.str.touppercase.md delete mode 100644 api-reference-v1-stable/series/series.str.trim.md delete mode 100644 api-reference-v1-stable/series/series.sub.md delete mode 100644 api-reference-v1-stable/series/series.sum.md delete mode 100644 api-reference-v1-stable/series/series.tail.md delete mode 100644 api-reference-v1-stable/series/series.tensor.md delete mode 100644 api-reference-v1-stable/series/series.unique.md delete mode 100644 api-reference-v1-stable/series/series.value_counts.md delete mode 100644 api-reference-v1-stable/series/series.values.md delete mode 100644 api-reference-v1-stable/series/series.var.md diff --git a/api-reference-v1-stable/README.md b/api-reference-v1-stable/README.md deleted file mode 100644 index b5d5d28..0000000 --- a/api-reference-v1-stable/README.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - This page gives an overview of all public danfo objects, functions and - methods. All classes and functions exposed in danfo.* namespace are public. ---- - -# API reference - -* [General Functions](general-functions/) - * [Data manipulations](general-functions/#data-manipulations) - * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) -* [Input/output](input-output/) - * [CSV](input-output/#csv) - * [JSON](input-output/#json) -* [Series](series/) - * [Attributes](series/#attributes) - * [Conversion](series/#conversion) - * [Indexing, iteration](series/#indexing-iteration) - * [Binary operator functions](series/#binary-operator-functions) - * [Function application, GroupBy & window](series/#function-application-and-groupby) - * [Computations / descriptive stats](series/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](series/#reindexing-selection-label-manipulation) - * [Missing data handling](series/#missing-data-handling) - * [Reshaping, sorting](series/#reshaping-sorting) - * [Accessors](series/#accessors) - * [Serialization / IO / conversion](series/#serialization-io-conversion) -* [DataFrame](dataframe/) - * [Attributes ](dataframe/#attributes) - * [Conversion](dataframe/#conversion) - * [Indexing, iteration](dataframe/#indexing-iteration) - * [Binary operator functions](dataframe/#binary-operator-functions) - * [Function application, GroupBy & window](dataframe/#function-application-and-groupby) - * [Computations / descriptive stats](dataframe/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](dataframe/#reindexing-selection-label-manipulation) - * [Missing data handling](dataframe/#missing-data-handling) - * [Reshaping, sorting, transposing](dataframe/#sorting-and-transposing) - * [Combining / comparing / joining / merging](dataframe/#combining-comparing-joining-merging) - * [Serialization / IO / conversion](dataframe/#serialization-io-conversion) -* [Plotting](plotting/) - * [Line Charts](plotting/line-charts.md) - * [Bar Charts](plotting/bar-charts.md) - * [Scatter Plots](plotting/scatter-plots.md) - * [Histograms](plotting/histograms.md) - * [Pie Charts](plotting/pie-charts.md) - * [Tables](plotting/tables.md) - * [Box Plots](plotting/box-plots.md) - * [Violin Plots](plotting/violin-plots.md) - * [Timeseries Plots](plotting/timeseries-plots.md) -* [GroupBy](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html) - * [Indexing, iteration](groupby/#indexing-iteration) - * [Function application](groupby/#function-application) - * [Computations / descriptive stats](groupby/#computations-descriptive-stats) - diff --git a/api-reference-v1-stable/configuration-options.md b/api-reference-v1-stable/configuration-options.md deleted file mode 100644 index f4c2136..0000000 --- a/api-reference-v1-stable/configuration-options.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: >- - This section describes all user configurable options available on - DataFrame/Series creation. ---- - -# Configuration Options - -On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. - -| Parameter | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | -| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | -| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | -| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| - -> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) - -## Examples of setting configs - -### Add a DataFrame header - -```javascript - const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] - }; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - }, - } -}); -df.print() -``` - -```javascript -╔════════════════════════════════════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟────────────┬───────────────────┬───────────────────┬───────────────────╢ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Configure column size and display format of DataFrame - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -}; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - columns: [ - { alignment: 'left' }, - { alignment: 'center', width: 20 }, - { alignment: 'right' }, - { alignment: 'justify' } - ], - }, - } -}); -df.print() -``` - -```javascript -╔══════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟───┬──────────────────────┬───────┬───────╢ -║ │ Name │ Count │ Price ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧══════════════════════╧═══════╧═══════╝ -``` - -### Configure the number of rows displayed when **print** is called - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250], - -}; -const df = new DataFrame(data, { - config: { - tableMaxColInConsole: 6, - tableMaxRow: 1 - } -}); -df.print() -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/dataframe/README.md b/api-reference-v1-stable/dataframe/README.md deleted file mode 100644 index a45aabd..0000000 --- a/api-reference-v1-stable/dataframe/README.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. ---- - -# Dataframe - -> `DataFrame`(data, {\ -> **columns:** \[ Array ],\ -> **dtypes:** \[ Array ],** **\ -> ** index: **\[Array], \ -> **options**: Object}) - -### Attributes - -| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | -| ------------------------------------------------ | ---------------------------------------- | -| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | - -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| ------------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.select_dtypes`](dataframe.select_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | - -### Conversion - -| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | -| ------------------------------------------- | -------------------------------------------------- | -| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | -| --------------------------------------------- | ------------------------------------------------------------------ | -| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | -| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | -| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | - -### Binary operator functions - -| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | -| ----------------------------------------- | --------------------------------------------------------------------------------------- | -| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | -| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | -| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | -| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | -| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | -| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | -| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | -| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | -| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | -| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | -| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | - -### Function application & GroupBy - -| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | -| --------------------------------------------- | --------------------------------------------------------- | -| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | -| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | - -### Computations / descriptive stats - -| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | -| --------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | -| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | -| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | -| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | -| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | -| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | -| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | -| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | -| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | -| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | -| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | -| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | - -### Reindexing / selection / label manipulation - -| | | -| --------------------------------------------------- | ------------------------------------------------------- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------------------- | ------------------------------------------- | -| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | -| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | -| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | -| [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | - -### Sorting & transposing - -| | | -| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| [`DataFrame.sort_values`](dataframe.sort_values.md) | Sort by the values along either axis. | -| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | - -### Combining / comparing / joining / merging - -| | | -| ---------------------------------------------------------- | ------------------------------------------------------------------- | -| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | -| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | -| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| -------------------------------------------------------- | ------------------------------------------------------------- | -| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | -| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| ------------------------------------------- | ---------------------------------------------------- | -| [`DataFrame.to_csv`](dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | -| [`DataFrame.to_json`](dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/dataframe/creating-a-dataframe.md b/api-reference-v1-stable/dataframe/creating-a-dataframe.md deleted file mode 100644 index 0228131..0000000 --- a/api-reference-v1-stable/dataframe/creating-a-dataframe.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -description: Creates a DataFrame object from flat structure ---- - -# Creating a DataFrame - -new danfo.**DataFrame**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

columns: Array of column names. If not specified, column names are - auto generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. - -### Creating a `DataFrame` from a JSON object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -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 }] - -df = new dfd.DataFrame(json_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Creating a `DataFrame` from an array of array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] -let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` from a 2D tensor - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -const tf = require("@tensorflow/tfjs-node") - - -let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) -let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) -df.print() -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` - -### Creating a `DataFrame` from an object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) - -console.log(dates); - -obj_data = {'A': dates, - 'B': ["bval1", "bval2", "bval3", "bval4"], - 'C': [10, 20, 30, 40], - 'D': [1.2, 3.45, 60.1, 45], - 'E': ["test", "train", "test", "train"] - } - -df = new dfd.DataFrame(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -//output in console -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D │ E ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying index, dtypes, columns - -You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. - -> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; -let index = ["a", "b"]; -let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] -let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] - -let df = new DataFrame(data1, { index, columns, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying memory mode - -To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: - -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; - -let df = new DataFrame(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. -{% endhint %} - -For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md b/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md deleted file mode 100644 index 83c6cd3..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a DataFrame with the absolute numeric value of each element. ---- - -# DataFrame.abs - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - -** **return** Series** - -## **Examples** - -The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let df_abs = df.abs() -df_abs.abs().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after applying abs function - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.add.md b/api-reference-v1-stable/dataframe/danfo.dataframe.add.md deleted file mode 100644 index 467c143..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.add.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -description: Get Addition of DataFrame and other, element-wise (binary operator add). ---- - -# DataFrame.add - -danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Addition of** scalar to **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.add(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of** Series to **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.add(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 8 │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 9 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of** **DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.add(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 2 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 9 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 25 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of** ** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.add(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Addition works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.add(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md b/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md deleted file mode 100644 index ef0ecc9..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Add new column to a DataFrame ---- - -# DataFrame.addColumn - -danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | - -**Returns:** - -## **Examples** - -## **Add Array as a new column to DataFrame** - -New columns get added at the end of the DataFrame, and this happens so returns nothing, - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -df.print() - -let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Add Series as a new column to DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -let s = new dfd.Series([1, 2, 3, 4]) -df.addColumn({ "column": "D", "values": s, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md b/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md deleted file mode 100644 index 01fab60..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Apply a function to each element or along a specified axis of a DataFrame. ---- - -# DataFrame.apply - -danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Apply a function along default axis 1 (columns) - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 1 }) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### Apply a function along axis 0 (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 0 }) -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ 6 ║ -╟───┼─────╢ -║ 1 │ 15 ║ -╟───┼─────╢ -║ 2 │ 90 ║ -╟───┼─────╢ -║ 3 │ 206 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.column.md b/api-reference-v1-stable/dataframe/danfo.dataframe.column.md deleted file mode 100644 index 2d70bfd..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.column.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -description: Return the elements of the specified column in the DataFrame ---- - -# DataFrame.column - -danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------- | ------- | -| column | String | The name of a column in the DataFrame | | - -**Returns:** - -** **return** Series** - -## **Examples** - -## **Select a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { "Name": ["Apples", "App", "Banana", undefined], - "Count": [NaN, 5, NaN, 10] , - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) - -df.column("Name").print() - -//Alternatively, you can retrieve columns by using the object property -df['Name'].print() //produces the same result as above - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -``` -{% endtab %} -{% endtabs %} - -To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md b/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md deleted file mode 100644 index ef705ed..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Makes a new copy of the DataFrame ---- - -# DataFrame.copy - -danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -**Returns:** - -** **return** new DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) -let new_df = df.copy() -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.count.md b/api-reference-v1-stable/dataframe/danfo.dataframe.count.md deleted file mode 100644 index 9e9916e..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.count.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Count non-NaN cells for each column or row. The values NaN and undefined are - considered NaN ---- - -# DataFrame.count - -danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Count Non-NaN values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ Name │ 3 ║ -╟───────┼──────────────────────╢ -║ Count │ 2 ║ -╟───────┼──────────────────────╢ -║ Price │ 4 ║ -╚═══════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Count Non-NaN values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md deleted file mode 100644 index c46ae7b..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative maximum over a DataFrame or Series axis. ---- - -# DataFrame.cummax - -danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -## Cumulative maximum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 11 │ 20 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 11 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 11 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative maximum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 15 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 89 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md deleted file mode 100644 index 53f4045..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative minimum over a DataFrame or Series axis. ---- - -# DataFrame.cummin - -danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -## Cumulative minimum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 15 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative minimum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 11 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 2 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md deleted file mode 100644 index b780cd2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative product over a DataFrame or Series axis. ---- - -# DataFrame.cumprod - -danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -## Cumulative product of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 10 │ 18 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 300 │ 720 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 26700 │ 56160 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative product of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod({axis: 1}) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 60 │ 2400 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 178 │ 13884 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md deleted file mode 100644 index 4863805..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative sum over a DataFrame or Series axis. ---- - -# DataFrame.cumsum - -danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -## Cumulative sum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 12 │ 35 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 14 │ 65 │ 49 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 16 │ 154 │ 127 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative sum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 31 │ 34 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 16 │ 22 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 32 │ 72 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 91 │ 169 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md b/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md deleted file mode 100644 index 4dac614..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -description: >- - Generate descriptive statistics for each numeric column. Numeric columns are - of type Int and float. ---- - -# DataFrame.describe - -danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] -let col_names = ["col1", "col2", "col3", "col4"] -let df = new dfd.DataFrame(data, {columns: col_names}) - -df.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 3 │ 3 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0 │ 2 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 2 │ 4 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 360 │ 180 │ 360 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.div.md b/api-reference-v1-stable/dataframe/danfo.dataframe.div.md deleted file mode 100644 index 54123d9..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.div.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -description: >- - Get Float division of DataFrame and other, element-wise (binary operator - truediv). ---- - -# DataFrame.div - -danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Division of** scalar with **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.div(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division of** Series with **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.div(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0.25 │ 0.6000000238418… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0.4000000059604… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1.25 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0.25 │ 0.8000000119209… ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of** **DataFrame **with** a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.div(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0.1000000014901… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.8000000119209… │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0.25 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of** ** Array **with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.div(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.div(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md deleted file mode 100644 index 81006a1..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Remove missing values (NaNs, undefined, null) for DataFrame ---- - -# DataFrame.dropna - -danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | -| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace: **false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Drop rows (axis=0) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -let df_drop = df.dropna(0) -df_drop.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop columns (axis=1) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -df.dropna({axis: 1, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md b/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md deleted file mode 100644 index a43fbd0..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -description: Get Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.eq - -danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.eq(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.eq(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.eq(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.eq(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md deleted file mode 100644 index 49aa13d..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -description: >- - Fill NaN/undefined values using the specified method. Detect missing values - for an array-like object. ---- - -# DataFrame.fillna - -danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| values | Array \| Scalar | The list of value(s) to use for replacement. | | -| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Fill missing values in specified columns with specified values - -Missing values are NaN, undefined or null values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -df.print() - -let values = ["Apples", df["Count"].mean()] -let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//Before filling -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ NaN │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ NaN │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After filling - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 7.5 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 7.5 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ -``` -{% endtab %} -{% endtabs %} - -### Fill all columns with NaNs with a specified value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") - -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill NaNs inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let values = ["Apples", df["Count"].mean()] -df.fillna(values, { - columns: ["Name", "Count"], - inplace: true -}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md deleted file mode 100644 index 3b41ec3..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -description: >- - Get Greater or Equal to of DataFrame and other, element-wise (binary operator - eq). ---- - -# DataFrame.ge - -danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -** DataFrame** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.ge(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ge(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ge(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.ge(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md b/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md deleted file mode 100644 index a31f095..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Group DataFrame using a mapper or by a Series of columns. ---- - -# DataFrame.groupby - -danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | ----------------------------------------------------- | ------- | -| columns | Array | The names of a column(s) in the DataFrame to group by | | - -**Returns:** - -** **return** DataFrame.groups** - -## **Examples** - -## **Groupby a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]) -console.log(group_df) - -//GroupBy Object -GroupBy { - key_col: [ 'A' ], - col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, - data: [ - [ 'Pear', 2, 3 ], - [ 'Pear', 5, 6 ], - [ 'Apple', 30, 40 ], - [ 'Apple', 89, 78 ] - ], - column_name: [ 'A', 'B', 'C' ], - data_tensors: { - Pear: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - '$index': [Array], - '$dtypes': [Array], - '$columns': [Array] - }, - Apple: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - ... - '$columns': [Array] - } - }, - col_dtype: [ 'string' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: - -1. [count](danfo.dataframe.count.md) -2. [sum](danfo.dataframe.sum.md) -3. [std](danfo.dataframe.std.md) -4. [var](danfo.dataframe.var.md) -5. [mean](danfo.dataframe.mean.md) -6. [cumsum](danfo.dataframe.cumsum.md) -7. [cummax](danfo.dataframe.cummax.md) -8. [cumprod](danfo.dataframe.cumprod.md) -9. [cummin](danfo.dataframe.cummin.md) -10. [max](danfo.dataframe.max.md) -11. [min](danfo.dataframe.min.md) - -## Example of Groupby and apply a sum function - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]).sum() - -group_df.print() - -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B_sum │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 7 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 119 │ 118 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -## **Groupby a two columns from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A", "B"]).sum() - -group_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 2 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Apple │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md b/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md deleted file mode 100644 index 121c7e7..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -description: Get Greater than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.gt - -danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.gt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.gt(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.gt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.gt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.head.md b/api-reference-v1-stable/dataframe/danfo.dataframe.head.md deleted file mode 100644 index 10ae0f2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.head.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the first n rows of the DataFrame based on position. ---- - -# DataFrame.head - -danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.head(2) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md deleted file mode 100644 index f8e0f4c..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -description: Purely integer-location based indexing for selection by position. ---- - -# DataFrame.iloc - -danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A string slice object with ints, e.g. `"1:7"` -* A boolean array. - -_**Note:** only the start index is included._ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,1,3]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row and return all columns** - -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: ["1:3"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of column and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by the specified index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,3], columns: [1,2]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by slices - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -╔═══╤═══════════════════╗ -║ │ Count ║ -╟───┼───────────────────╢ -║ 2 │ 30 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### More default slicing behavior - -If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md deleted file mode 100644 index b919db5..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Return a boolean same-sized object indicating if the values are NaN. - NaN/undefined values gets mapped to true values, and everything else gets - mapped to false values. ---- - -# DataFrame.isna - -danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.isna().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ false │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ false │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.it.md b/api-reference-v1-stable/dataframe/danfo.dataframe.it.md deleted file mode 100644 index 69093a2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.it.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: Get Less than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.It - -danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.lt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10, 40]) - -let df_rep = df.lt(sf, { axis: 1 }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.lt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.lt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.le.md b/api-reference-v1-stable/dataframe/danfo.dataframe.le.md deleted file mode 100644 index 0b88ff1..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.le.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: >- - Get Less than or Equal to of DataFrame and other, element-wise (binary - operator eq). ---- - -# DataFrame.le - -danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.le(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.le(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.le(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.le(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md deleted file mode 100644 index 88d7556..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md +++ /dev/null @@ -1,367 +0,0 @@ ---- -description: Access a group of rows and columns by label(s) ---- - -# DataFrame.loc - -danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -`.loc()` is label position based-from `0` to `length-1` of the row axis. - -Allowed inputs for are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note: **only** **the start label is included, and the end label is ignored. _ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Index by specific rows and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({rows: ["a", "c"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a list of column names and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({columns: ["Count", "Price"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ a │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ b │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Index both axes by the specified labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: ["c","d"], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after slicing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ Banana │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ Pear │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -df`.loc({ row: [a:e]}).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -df``.loc({ row: [`"a":"e"`]}).print()``\ -\ -_**Inner**_ _**quotes are not needed for numeric indices!**_ -{% endhint %} - -### Slice DataFrame rows by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.loc({ rows: df["Count"].gt(6) }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -### Slice DataFrame rows by multiple boolean conditions - -{% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame. _ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let condition = df["Count"].gt(6).and(df["Price"].lt(250)) -let sub_df = df.loc({ rows: condition }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` - -### Slice DataFrame with boolean mask - -{% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame. _ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) - -let sub_df = df.loc({ rows: [false, true, true, true] }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.max.md b/api-reference-v1-stable/dataframe/danfo.dataframe.max.md deleted file mode 100644 index f8e9124..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.max.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Return the maximum of the values for the requested axis. ---- - -# DataFrame.max - -danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Return the maximum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.max().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 11 ║ -╟───┼──────────────────────╢ -║ B │ 89 ║ -╟───┼──────────────────────╢ -║ C │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the maximum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.max({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 15 ║ -╟───┼──────────────────────╢ -║ 2 │ 40 ║ -╟───┼──────────────────────╢ -║ 3 │ 89 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md deleted file mode 100644 index fbc005e..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the mean of the values for the requested axis. ---- - -# DataFrame.mean - -danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Computes the mean of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.mean().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 4 ║ -╟───┼──────────────────────╢ -║ B │ 38.5 ║ -╟───┼──────────────────────╢ -║ C │ 31.75 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Computes the mean of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -let cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.mean({ axis: 0 }).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11.333333015441895 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.333333492279053 ║ -╟───┼──────────────────────╢ -║ 2 │ 24 ║ -╟───┼──────────────────────╢ -║ 3 │ 56.33333206176758 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.median.md b/api-reference-v1-stable/dataframe/danfo.dataframe.median.md deleted file mode 100644 index e75519f..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.median.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the median of the values for the requested axis. ---- - -# DataFrame.median - -danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Calculates the median of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.median().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 2 ║ -╟───┼──────────────────────╢ -║ B │ 25 ║ -╟───┼──────────────────────╢ -║ C │ 23 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the median of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.median({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 30 ║ -╟───┼──────────────────────╢ -║ 3 │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.min.md b/api-reference-v1-stable/dataframe/danfo.dataframe.min.md deleted file mode 100644 index 93b9bf8..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.min.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the minimum of the values for the requested axis. ---- - -# DataFrame.min - -danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Returns the minimum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.min().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 1 ║ -╟───┼──────────────────────╢ -║ B │ 15 ║ -╟───┼──────────────────────╢ -║ C │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the minimum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.min({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md deleted file mode 100644 index 8cd7e9f..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Get Modulo of DataFrame and other, element-wise (binary operator mod). ---- - -# DataFrame.mod - -danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Modulo of** scalar with **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mod(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of** Series with **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mod(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 4 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mod(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 5 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of** ** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mod(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Modulo works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mod(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md deleted file mode 100644 index 3627b59..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md +++ /dev/null @@ -1,252 +0,0 @@ ---- -description: Get Multiplication of dataframe and other, element-wise (binary operator mul). ---- - -# DataFrame.mul - -danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Multiplication of** scalar to **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mul(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Multiplication of** Series to **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mul(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 4 │ 15 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 16 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of** **DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mul(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 100 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 8 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of** ** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mul(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mul(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md deleted file mode 100644 index 1996400..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.ne - -danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing** **DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.ne(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ne(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ne(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing** **DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10, 40, 30, 20] - -let df_rep = df.le(val) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ true │ false │ false │ true ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ false │ true │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md b/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md deleted file mode 100644 index 634e6e2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -description: >- - Get Exponential power of dataframe and other, element-wise (binary operator - pow). ---- - -# DataFrame.pow - -danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Exponential of** scalar with **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.pow(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of** Series with **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.pow(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 243 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 256 │ 32 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 625 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 1024 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of** **DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.pow(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1048576 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1024 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 95367433551872 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 16 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of** ** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.pow(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Exponential works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.pow(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.query.md b/api-reference-v1-stable/dataframe/danfo.dataframe.query.md deleted file mode 100644 index 129c8e7..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.query.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -description: >- - Query the DataFrame by the result of a logical comparison or boolean mask. - Supports logical operations like (">", "<", ">=", "<=", and. "==") ---- - -# DataFrame.query - -danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | - -**Returns:** - - **** return **new DataFrame** - -## **Examples** - -## **Query a DataFrame using a boolean mask** - -{% hint style="info" %} -Querying by a boolean condition is supported from v0.3.0 and above. -{% endhint %} - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5) }) -query_df.print() //after query -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) -query_df.print() //after query - -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -## **Query a DataFrame using logical operators** - -To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() //before query - -let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) -query_df.print() //after query -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query by a string column in a DataFrame** - -The query method also works on string columns. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query a DataFrame inplace** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.query({ - column: "B", - is: ">", - to: 5, - inplace: true -}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md b/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md deleted file mode 100644 index 9a0b39f..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -description: Replaces values in a DataFrame with specified values ---- - -# DataFrame.replace - -> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| oldValue | String, boolean, Number | The value you want to replace | | -| newValue | String, boolean, Number | The new value you want to replace the old value with | | -| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | - -**Returns:** - -** **return** DataFrame** - -**** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_rep = df.replace(10, -999, { columns: ["Col1"] }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -999 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 45 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 56 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -999 │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By not specifying a** **column**, **the** **replace works on all columns ** ** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] -let df = new dfd.DataFrame(data) -//replace value in all column -let df_rep = df.replace("A", "BOY") - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ BOY │ BOY │ BOY │ B ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ B │ C │ C │ D ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.round.md b/api-reference-v1-stable/dataframe/danfo.dataframe.round.md deleted file mode 100644 index 32e7c8a..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.round.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: Round elements in a DataFrame to a specified number of decimal places. ---- - -# DataFrame.round - -danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -## Round elements to 1dp (Default) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1 │ 3.6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.1 │ 40.2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Round elements to a specified number of decimal places - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round(2) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round operation - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.12 │ 3.57 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.23 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md deleted file mode 100644 index 73e057a..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: Return a random sample of rows from DataFrame. ---- - -# DataFrame.sample - -danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | - -**Returns:** - -** **return** {Promies} resolves to DataFrame** - -**** - -## Sample a DataFrame randomly - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(2); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sample a DataFrame randomly with seed - -By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(3, { seed: 2 }); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.std.md b/api-reference-v1-stable/dataframe/danfo.dataframe.std.md deleted file mode 100644 index b94372e..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.std.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return sample standard deviation over requested axis. ---- - -# DataFrame.std - -danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Calculates the standard deviation of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4.69041575982343 ║ -╟───┼──────────────────────╢ -║ 1 │ 34.23935357645254 ║ -╟───┼──────────────────────╢ -║ 2 │ 35.103418636936205 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the standard deviation of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 8.504900548115383 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.094598884597588 ║ -╟───┼──────────────────────╢ -║ 2 │ 19.697715603592208 ║ -╟───┼──────────────────────╢ -║ 3 │ 47.37439533475159 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md deleted file mode 100644 index aded5cb..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -description: Get Subtraction of dataframe and other, element-wise (binary operator sub). ---- - -# DataFrame.sub - -danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Subtraction of** scalar to **DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.sub(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Subtraction of** Series to **DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.sub(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ -3 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ -3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ -5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -3 │ -1 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of** **DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.sub(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ -18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ -1 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ -15 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -10 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of** ** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.sub(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Subtraction works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.sub(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md deleted file mode 100644 index 515788b..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Return the sum of the values for the requested axis. ---- - -# DataFrame.sum - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Sum elements along default axis (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum() -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤════════════════════╗ -║ A │ 37.199999999999996 ║ -╟───┼────────────────────╢ -║ B │ 41 ║ -╟───┼────────────────────╢ -║ C │ -10 ║ -╚═══╧════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sum elements along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum({axis: 0}) -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ sum ║ -╟───┼──────────────────────╢ -║ 0 │ 33.9 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 82.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -54 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md b/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md deleted file mode 100644 index f317ba2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the last n rows from the DataFrame based on position. ---- - -# DataFrame.tail - -danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.tail(3) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.var.md b/api-reference-v1-stable/dataframe/danfo.dataframe.var.md deleted file mode 100644 index b95bb1a..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.var.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return unbiased variance over requested axis. ---- - -# DataFrame.var - -danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - -** **return** Series** - -## **Examples** - -## Calculate variance of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 22 ║ -╟───┼──────────────────────╢ -║ 1 │ 1172.3333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 1232.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculate variance of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 72.33333333333334 ║ -╟───┼──────────────────────╢ -║ 1 │ 50.33333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 388 ║ -╟───┼──────────────────────╢ -║ 3 │ 2244.333333333333 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/dataframe/dataframe.append.md b/api-reference-v1-stable/dataframe/dataframe.append.md deleted file mode 100644 index ae84a8b..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.append.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Adds new row to the end of a DataFrame ---- -# DataFrame.append - -danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] - -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | -| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Appends a new row to the end of a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data) -df.print() - -let new_df = df.append([[20, 40, 60, "d"]], [3]) -new_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 40 │ 60 │ d ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/dataframe/dataframe.apply_map.md b/api-reference-v1-stable/dataframe/dataframe.apply_map.md deleted file mode 100644 index 986566f..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.apply_map.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Apply a function to a Dataframe values element-wise. ---- - -# DataFrame.apply_map - -danfo.DataFrame.**apply_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Apply a function to all values in a DataFrame - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - short_name: ["NG", "GH", "EGY", "SA"], - long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] -} -let df = new dfd.DataFrame(data) - -function lower(x) { - return `${x}`.toLowerCase() -} - -let df_new = df.apply_map(lower) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ short_name │ long_name ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ ng │ nigeria ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ gh │ ghana ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ egy │ eqypt ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ sa │ south africa ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.astype.md b/api-reference-v1-stable/dataframe/dataframe.astype.md deleted file mode 100644 index fb388a3..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.astype.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -description: Cast column of a DataFrame to a specified dtype. ---- - -# DataFrame.astype - -danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Cast a float dtype column to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.print() -df.ctypes.print() - -let df_new = df.astype({column: "A", dtype: "int32"}) -df_new.print() - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before casting -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ - - - //after casting - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Casting a string column of numbers to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["20", "13", "45", "90"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ 13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ 45 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -**Note: **Casting a string column of alphabets/words to numeric form will return NaNs as values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.axes.md b/api-reference-v1-stable/dataframe/dataframe.axes.md deleted file mode 100644 index 4bdc319..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.axes.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: >- - Return an Object containing the axes of the DataFrame. It has the row axis - labels and column axis labels as the only members. They are returned in that - order. ---- - -# DataFrame.axes - -danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - -** **return** Object** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.axis) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -{ index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.drop.md b/api-reference-v1-stable/dataframe/dataframe.drop.md deleted file mode 100644 index 2376308..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.drop.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -description: >- - Drop specified labels from rows or columns.Remove rows or columns by - specifying label names and corresponding axis. ---- - -# DataFrame.drop - -danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Drop columns by specifying the names - -By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.drop({ columns: ["C", "B"], inplace: true }); -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ D ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ a ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ b ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ c ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ c ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying int labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] -} - -let df = new dfd.DataFrame(data) -df.drop({ index: [0, 2], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying string labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.drop({ index: ["a", "c"], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.dtypes.md b/api-reference-v1-stable/dataframe/dataframe.dtypes.md deleted file mode 100644 index 6e856d5..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.dtypes.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Return the inferred column types in the DataFrame. This returns a Series with - the data type of each column. The result’s index is the original DataFrame’s - columns. ---- - -# DataFrame.ctypes - -danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] - -**Returns:** - -** **return** Series** - -## **Examples** - -Returns auto-generated** **index of a** **DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Columns with mixed types are represented as **string.** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference-v1-stable/dataframe/dataframe.index.md b/api-reference-v1-stable/dataframe/dataframe.index.md deleted file mode 100644 index 0983db8..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -description: The index (row labels) of the DataFrame. ---- - -# DataFrame.index - -danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -## **Examples** - -Returns auto-generated** **index of a** **DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[0, 1, 2, 3] -``` -{% endtab %} -{% endtabs %} - - - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["r1", "r2", "r3", "r4"]) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 'r1', 'r2', 'r3', 'r4' ] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.ndim.md b/api-reference-v1-stable/dataframe/dataframe.ndim.md deleted file mode 100644 index 002da15..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.ndim.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: >- - Return an int representing the number of axes / array dimensions. Returns 1 if - Series. Otherwise return 2 for DataFrame. ---- - -# DataFrame.ndim - -danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - -** **return** Int** - -**Note:** To get the **shape **of the DataFrame use the .[shape](dataframe.shape.md) property. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.ndim) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -2 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.nunique-1.md b/api-reference-v1-stable/dataframe/dataframe.nunique-1.md deleted file mode 100644 index f06d4ed..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.nunique-1.md +++ /dev/null @@ -1,98 +0,0 @@ -# DataFrame.nunique - -danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | -------------------------------------- | ------- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | - -**Returns:** - -** **return** Series** - -## **Examples** - -### Return number of unique values along column axis (axis=1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 4 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} - -### Return number of unique values in row axis (axis=0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique(axis=0).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note: **To get the unique elements along an axis, use** **[DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference-v1-stable/dataframe/dataframe.print.md b/api-reference-v1-stable/dataframe/dataframe.print.md deleted file mode 100644 index d03232d..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.print.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: >- - Pretty prints default (10) number of rows in a DataFrame or Series to the - console ---- - -# DataFrame.print - -danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ FR ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ GH ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Using JavaScript default **console.log** to display a DataFrame will return the Object instead unless you manually cast it to a String - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -console.log(df) -console.log(String(df)); -// console.log(df + ""); //same result as above -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -DataFrame { - '$isSeries': false, - '$config': Configs { - tableDisplayConfig: {}, - tableMaxRow: 10, - tableMaxColInConsole: 21, - dtypeTestLim: 7, - lowMemoryMode: false - }, - '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], - '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], - '$index': [ 0, 1, 2 ], - '$dtypes': [ 'float32', 'int32', 'string' ], - '$columns': [ 'Abs', 'Count', 'country code' ] -} -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ FR ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ GH ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.rename.md b/api-reference-v1-stable/dataframe/dataframe.rename.md deleted file mode 100644 index 6625bc1..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.rename.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: >- - Change axes labels. Object values must be unique (1-to-1). Labels not - contained in a dict / Series will be left as-is. Extra labels listed don’t - throw an error. ---- - -# DataFrame.rename - -danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### Rename columns - -By setting **inplace **to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df.rename({ mapper: {"A": "new_name"},inplace: true }) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename more the one column at time - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ new_c ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename index by labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df = df.rename({ mapper: { "a": 0 }, axis: 0 }) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.reset_index.md b/api-reference-v1-stable/dataframe/dataframe.reset_index.md deleted file mode 100644 index 00239fc..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.reset_index.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -description: Reset the index of the DataFrame, and use the default one instead. ---- - -# DataFrame.reset_index - -danfo.DataFrame.**reset_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df.print() - -df.reset_index({ inplace: true }) //inplace -//df = df.reset_index() //not in inplace - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md b/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md deleted file mode 100644 index 127b433..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return a subset of the DataFrame’s columns based on the column dtypes. ---- - -# DataFrame.select_dtypes - -danfo.DataFrame.**select_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | -------------------------------- | ------- | -| include | Array | List of column dtypes to return | | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -float_df = df.select_dtypes(['float32']) -float_df.print() - -mix_df = df.select_dtypes(include=['float32', "int32"]) -mix_df.print() - -str_df = df.select_dtypes(include=['string']) -str_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//select float column(s) -╔═══╤══════════════════════╗ -║ │ A ║ -╟───┼──────────────────────╢ -║ 0 │ -20.1 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 2 │ 47.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -20 ║ -╚═══╧══════════════════════╝ - - - //select both float and int columns - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//return string type column -╔═══╤══════════════════════╗ -║ │ D ║ -╟───┼──────────────────────╢ -║ 0 │ a ║ -╟───┼──────────────────────╢ -║ 1 │ b ║ -╟───┼──────────────────────╢ -║ 2 │ 20 ║ -╟───┼──────────────────────╢ -║ 3 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.set_index.md b/api-reference-v1-stable/dataframe/dataframe.set_index.md deleted file mode 100644 index e82c213..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.set_index.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -description: >- - Set the DataFrame index using existing columns or an array (of the equal - length). ---- - -# DataFrame.set_index - -danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | - -## **Examples** - -### **Setting index to a column in the DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ -20 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 30 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **** - -### **Setting index to a column in the DataFrame and dropping the column** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", drop: true, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ B │ C ║ -╟────────────┼───────────────────┼───────────────────╢ -║ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Set index to an array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.print() - -let new_index = ["a", "b", "c"] -df.set_index({index: new_index, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). diff --git a/api-reference-v1-stable/dataframe/dataframe.shape.md b/api-reference-v1-stable/dataframe/dataframe.shape.md deleted file mode 100644 index 3e8486f..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.shape.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -description: Returns an Array representing the dimensionality of the DataFrame. ---- - -# DataFrame.shape - -danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - -** **return** Int** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.shape) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[4,3] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_index.md b/api-reference-v1-stable/dataframe/dataframe.sort_index.md deleted file mode 100644 index 0829afe..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.sort_index.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -description: Sort DataFrame by index ---- -# DataFrame.sort_index - -DataFrame.**sort_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], - index: ["b", "a", "c"] }) -df.print() - -let df2 = df.sort_index({ ascending: false }) -df2.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after sorting in descending order - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_values.md b/api-reference-v1-stable/dataframe/dataframe.sort_values.md deleted file mode 100644 index 8da51fe..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.sort_values.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Sort a Dataframe in ascending or descending order by a specified column name. ---- - -# DataFrame.sort_values - -danfo.DataFrame.**sort_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "C", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Sort DataFrame by a column in descending order** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "B", inplace: true, ascending: false}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.tensor.md b/api-reference-v1-stable/dataframe/dataframe.tensor.md deleted file mode 100644 index 125198f..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.tensor.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -description: Return a Tensorflow tensor representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. ---- -# DataFrame.tensor - -danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - -** **return** tf.tensor** - -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30]} - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -Tensor - [[-20 , 34, 20], - [30 , -4, 20], - [47.2999992, 5 , 30], - [-20 , 6 , 30]] -``` -{% endtab %} -{% endtabs %} - -String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 - -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 0, - rankType: '2' -} - -Tensor - [[20.2000008, 34, NaN], - [30 , 4 , NaN], - [47.2999992, 5 , NaN]] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.to_csv.md b/api-reference-v1-stable/dataframe/dataframe.to_csv.md deleted file mode 100644 index ee31a5e..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_csv.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -description: Convert DataFrame data to a comma-separated values (csv) ---- -# DataFrame.to_csv - -DataFrame.**to_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -**** - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = df.to_csv({ download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in browser - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ fileName: "testOut.csv", download: true}); -``` - diff --git a/api-reference-v1-stable/dataframe/dataframe.to_excel.md b/api-reference-v1-stable/dataframe/dataframe.to_excel.md deleted file mode 100644 index 4adf437..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_excel.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# DataFrame.to_excel - -> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in a browser - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ fileName: "testOut.xlsx"}); -``` diff --git a/api-reference-v1-stable/dataframe/dataframe.to_json.md b/api-reference-v1-stable/dataframe/dataframe.to_json.md deleted file mode 100644 index 59f7e34..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_json.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -description: Convert DataFrame to JSON format ---- -# DataFrame.to_json - -> DataFrame.**to_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = df.to_json({ download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = df.to_json({ - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ fileName: "test_out.json" }); -``` diff --git a/api-reference-v1-stable/dataframe/dataframe.values.md b/api-reference-v1-stable/dataframe/dataframe.values.md deleted file mode 100644 index 6b7ea1d..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.values.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Return a the JavaScript array representation of the DataFrame. ---- - -# DataFrame.values - -danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - -** **return** Array** - -**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -console.log(df.values) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - [ -20.1, 34, 20 ], - [ 30, -4, -20 ], - [ 47.3, 5, 30 ], - [ -20, 6, -40 ] -] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/general-functions/README.md b/api-reference-v1-stable/general-functions/README.md deleted file mode 100644 index 07815b0..0000000 --- a/api-reference-v1-stable/general-functions/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: Top level functions that can be called from the Danfo namespace ---- - -# General Functions - -### Data manipulations - -| | | -| ------------------------------------- | ----------------------------------------------------------------------------------------------- | -| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | -| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | -| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | - -### Data Processing/Normalization - -| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | -| ----------------------------------------- | ---------------------------------------------------------------------- | -| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | -| [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | -| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | - -### Top-level dealing with datetime - -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | -| ------------------------------------ | --------------------------------------- | -| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference-v1-stable/general-functions/danfo.concat.md b/api-reference-v1-stable/general-functions/danfo.concat.md deleted file mode 100644 index 19c3d8e..0000000 --- a/api-reference-v1-stable/general-functions/danfo.concat.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Concatenate DataFrames and Series along an axis ---- - -# danfo.concat - -danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Concatenate two DataFrames along column axis (1) ** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) -com_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two DataFrames along row axis (0) ** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two Series along row axis (0) ** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. diff --git a/api-reference-v1-stable/general-functions/danfo.date_range.md b/api-reference-v1-stable/general-functions/danfo.date_range.md deleted file mode 100644 index 32d18b8..0000000 --- a/api-reference-v1-stable/general-functions/danfo.date_range.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -description: Return a fixed frequency Dates spread between start and end parameters. ---- - -# danfo.date_range - -danfo.**date_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '2/1/2018, 12:00:00 AM', - '3/1/2018, 12:00:00 AM', - '4/1/2018, 12:00:00 AM', - '5/1/2018, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '1/1/2019, 12:00:00 AM', - '1/1/2020, 12:00:00 AM', - '1/1/2021, 12:00:00 AM', - '1/1/2022, 12:00:00 AM', - '1/1/2023, 12:00:00 AM', - '1/1/2024, 12:00:00 AM', - '1/1/2025, 12:00:00 AM', - '1/1/2026, 12:00:00 AM', - '1/1/2027, 12:00:00 AM', - '1/1/2028, 12:00:00 AM', - '1/1/2029, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.get_dummies.md b/api-reference-v1-stable/general-functions/danfo.get_dummies.md deleted file mode 100644 index 793aa58..0000000 --- a/api-reference-v1-stable/general-functions/danfo.get_dummies.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -description: Convert categorical variable into dummy/indicator variables. ---- - -# danfo.get_dummies - -danfo.**get_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| data | Series or Dataframe | The data to dummify | | -| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] -let sf1 = new dfd.Series(datasf) - -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert all categorical columns in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ fruits_pear │ fruits_mango │ ... │ fruits_bean │ Country_NG │ Country_GH │ Country_RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 1 │ 0 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 0 │ 1 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ 0 │ 0 │ ... │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 0 │ 1 │ ... │ 0 │ 0 │ 0 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ 0 │ 0 │ ... │ 1 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert a specific column in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ Country │ fruits_pear │ fruits_mango │ fruits_pawpaw │ fruits_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ NG │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ NG │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ GH │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ RU │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ RU │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.labelencoder.md b/api-reference-v1-stable/general-functions/danfo.labelencoder.md deleted file mode 100644 index 12d57ee..0000000 --- a/api-reference-v1-stable/general-functions/danfo.labelencoder.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Encode target labels with value between 0 and n_classes-1. ---- - -# danfo.LabelEncoder - -class danfo.**LabelEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. - -## **Examples** - -### **Label Encode values in a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = ["dog","cat","man","dog","cat","man","man","cat"] -let series = new dfd.Series(data) - -let encode = new dfd.LabelEncoder() - -encode.fit(series) -console.log(encode); - -let sf_enc = encode.transform(series.values) -sf_enc.print() - -let new_sf = encode.transform(["dog","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'dog', 'cat', 'man' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╟───┼──────────────────────╢ -║ 5 │ 2 ║ -╟───┼──────────────────────╢ -║ 6 │ 2 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with -1** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.LabelEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.merge.md b/api-reference-v1-stable/general-functions/danfo.merge.md deleted file mode 100644 index 82a9a3d..0000000 --- a/api-reference-v1-stable/general-functions/danfo.merge.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -description: >- - Merge DataFrame or named Series objects with a database-style join.The join is - done on columns or indexes. ---- - -# danfo.merge - -danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | - -**Returns:** - -** **return** DataFrame** - -## **Examples** - -**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. - -danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. - -For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. - -### **Merging by a single key found in both axis** - -By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - //first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on column 'Key1' - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### **Inner Join/Merge by multiple keys found in both axis** - -Merging by two keys takes into consideration the keys appearing in both`left` and `right DataFrame.` - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", 'Key2'], how: "inner"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on two keys - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent - -### Outer join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1"], how: "outer"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//First DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//After outer join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Left join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "left"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - After left join -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ NaN │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Right join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "right"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after right join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ NaN │ NaN │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md b/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md deleted file mode 100644 index 06add63..0000000 --- a/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -description: Transform features by scaling each feature to a range of max and min values. ---- - -# danfo.MinMaxScaler - -class danfo.**MinMaxScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. - -This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). - -The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize DataFrame Object using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.19191919267... │ 0.02902902849... │ 0.00950475223... │ 0.00333333341... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize Series Object Using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -let sf = df.iloc({columns: ["0"]}) - -scaler.fit(sf) - -let df_enc = scaler.transform(sf) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - Shape: (3,1) - -╔═══╤═══════════════════╗ -║ │ 0 ║ -╟───┼───────────────────╢ -║ 0 │ 1 ║ -╟───┼───────────────────╢ -║ 1 │ 0.19191919267... ║ -╟───┼───────────────────╢ -║ 2 │ 0 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.onehotencoder.md b/api-reference-v1-stable/general-functions/danfo.onehotencoder.md deleted file mode 100644 index fdb8d4a..0000000 --- a/api-reference-v1-stable/general-functions/danfo.onehotencoder.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Encode categorical features as a one-hot numeric array. ---- - -# danfo.OneHotEncoder - -class danfo.**OneHotEncoder **\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] - -danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","bean"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with 0s all through** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","woman", "cup"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get_dummies](danfo.get_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.standardscaler.md b/api-reference-v1-stable/general-functions/danfo.standardscaler.md deleted file mode 100644 index 298d86e..0000000 --- a/api-reference-v1-stable/general-functions/danfo.standardscaler.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: Standardize features by removing the mean and scaling to unit variance. ---- - -# danfo.StandardScaler - -class danfo.**StandScaler **\[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: - -> z = (x - u) / s - -where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. - -The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize Series Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.StandardScaler() - -let sf = new dfd.Series([100,1000,2000, 3000]) -sf.print() - -scaler.fit(sf) - -let sf_enc = scaler.transform(sf) -sf_enc.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 100 ║ -╟───┼──────────────────────╢ -║ 1 │ 1000 ║ -╟───┼──────────────────────╢ -║ 2 │ 2000 ║ -╟───┼──────────────────────╢ -║ 3 │ 3000 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1.1375757455825806 ║ -╟───┼──────────────────────╢ -║ 1 │ -0.4191068708896637 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.37919193506240845 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.1774907112121582 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize DataFrame Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.StandardScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 89, 12], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.to_datetime.md b/api-reference-v1-stable/general-functions/danfo.to_datetime.md deleted file mode 100644 index 7012100..0000000 --- a/api-reference-v1-stable/general-functions/danfo.to_datetime.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -description: Converts an array of Date time string to Date object. ---- - -# danfo.toDateTime - -danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | -| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -Converts a **Series** of Date strings to Date time and get time properties - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) -let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime(data) - -dt.month().print() -dt.month_name().print() -dt.weekdays().print() -dt.day().print() -dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - -//Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 - -//string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec - -//string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - -//Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference-v1-stable/groupby.md b/api-reference-v1-stable/groupby.md deleted file mode 100644 index 1db2e52..0000000 --- a/api-reference-v1-stable/groupby.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -description: >- - GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby(), - danfo.Series.groupby() ---- - -# Groupby - -### Indexing, iteration - -| [`GroupBy.__iter__`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.__iter__.html#pandas.core.groupby.GroupBy.__iter__)\(\) | Groupby iterator. | -| :--- | :--- | -| [`GroupBy.groups`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups) | Dict {group name -> group labels}. | -| [`GroupBy.indices`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.indices.html#pandas.core.groupby.GroupBy.indices) | Dict {group name -> group indices}. | -| [`GroupBy.get_group`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.get_group.html#pandas.core.groupby.GroupBy.get_group)\(name\[, obj\]\) | Construct DataFrame from group with provided name. | - -| [`Grouper`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Grouper.html#pandas.Grouper)\(\*args, \*\*kwargs\) | A Grouper allows the user to specify a groupby instruction for an object. | -| :--- | :--- | - - -### Function application - -| [`GroupBy.apply`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.apply.html#pandas.core.groupby.GroupBy.apply)\(func, \*args, \*\*kwargs\) | Apply function func group-wise and combine the results together. | -| :--- | :--- | -| [`GroupBy.agg`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.agg.html#pandas.core.groupby.GroupBy.agg)\(func, \*args, \*\*kwargs\) | | -| [`SeriesGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.aggregate.html#pandas.core.groupby.SeriesGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`DataFrameGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html#pandas.core.groupby.DataFrameGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`SeriesGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.transform.html#pandas.core.groupby.SeriesGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed Series on each group and return a Series having the same indexes as the original object filled with the transformed values | -| [`DataFrameGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.transform.html#pandas.core.groupby.DataFrameGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed DataFrame on each group and return a DataFrame having the same indexes as the original object filled with the transformed values | -| [`GroupBy.pipe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pipe.html#pandas.core.groupby.GroupBy.pipe)\(func, \*args, \*\*kwargs\) | Apply a function func with arguments to this GroupBy object and return the function’s result. | - -### Computations / descriptive stats - -| [`GroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.all.html#pandas.core.groupby.GroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`GroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.any.html#pandas.core.groupby.GroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`GroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.bfill.html#pandas.core.groupby.GroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.backfill.html#pandas.core.groupby.GroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.count.html#pandas.core.groupby.GroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`GroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumcount.html#pandas.core.groupby.GroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`GroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummax.html#pandas.core.groupby.GroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`GroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummin.html#pandas.core.groupby.GroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`GroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumprod.html#pandas.core.groupby.GroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`GroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumsum.html#pandas.core.groupby.GroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`GroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ffill.html#pandas.core.groupby.GroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.first`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html#pandas.core.groupby.GroupBy.first)\(\[numeric\_only, min\_count\]\) | Compute first of group values. | -| [`GroupBy.head`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.head.html#pandas.core.groupby.GroupBy.head)\(\[n\]\) | Return first n rows of each group. | -| [`GroupBy.last`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html#pandas.core.groupby.GroupBy.last)\(\[numeric\_only, min\_count\]\) | Compute last of group values. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max)\(\[numeric\_only, min\_count\]\) | Compute max of group values. | -| [`GroupBy.mean`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.mean.html#pandas.core.groupby.GroupBy.mean)\(\[numeric\_only\]\) | Compute mean of groups, excluding missing values. | -| [`GroupBy.median`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.median.html#pandas.core.groupby.GroupBy.median)\(\[numeric\_only\]\) | Compute median of groups, excluding missing values. | -| [`GroupBy.min`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.min.html#pandas.core.groupby.GroupBy.min)\(\[numeric\_only, min\_count\]\) | Compute min of group values. | -| [`GroupBy.ngroup`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ngroup.html#pandas.core.groupby.GroupBy.ngroup)\(\[ascending\]\) | Number each group from 0 to the number of groups - 1. | -| [`GroupBy.nth`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.nth.html#pandas.core.groupby.GroupBy.nth)\(n\[, dropna\]\) | Take the nth row from each group if n is an int, or a subset of rows if n is a list of ints. | -| [`GroupBy.ohlc`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ohlc.html#pandas.core.groupby.GroupBy.ohlc)\(\) | Compute open, high, low and close values of a group, excluding missing values. | -| [`GroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pad.html#pandas.core.groupby.GroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.prod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.prod.html#pandas.core.groupby.GroupBy.prod)\(\[numeric\_only, min\_count\]\) | Compute prod of group values. | -| [`GroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html#pandas.core.groupby.GroupBy.rank)\(\[method, ascending, na\_option, …\]\) | Provide the rank of values within each group. | -| [`GroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pct_change.html#pandas.core.groupby.GroupBy.pct_change)\(\[periods, fill\_method, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`GroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.size.html#pandas.core.groupby.GroupBy.size)\(\) | Compute group sizes. | -| [`GroupBy.sem`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sem.html#pandas.core.groupby.GroupBy.sem)\(\[ddof\]\) | Compute standard error of the mean of groups, excluding missing values. | -| [`GroupBy.std`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.std.html#pandas.core.groupby.GroupBy.std)\(\[ddof\]\) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum)\(\[numeric\_only, min\_count\]\) | Compute sum of group values. | -| [`GroupBy.var`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.var.html#pandas.core.groupby.GroupBy.var)\(\[ddof\]\) | Compute variance of groups, excluding missing values. | -| [`GroupBy.tail`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.tail.html#pandas.core.groupby.GroupBy.tail)\(\[n\]\) | Return last n rows of each group. | - -The following methods are available in both `SeriesGroupBy` and `DataFrameGroupBy` objects, but may differ slightly, usually in that the `DataFrameGroupBy` version usually permits the specification of an axis argument, and often an argument indicating whether to restrict application to columns of a specific data type. - -| [`DataFrameGroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.all.html#pandas.core.groupby.DataFrameGroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`DataFrameGroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.any.html#pandas.core.groupby.DataFrameGroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`DataFrameGroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.backfill.html#pandas.core.groupby.DataFrameGroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.bfill.html#pandas.core.groupby.DataFrameGroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.corr`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corr.html#pandas.core.groupby.DataFrameGroupBy.corr) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrameGroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.count.html#pandas.core.groupby.DataFrameGroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`DataFrameGroupBy.cov`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cov.html#pandas.core.groupby.DataFrameGroupBy.cov) | Compute pairwise covariance of columns, excluding NA/null values. | -| [`DataFrameGroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumcount.html#pandas.core.groupby.DataFrameGroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`DataFrameGroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummax.html#pandas.core.groupby.DataFrameGroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`DataFrameGroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummin.html#pandas.core.groupby.DataFrameGroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`DataFrameGroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumprod.html#pandas.core.groupby.DataFrameGroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`DataFrameGroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumsum.html#pandas.core.groupby.DataFrameGroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`DataFrameGroupBy.describe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.describe.html#pandas.core.groupby.DataFrameGroupBy.describe)\(\*\*kwargs\) | Generate descriptive statistics. | -| [`DataFrameGroupBy.diff`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.diff.html#pandas.core.groupby.DataFrameGroupBy.diff) | First discrete difference of element. | -| [`DataFrameGroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.ffill.html#pandas.core.groupby.DataFrameGroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.fillna`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.fillna.html#pandas.core.groupby.DataFrameGroupBy.fillna) | Fill NA/NaN values using the specified method. | -| [`DataFrameGroupBy.filter`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.filter.html#pandas.core.groupby.DataFrameGroupBy.filter)\(func\[, dropna\]\) | Return a copy of a DataFrame excluding filtered elements. | -| [`DataFrameGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.hist.html#pandas.core.groupby.DataFrameGroupBy.hist) | Make a histogram of the DataFrame’s. | -| [`DataFrameGroupBy.idxmax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmax.html#pandas.core.groupby.DataFrameGroupBy.idxmax) | Return index of first occurrence of maximum over requested axis. | -| [`DataFrameGroupBy.idxmin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmin.html#pandas.core.groupby.DataFrameGroupBy.idxmin) | Return index of first occurrence of minimum over requested axis. | -| [`DataFrameGroupBy.mad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.mad.html#pandas.core.groupby.DataFrameGroupBy.mad) | Return the mean absolute deviation of the values for the requested axis. | -| [`DataFrameGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.nunique.html#pandas.core.groupby.DataFrameGroupBy.nunique)\(\[dropna\]\) | Return DataFrame with counts of unique elements in each position. | -| [`DataFrameGroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pad.html#pandas.core.groupby.DataFrameGroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pct_change.html#pandas.core.groupby.DataFrameGroupBy.pct_change)\(\[periods, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`DataFrameGroupBy.plot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.plot.html#pandas.core.groupby.DataFrameGroupBy.plot) | Class implementing the .plot attribute for groupby objects. | -| [`DataFrameGroupBy.quantile`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.quantile.html#pandas.core.groupby.DataFrameGroupBy.quantile)\(\[q, interpolation\]\) | Return group values at the given quantile, a la numpy.percentile. | -| [`DataFrameGroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.rank.html#pandas.core.groupby.DataFrameGroupBy.rank)\(\[method, ascending, …\]\) | Provide the rank of values within each group. | -| [`DataFrameGroupBy.resample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.resample.html#pandas.core.groupby.DataFrameGroupBy.resample)\(rule, \*args, \*\*kwargs\) | Provide resampling when using a TimeGrouper. | -| [`DataFrameGroupBy.sample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html#pandas.core.groupby.DataFrameGroupBy.sample)\(\[n, frac, replace, …\]\) | Return a random sample of items from each group. | -| [`DataFrameGroupBy.shift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.shift.html#pandas.core.groupby.DataFrameGroupBy.shift)\(\[periods, freq, …\]\) | Shift each group by periods observations. | -| [`DataFrameGroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.size.html#pandas.core.groupby.DataFrameGroupBy.size)\(\) | Compute group sizes. | -| [`DataFrameGroupBy.skew`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.skew.html#pandas.core.groupby.DataFrameGroupBy.skew) | Return unbiased skew over requested axis. | -| [`DataFrameGroupBy.take`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.take.html#pandas.core.groupby.DataFrameGroupBy.take) | Return the elements in the given _positional_ indices along an axis. | -| [`DataFrameGroupBy.tshift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.tshift.html#pandas.core.groupby.DataFrameGroupBy.tshift) | \(DEPRECATED\) Shift the time index, using the index’s frequency if available. | - -The following methods are available only for `SeriesGroupBy` objects. - -| [`SeriesGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.hist.html#pandas.core.groupby.SeriesGroupBy.hist) | Draw histogram of the input series using matplotlib. | -| :--- | :--- | -| [`SeriesGroupBy.nlargest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nlargest.html#pandas.core.groupby.SeriesGroupBy.nlargest) | Return the largest n elements. | -| [`SeriesGroupBy.nsmallest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nsmallest.html#pandas.core.groupby.SeriesGroupBy.nsmallest) | Return the smallest n elements. | -| [`SeriesGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nunique.html#pandas.core.groupby.SeriesGroupBy.nunique)\(\[dropna\]\) | Return number of unique elements in the group. | -| [`SeriesGroupBy.unique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.unique.html#pandas.core.groupby.SeriesGroupBy.unique) | Return unique values of Series object. | -| [`SeriesGroupBy.value_counts`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.value_counts.html#pandas.core.groupby.SeriesGroupBy.value_counts)\(\[normalize, …\]\) | | -| [`SeriesGroupBy.is_monotonic_increasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing) | Alias for is\_monotonic. | -| [`SeriesGroupBy.is_monotonic_decreasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing) | Return boolean if values in the object are monotonic\_decreasing. | - -The following methods are available only for `DataFrameGroupBy` objects. - -| [`DataFrameGroupBy.corrwith`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corrwith.html#pandas.core.groupby.DataFrameGroupBy.corrwith) | Compute pairwise correlation. | -| :--- | :--- | -| [`DataFrameGroupBy.boxplot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.boxplot.html#pandas.core.groupby.DataFrameGroupBy.boxplot)\(\[subplots, column, …\]\) | Make box plots from DataFrameGroupBy data. | - diff --git a/api-reference-v1-stable/groupby/README.md b/api-reference-v1-stable/groupby/README.md deleted file mode 100644 index 9a1db65..0000000 --- a/api-reference-v1-stable/groupby/README.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: 'GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby()' ---- - -# Groupby - -### Indexing, iteration - -| | | -| :--- | :--- | -| [`GroupBy.get_group`](groupby.get_groups.md) | Construct DataFrame from group with provided name. | - -### Function application - -| | | -| :--- | :--- | -| [`GroupBy.agg`](groupby.agg.md) | Aggregate using one or more operations over the specified axis. | - -### Computations / descriptive stats - -| | | -| :--- | :--- | -| [`GroupBy.count`](groupby.count.md) | Compute count of group, excluding missing values. | -| [`GroupBy.cummax`](groupby.cummax.md) | Cumulative max for each group. | -| [`GroupBy.cummin`](groupby.cummin.md) | Cumulative min for each group. | -| [`GroupBy.cumprod`](groupby.cumprod.md) | Cumulative product for each group. | -| [`GroupBy.cumsum`](groupby.cumsum.md) | Cumulative sum for each group. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max) | Compute max of group values. | -| [`GroupBy.mean`](groupby.mean.md) | Compute mean of groups, excluding missing values. | -| [`GroupBy.min`](groupby.min.md) | Compute min of group values. | -| [`GroupBy.std`](groupby.std.md) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum) | Compute sum of group values. | -| [`GroupBy.var`](groupby.var.md) | Compute variance of groups, excluding missing values. | - diff --git a/api-reference-v1-stable/groupby/groupby.agg.md b/api-reference-v1-stable/groupby/groupby.agg.md deleted file mode 100644 index f9d6a5f..0000000 --- a/api-reference-v1-stable/groupby/groupby.agg.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -description: Obtain data aggregate per groups for each column ---- - -# Groupby.agg - -> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | -| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | - -**Return: **DataFrame - -**Examples** - -Using mean and sum aggregate - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Mean and Sum aggregate on dataframe groupby two column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/groupby/groupby.apply.md b/api-reference-v1-stable/groupby/groupby.apply.md deleted file mode 100644 index 2150a21..0000000 --- a/api-reference-v1-stable/groupby/groupby.apply.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -description: Apply custom aggregate function to grouped data ---- - -# Groupby.apply - -danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function \| function to be applied to grouped data | Undefined | | - -**Returns:** - - ****return **DataFrame** - -## **Examples** - -Using apply to create a custom function that subtract the minimum value of each grouped data from each of its values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - 'A': ['foo', 'bar', 'foo', 'bar', - - 'foo', 'bar', 'foo', 'foo'], - - 'B': ['one', 'one', 'two', 'three', - - 'two', 'two', 'one', 'three'], - - 'C': [1, 3, 2, 4, 5, 2, 6, 7], - - 'D': [3, 2, 4, 1, 5, 6, 7, 8] - }; -let df = new dfd.DataFrame(data); -let group_df = df.groupby(["A", "B"]); - -const subMin = (x) => { - return x.sub(x.min()); -}; - -group_df.apply(subMin).print(); - -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_apply │ D_apply ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 5 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 3 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -\*\*\*\* diff --git a/api-reference-v1-stable/groupby/groupby.col.md b/api-reference-v1-stable/groupby/groupby.col.md deleted file mode 100644 index 02e7cdd..0000000 --- a/api-reference-v1-stable/groupby/groupby.col.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: Obtain the column(s) per groups ---- - -# Groupby.col - -> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| col\_names | Array | List of column | | - -Returns: Groupby Data structure - -Note: This is similar to pandas `df.groupby(["column"])["col_names"]` - -**Examples** - -Obtain a column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]) - -//for more coumns -grp.col(["C","D"]) -``` -{% endtab %} -{% endtabs %} - -Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. - -```text -//it returns the groupby data structure -GroupBy { - key_col: [ 'A' ], - col_dict: { - foo: [ [Array], [Array], [Array], [Array], [Array] ], - bar: [ [Array], [Array], [Array] ] - }, - data: [ - [ 'foo', 'one', 1, 3 ], - [ 'bar', 'one', 3, 2 ], - [ 'foo', 'two', 2, 4 ], - [ 'bar', 'three', 4, 1 ], - [ 'foo', 'two', 5, 5 ], - [ 'bar', 'two', 2, 6 ], - [ 'foo', 'one', 6, 7 ], - [ 'foo', 'three', 7, 8 ] - ], - column_name: [ 'A', 'B', 'C', 'D' ], - data_tensors: { - foo: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - }, - bar: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - } - }, - group_col_name: [ 'C' ], - group_col: { foo: [ [Series] ], bar: [ [Series] ] } -} -``` - - - diff --git a/api-reference-v1-stable/groupby/groupby.count.md b/api-reference-v1-stable/groupby/groupby.count.md deleted file mode 100644 index 36733be..0000000 --- a/api-reference-v1-stable/groupby/groupby.count.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Count the occurrence of values in columns per groups ---- - -# Groupby.count - -> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).count().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.cummax.md b/api-reference-v1-stable/groupby/groupby.cummax.md deleted file mode 100644 index 8231a61..0000000 --- a/api-reference-v1-stable/groupby/groupby.cummax.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative max per groups for each column ---- - -# Groupby.cummax - -> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative max of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 4 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 4 │ 6 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 4 │ 6 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cummin.md b/api-reference-v1-stable/groupby/groupby.cummin.md deleted file mode 100644 index 7fd9ed6..0000000 --- a/api-reference-v1-stable/groupby/groupby.cummin.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative minimum per groups for each column ---- - -# Groupby.cummin - -> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative min of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 2 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 2 │ 1 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cumprod.md b/api-reference-v1-stable/groupby/groupby.cumprod.md deleted file mode 100644 index af46123..0000000 --- a/api-reference-v1-stable/groupby/groupby.cumprod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cumulative product per group for each column ---- - -# Groupby.cumprod - -> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative product of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 │ 420 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 │ 3360 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 24 │ 12 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 24 │ 12 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 21 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cumsum.md b/api-reference-v1-stable/groupby/groupby.cumsum.md deleted file mode 100644 index 3b2b0e6..0000000 --- a/api-reference-v1-stable/groupby/groupby.cumsum.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -description: Obtain the cumulative sum per groups for each column ---- - -# Groupby.cumsum - -> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative sum of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 │ 19 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 │ 27 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 9 │ 9 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 9 │ 9 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.get_groups.md b/api-reference-v1-stable/groupby/groupby.get_groups.md deleted file mode 100644 index 0cdf912..0000000 --- a/api-reference-v1-stable/groupby/groupby.get_groups.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -description: Obtain the data for each element of the groupby column ---- - -# Groupby.get\_groups - -> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] - -| Parameters | Type | Description | default | -| :--- | :--- | :--- | :--- | -| key | Array | element of the groupby column | | - -**Returns**: DataFrame - -**Example** - -Group the dataframe by column A and obtain the group belonging to the values in column A - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) - -grp.get_groups(["foo"]).print() - -grp.get_groups(["bar"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get groups for key "foo" - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get groups for key "bar" - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ three │ 4 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) - -grp.get_groups(["foo","one"]).print() - -grp.get_groups(["bar","one"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get_groups(["foo","one"] - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get_groups(["bar","one"]) - - - Shape: (1,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.max.md b/api-reference-v1-stable/groupby/groupby.max.md deleted file mode 100644 index 6bebae5..0000000 --- a/api-reference-v1-stable/groupby/groupby.max.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -description: Obtain the maximum value of columns per groups ---- - -# Groupby.max - -> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] - -**Parameters: **None - -**Returns**: DataFrame - -**Example** - -Obtain the maximum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/groupby/groupby.mean.md b/api-reference-v1-stable/groupby/groupby.mean.md deleted file mode 100644 index add6958..0000000 --- a/api-reference-v1-stable/groupby/groupby.mean.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -description: Obtain the mean per groups for each column(s) ---- - -# Groupby.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the mean of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 5.40000009536... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.min.md b/api-reference-v1-stable/groupby/groupby.min.md deleted file mode 100644 index 0151e64..0000000 --- a/api-reference-v1-stable/groupby/groupby.min.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -description: Obtain the minimum value per groups for a coumn(s) ---- - -# Groupby.min - -> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the minimum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the minimum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.std.md b/api-reference-v1-stable/groupby/groupby.std.md deleted file mode 100644 index c792a8e..0000000 --- a/api-reference-v1-stable/groupby/groupby.std.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the standard deviation per groups for specified columns ---- - -# Groupby.std - -> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the standard deviation of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... │ 2.07364413533... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 2.64575131106... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).std().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... │ 2.82842712474... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... │ 0.70710678118... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.sum.md b/api-reference-v1-stable/groupby/groupby.sum.md deleted file mode 100644 index f6f2900..0000000 --- a/api-reference-v1-stable/groupby/groupby.sum.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -description: Obtain the sum per groups for columns ---- - -# Groupby.sum - -> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the sum of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.var.md b/api-reference-v1-stable/groupby/groupby.var.md deleted file mode 100644 index 373109f..0000000 --- a/api-reference-v1-stable/groupby/groupby.var.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the variance per groups for a specified column ---- - -# Groupby.var - -> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 │ 4.3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).var().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 │ 0.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/input-output/README.md b/api-reference-v1-stable/input-output/README.md deleted file mode 100644 index e86d5de..0000000 --- a/api-reference-v1-stable/input-output/README.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Functions for reading tabular/structured data into DataFrame/Series Objects ---- - -# Input/Output - -## CSV - -| \`\` | | -| ----------------------------------- | -------------------------------------------------------- | -| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | -| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | -| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | - -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference-v1-stable/input-output/danfo.read_csv.md b/api-reference-v1-stable/input-output/danfo.read_csv.md deleted file mode 100644 index 79644f3..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_csv.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: >- - Reads a comma-separated values (CSV) file into DataFrame. Also supports the - reading of CSV files in chunks. ---- - -# danfo.read_csv - -> danfo.**read_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] - -| **Parameters** | Type | Description | Default | -| -------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | -| **configs**: | object, optional |

Supports all Papaparse config parameters. See https://www.papaparse.com/docs#config.

|

{

dynamicTyping: true,

header: true

}

| - -**Returns:** - -** **_**Promise**_. Resolves to DataFrame - -The **read_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. - -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("./user_names.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading files from a URL** - -By specifying a valid URL, you can load CSV files from any location into Danfo**'**s data structure: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_excel.md b/api-reference-v1-stable/input-output/danfo.read_excel.md deleted file mode 100644 index 459aa30..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_excel.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Reads an excel file into DataFrame. ---- - -# danfo.read_excel - -> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] - -| Parameters | Type | Description | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| source | string | **source** : string, URL or local file path to retreive Excel file. | -| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| - -> **Returns:** -> -> ** **return** **{**Promise**} DataFrame structure of parsed Excel data - -### Example - -The **read_excel** method can read excel files saved on a local disk, or over the internet. - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") -const path = require("path") - -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") - -async function load_process_data() { - let df = await dfd.read_excel(local_xcel) - df.head().print() -} - -load_process_data() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_json.md b/api-reference-v1-stable/input-output/danfo.read_json.md deleted file mode 100644 index 85412ea..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_json.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: Reads a JSON file into DataFrame. ---- - -# danfo.read_json - -> danfo.**read_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| _**source**_ | Input file object, string file** **path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | -| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| - -**Returns:** - -** **_**Promise**_. Resolves to DataFrame - -The **read_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. - -### **Reading JSON files from local disk** - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.to_csv.md b/api-reference-v1-stable/input-output/danfo.to_csv.md deleted file mode 100644 index 5bd4105..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_csv.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -description: Writes a DataFrame or Series to CSV format. ---- - -# danfo.to_csv - -> danfo.**to_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] - -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = dfd.to_csv(df, { download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in Client-side lib - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -const dfd = require("danfojs") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { fileName: "testOut.csv", download: true}); -``` diff --git a/api-reference-v1-stable/input-output/danfo.to_excel.md b/api-reference-v1-stable/input-output/danfo.to_excel.md deleted file mode 100644 index 1fe1adf..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_excel.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# danfo.to_excel - -> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in Client-side lib - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { fileName: "testOut.xlsx"}); -``` diff --git a/api-reference-v1-stable/input-output/danfo.to_json.md b/api-reference-v1-stable/input-output/danfo.to_json.md deleted file mode 100644 index 80eaa04..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_json.md +++ /dev/null @@ -1,124 +0,0 @@ -# danfo.to_json - -> danfo.**to_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = dfd.to_json(df, { download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = dfd.to_json(df, { - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { fileName: "test_out.json" }); -``` diff --git a/api-reference-v1-stable/input-output/read.md b/api-reference-v1-stable/input-output/read.md deleted file mode 100644 index c38778e..0000000 --- a/api-reference-v1-stable/input-output/read.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -description: >- - The generic read function loads a tabular data using the Frictionless - specification. ---- - -# read - -> danfo.**read**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] - - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - stringA path to the file/resources. It can be a local file, a URL to tabular - data (CSV, EXCEL) or Datahub.io Data Resource.
configs - object -

-

Configuration options. Supported params are:

-

data_num (Defaults => 0): The specific dataset to load, when - reading data from a datapackage.json,

-

header (Defaults => true): Whether the dataset contains a header - or not.

-

sheet (Defaults => 0): Number of the excel sheet which u want - to load.

-

}

-
- -**Returns:** - - ****_**Promise**_. Resolves to DataFrame - -The **read** function uses [frictionless.js](https://github.com/frictionlessdata/frictionless-js) underhood.[`frictionless.js`](https://github.com/frictionlessdata/frictionless-js) is a lightweight, standardized "stream-plus-metadata" interface for accessing files and datasets, especially tabular ones \(CSV, Excel\). It follows the [Frictionless spec](https://frictionlessdata.io/specs/) - -> ### **Note**: The `read` method is only available in danfojs-node at the moment. - -### Read a CSV file - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("file.csv") - let sample = await df.sample(10) - sample.print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### **Loading Files from URL** - -By specifying a valid URL, you can load CSV/EXCEL file: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") - df.head().print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### Loading Data from a Data Package Descriptor - -You can load data from a frictionless data package [descriptor](https://specs.frictionlessdata.io/data-package/#descriptor). A data package descriptor is a central file in a Data Package. It is a JSON file that provides: - -* General metadata such as the package’s title, license, publisher etc -* A list of the data “resources” that make up the package including their location on disk or online and other relevant information \(including, possibly, schema information about these data resources in a structured form\) - -For instance, in the example below, we load the first resource in the [Natural Gas dataset](https://datahub.io/core/natural-gas) from datahub.io. - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - const package_url = - "https://datahub.io/core/natural-gas/datapackage.json"; - - const df = await dfd.read(package_url, { data_num: 1 }); - df.head().print(); - -load_data() -``` -{% endtab %} -{% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Date │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1997-01-07 │ 3.81999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1997-01-08 │ 3.79999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 1997-01-09 │ 3.60999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 1997-01-10 │ 3.91999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ 1997-01-13 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference-v1-stable/plotting/README.md b/api-reference-v1-stable/plotting/README.md deleted file mode 100644 index 93161e3..0000000 --- a/api-reference-v1-stable/plotting/README.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: >- - DataFrame and Series have inbuilt support for plotting using Plotly's backend. - All customization can be done using Plotly's parameter passed to the config - object. ---- - -# Plotting - -* [Line Charts](line-charts.md) -* [Bar Charts](bar-charts.md) -* [Scatter Plots](scatter-plots.md) -* [Histograms](histograms.md) -* [Pie Charts](pie-charts.md) -* [Tables](tables.md) -* [Box Plots](box-plots.md) -* [Violin Plots](violin-plots.md) -* [Timeseries Plots](timeseries-plots.md) - diff --git a/api-reference-v1-stable/plotting/bar-charts.md b/api-reference-v1-stable/plotting/bar-charts.md deleted file mode 100644 index aee82cd..0000000 --- a/api-reference-v1-stable/plotting/bar-charts.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -description: Makes a vertical bar plot. ---- - -# Bar Charts - -A bar plot presents categorical data with rectangular bars with lengths proportional to the values that they represent. - -## Examples - -The **bar** plot is exposed by the .**plot\(\)** function called on a Series or DataFrame. The **.plot\(\)** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. - -### Bar plot on Series - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-6-.png) - -### Bar plot on DataFrame - -```markup - - - - - - - - - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-7-.png) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} - diff --git a/api-reference-v1-stable/plotting/box-plots.md b/api-reference-v1-stable/plotting/box-plots.md deleted file mode 100644 index 8a6e490..0000000 --- a/api-reference-v1-stable/plotting/box-plots.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -description: Make a box plot from DataFrame columns. ---- - -# Box Plots - -Make a box-and-whisker plot from DataFrame columns, optionally grouped by some other columns. A box plot is a method for graphically depicting groups of numerical data through their quartiles. - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-23-.png) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am%20%281%29%20%281%29.png) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-24-.png) - - - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} - diff --git a/api-reference-v1-stable/plotting/configuring-your-plots.md b/api-reference-v1-stable/plotting/configuring-your-plots.md deleted file mode 100644 index 7d96b4d..0000000 --- a/api-reference-v1-stable/plotting/configuring-your-plots.md +++ /dev/null @@ -1,69 +0,0 @@ -# Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. - -For example in the following code, we show how to set some basic configuration as well as layout for a line plot. - -```markup - - - - - - - - - - - -
- - - - -``` - -![](../../.gitbook/assets/newplot-32-.png) - diff --git a/api-reference-v1-stable/plotting/histograms.md b/api-reference-v1-stable/plotting/histograms.md deleted file mode 100644 index 12497e3..0000000 --- a/api-reference-v1-stable/plotting/histograms.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: 'Draw one histogram of the DataFrame’s columns, or single histogram for Series' ---- - -# Histograms - -A histogram is a representation of the distribution of data. This function groups the values of all given Series in the DataFrame into bins - -## Examples - -### Histogram of a Column in a DataFrame - -In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-10-.png) - -### Customized Histogram plots on DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-20-.png) - -### Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: - -```javascript -var layout = { - title: 'A sample plot', - xaxis: { - title: 'X', - }, - yaxis: { - title: 'Y', - } -} - -df.plot("div_tag").histogram({layout: layout}) -``` - -{% hint style="info" %} -For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. -{% endhint %} - diff --git a/api-reference-v1-stable/plotting/line-charts.md b/api-reference-v1-stable/plotting/line-charts.md deleted file mode 100644 index 73326f4..0000000 --- a/api-reference-v1-stable/plotting/line-charts.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: >- - Plot Series or DataFrame as lines. This function is useful to plot lines using - DataFrame’s values as coordinates. ---- - -# Line Charts - -## Examples - -### Basic Line plot on Series - -The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-4-.png) - -### Line plots on DataFrame - -The example below shows the plot of column values against a common x-axis (index) - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](<../../.gitbook/assets/newplot-2- (1) (1) (2) (2).png>) - -The example below shows how to plot two columns in a DataFrame against each other. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-3-.png) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/pie-charts.md b/api-reference-v1-stable/plotting/pie-charts.md deleted file mode 100644 index c355bcb..0000000 --- a/api-reference-v1-stable/plotting/pie-charts.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -description: Generate a pie plot. ---- - -# Pie Charts - -A pie plot is a proportional representation of the numerical data in a column - -## Examples - -### Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-12-.png) - -### Multiple Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-21-.png) - -### Configure Position of Pie Charts - -If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-22-.png) - -{% hint style="info" %} -For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. -{% endhint %} - diff --git a/api-reference-v1-stable/plotting/scatter-plots.md b/api-reference-v1-stable/plotting/scatter-plots.md deleted file mode 100644 index 739a49f..0000000 --- a/api-reference-v1-stable/plotting/scatter-plots.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -description: Create a scatter plot of columns in a DataFrame ---- - -# Scatter Plots - -The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. - -## Examples - -### Scatter Plots on Columns in a DataFrame - -In the example below, we use the titanic dataset, to show a close to real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-8-%20%281%29.png) - -### More Examples - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-19-.png) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} - diff --git a/api-reference-v1-stable/plotting/tables.md b/api-reference-v1-stable/plotting/tables.md deleted file mode 100644 index efa1fbb..0000000 --- a/api-reference-v1-stable/plotting/tables.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -description: Turn DataFrame/Series in D3.js-based tables ---- - -# Tables - -## Examples - -### Create Interactive Tables from DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png) - -### Configure the header and cell of a table - -To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. - -```markup - - - - - - - - - Document - - - - -
- - - - - - -``` - -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png) - diff --git a/api-reference-v1-stable/plotting/timeseries-plots.md b/api-reference-v1-stable/plotting/timeseries-plots.md deleted file mode 100644 index 7bbb089..0000000 --- a/api-reference-v1-stable/plotting/timeseries-plots.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Timeseries plot are based on date index ---- - -# Timeseries Plots - -## Examples - -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot-29- (2) (1).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/violin-plots.md b/api-reference-v1-stable/plotting/violin-plots.md deleted file mode 100644 index e0c1c8f..0000000 --- a/api-reference-v1-stable/plotting/violin-plots.md +++ /dev/null @@ -1,116 +0,0 @@ -# Violin Plots - -Make a violin plot from DataFrame columns, optionally grouped by some other columns. A violin plot is a method for graphically depicting groups of numerical data through their quartiles. See also [Box Plot](box-plots.md) - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-25-.png) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-26-.png) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](../../.gitbook/assets/newplot-27-.png) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} - diff --git a/api-reference-v1-stable/series/README.md b/api-reference-v1-stable/series/README.md deleted file mode 100644 index 7eefaa7..0000000 --- a/api-reference-v1-stable/series/README.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -description: One-dimensional ndarray with axis labels (including time series). ---- - -# Series - -> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ],** index: **\[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] - -### Attributes - -| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | -| --------------------------------- | ------------------------------------------- | - -| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | -| ----------------------------------- | ---------------------------------------------------------------- | -| [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | -| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | -| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | -| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | - -### Conversion - -| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | -| --------------------------------------------------- | ---------------------------------------------- | -| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| | | -| ------------------------------------------------------- | ------------------------------------------------------------------ | -| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | -| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | - -### Binary operator functions - -| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | -| --------------------------------- | --------------------------------------------------------------------------------------- | -| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | -| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | -| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | -| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | -| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | -| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | -| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | -| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | -| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | -| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | -| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | -| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | -| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | - -### Function application & GroupBy - -| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | -| --------------------------------- | ------------------------------------------------------- | -| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | - -### Computations / descriptive stats - -| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | -| ----------------------------------------------------------- | ---------------------------------------------------------------- | -| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | -| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | -| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | -| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | -| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | -| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | -| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | -| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | -| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | -| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | -| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | -| [`Series.unique`](series.unique.md) | Return unique values of Series object. | -| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value_counts.md) | Return a Series containing counts of unique values. | - -### Reindexing / selection / label manipulation - -| | | -| ----------------------------------------------------- | -------------------------------------------------------- | -| [`Series.drop_duplicates`](series.drop_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------- | ------------------------------------------------ | -| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | -| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | -| [`Series.isna`](series.isna.md) | Detect missing values. | -| [`Series.replace`](series.replace.md) | Replace values given in to_replace with value. | - -### Reshaping, sorting - -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| --------------------------------------------- | ------------------------------------------------------------- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort_values.md) | Sort by the values. | - -### Accessors - -Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. - -| Data Type | Accessor | -| --------- | -------- | -| Datetime | dt | -| String | str | - -#### Datetimelike properties - -`Series.dt` can be used to access the values of the series as datetime and return several properties. These can be accessed like `Series.dt.`. - -**Datetime methods** - -| | | -| ------------------------------------------------- | ------------------------------------------------------------------ | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | -| [`Series.dt.month_name`](series.dt.month_name.md) | Return the month names of the DateTimeIndex with specified locale. | - -#### String handling - -`Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. - -| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | -| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | -| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | -| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | -| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | -| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | -| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | -| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | -| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | -| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | -| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | -| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | -| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | -| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | -| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | -| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | -| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | -| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | -| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| ----------------------------------------------------- | ------------------------------------------------------------- | -| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | -| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| ----------------------------------------------------- | ---------------------------------------------------- | -| [`Series.to_csv`](../dataframe/dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | -| [`Series.to_json`](../dataframe/dataframe.to_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/series/creating-a-series.md b/api-reference-v1-stable/series/creating-a-series.md deleted file mode 100644 index 3c8e4ba..0000000 --- a/api-reference-v1-stable/series/creating-a-series.md +++ /dev/null @@ -1,210 +0,0 @@ -# Creating a Series - -new danfo.**Series**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. - -### Creating a Series from an object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```javascript -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series from an array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = ["bval1", "bval2", "bval3", "bval4"] -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series and specifying index and dtypes - -You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. - -> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2, 3, 4, 5]; -let index = ["a", "b", "c", "d", "e"]; -let dtypes = ["int32",] - -let df = new Series(data1, { index, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╚═══╧═══╝ -``` - -### Creating a Series and specifying memory mode - -To use less space on Series creation, you can set the low memory mode as demonstrated below: - -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2.3, 3, 4, 5, "girl"]; - -let df = new Series(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the Series. -{% endhint %} - diff --git a/api-reference-v1-stable/series/danfo.series.add.md b/api-reference-v1-stable/series/danfo.series.add.md deleted file mode 100644 index 7cd6150..0000000 --- a/api-reference-v1-stable/series/danfo.series.add.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: 'Return Addition of series and other, element-wise (binary operator add).' ---- - -# danfo.Series.add - -Return Addition of series and other, element-wise \(binary operator add\). - - **parameter:** {other} Series or Number to add - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 6] -let data2 = [30, 40, 39, 1, 2, 1] -let sf = new Series(data) -let sf2 = new Series(data2) -sf.add(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.apply.md b/api-reference-v1-stable/series/danfo.series.apply.md deleted file mode 100644 index d59a99c..0000000 --- a/api-reference-v1-stable/series/danfo.series.apply.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -description: invoke a function on Series Value ---- - -# danfo.Series.apply - -> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function | Function \(can be anonymous\) to apply | | - -**Returns:** - - ****return **Series** - -\*\*\*\* - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply1.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_apply2.png) - - - diff --git a/api-reference-v1-stable/series/danfo.series.copy.md b/api-reference-v1-stable/series/danfo.series.copy.md deleted file mode 100644 index c610c04..0000000 --- a/api-reference-v1-stable/series/danfo.series.copy.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.copy - -Make a new copy of Series - - - -**parameter:** - - **return:** {Series} - -**Example** - -```javascript -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf_copy = sf.copy() - - -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf = sf.set_index({ "index": ["a", "b", "c", "d"] }) -sf_copy = sf.copy() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.count.md b/api-reference-v1-stable/series/danfo.series.count.md deleted file mode 100644 index 50a5789..0000000 --- a/api-reference-v1-stable/series/danfo.series.count.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.count - -Return number of non-NA/null observations in the Series. - -This is equivalent to the method numpy.sum - - **parameter:** - - **return:** {Number}, sum of values in Series - -**Example** - -```javascript -let data = ["boy", "gitl", "woman", NaN] -let sf = new Series(data) -sf.count() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.describe.md b/api-reference-v1-stable/series/danfo.series.describe.md deleted file mode 100644 index 184dbe9..0000000 --- a/api-reference-v1-stable/series/danfo.series.describe.md +++ /dev/null @@ -1,26 +0,0 @@ -# danfo.Series.describe - - - -Generate descriptive statistics. Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding NaN values - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three"] }) - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -df.reset_index() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.div.md b/api-reference-v1-stable/series/danfo.series.div.md deleted file mode 100644 index ae2731b..0000000 --- a/api-reference-v1-stable/series/danfo.series.div.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# danfo.Series.div - -Return division of series and other, element-wise \(binary operator div\). - -Equivalent to series / other - - **parameter:** {other} Series, Number to divide with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.div(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.head.md b/api-reference-v1-stable/series/danfo.series.head.md deleted file mode 100644 index 1bc9d5e..0000000 --- a/api-reference-v1-stable/series/danfo.series.head.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -description: This function returns the first n rows for the object based on position. ---- - -# danfo.Series.head - - - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let cols = ["A"] -let sf = new Series(data, { columns: cols }) -sf.head() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.map.md b/api-reference-v1-stable/series/danfo.series.map.md deleted file mode 100644 index 9d7cad4..0000000 --- a/api-reference-v1-stable/series/danfo.series.map.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: Map the value of a series to it representation ---- - -# danfo.Series.map - -> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] - -| Parameter | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function or Object | callable can either be a function or an object\({}\) | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map) - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map1.png) - diff --git a/api-reference-v1-stable/series/danfo.series.max.md b/api-reference-v1-stable/series/danfo.series.max.md deleted file mode 100644 index cac4ba1..0000000 --- a/api-reference-v1-stable/series/danfo.series.max.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.max - diff --git a/api-reference-v1-stable/series/danfo.series.maximum.md b/api-reference-v1-stable/series/danfo.series.maximum.md deleted file mode 100644 index 9082120..0000000 --- a/api-reference-v1-stable/series/danfo.series.maximum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.maximum - -Return maximum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check maximum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.maximum(sf2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.mean.md b/api-reference-v1-stable/series/danfo.series.mean.md deleted file mode 100644 index 6ace487..0000000 --- a/api-reference-v1-stable/series/danfo.series.mean.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mean - diff --git a/api-reference-v1-stable/series/danfo.series.median.md b/api-reference-v1-stable/series/danfo.series.median.md deleted file mode 100644 index 077c0ec..0000000 --- a/api-reference-v1-stable/series/danfo.series.median.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.median - diff --git a/api-reference-v1-stable/series/danfo.series.min.md b/api-reference-v1-stable/series/danfo.series.min.md deleted file mode 100644 index 22f3589..0000000 --- a/api-reference-v1-stable/series/danfo.series.min.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.min - diff --git a/api-reference-v1-stable/series/danfo.series.minimum.md b/api-reference-v1-stable/series/danfo.series.minimum.md deleted file mode 100644 index 2a9d9c6..0000000 --- a/api-reference-v1-stable/series/danfo.series.minimum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.minimum - - - -Return minimum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check minimum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.minimum(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.mod.md b/api-reference-v1-stable/series/danfo.series.mod.md deleted file mode 100644 index 577014d..0000000 --- a/api-reference-v1-stable/series/danfo.series.mod.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Modulo of series and other, element-wise (binary operator mod).' ---- - -# danfo.Series.mod - -Return Modulo of series and other, element-wise \(binary operator mod\). - -Equivalent to series % other - - **parameter:** {other} Series, Number - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mod(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.mode.md b/api-reference-v1-stable/series/danfo.series.mode.md deleted file mode 100644 index 8d86e6e..0000000 --- a/api-reference-v1-stable/series/danfo.series.mode.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mode - diff --git a/api-reference-v1-stable/series/danfo.series.mul.md b/api-reference-v1-stable/series/danfo.series.mul.md deleted file mode 100644 index 6cdac92..0000000 --- a/api-reference-v1-stable/series/danfo.series.mul.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: 'Return Multiplication of series and other, element-wise (binary operator mul).' ---- - -# danfo.Series.mul - -Return Multiplication of series and other, element-wise \(binary operator mul\). - -Equivalent to series \* other, but with support to substitute a fill\_value for missing data in one of the inputs. - - **parameter:** {Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mul(sf2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.pow.md b/api-reference-v1-stable/series/danfo.series.pow.md deleted file mode 100644 index 291a993..0000000 --- a/api-reference-v1-stable/series/danfo.series.pow.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# danfo.Series.pow - -Return Exponential power of series and other, element-wise \(binary operator pow\). - -Equivalent to series \*\* other - - **parameter:** {other} Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.pow(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.reset_index.md b/api-reference-v1-stable/series/danfo.series.reset_index.md deleted file mode 100644 index 7a908a9..0000000 --- a/api-reference-v1-stable/series/danfo.series.reset_index.md +++ /dev/null @@ -1,31 +0,0 @@ -# danfo.Series.reset\_index - - - -Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. - - - -**parameter:** {kwargs} {inplace: Modify the Series in place \(do not create a new object, drop: Just reset the index, without inserting it as a column in the new DataFrame.} - - **return:** {Series} - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -let df_reset = df_new.reset_index() -df_reset.print() - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -let df_new = df.reset_index() -df_new -``` - diff --git a/api-reference-v1-stable/series/danfo.series.round.md b/api-reference-v1-stable/series/danfo.series.round.md deleted file mode 100644 index 2bbacbb..0000000 --- a/api-reference-v1-stable/series/danfo.series.round.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.round - -Round each value in a Series to the given number of decimals. - - - - **parameter:** {dp} Number, Numbers of Decimal places to round to - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf = new Series(data1) -sf.round(1) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.sample.md b/api-reference-v1-stable/series/danfo.series.sample.md deleted file mode 100644 index fa8f326..0000000 --- a/api-reference-v1-stable/series/danfo.series.sample.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# danfo.Series.sample - -Gets \[num\] number of random rows in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.sample(2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.set_index.md b/api-reference-v1-stable/series/danfo.series.set_index.md deleted file mode 100644 index 5cb3d28..0000000 --- a/api-reference-v1-stable/series/danfo.series.set_index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# danfo.Series.set\_index - -> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object {} | The object contains the key **index** and assigned an array value of equal length to the Series. format {"index": \[Array\] } | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series.reset_index.png) - -```javascript -const dfd = require("danfojs") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["H", "L", "M","F","T"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_reset_index2.png) - diff --git a/api-reference-v1-stable/series/danfo.series.sort_values.md b/api-reference-v1-stable/series/danfo.series.sort_values.md deleted file mode 100644 index 0a0c4e7..0000000 --- a/api-reference-v1-stable/series/danfo.series.sort_values.md +++ /dev/null @@ -1,27 +0,0 @@ -# danfo.Series.sort\_values - - - -Sort a Series in ascending or descending order by some criterion. - - - - **parameter:** {kwargs} Object, {ascending \(Bool\): Whether to return sorted values in ascending order or not, inplace \(Bool\): Whether to perform sorting on the original Series or not} - - **return:** {Number} - -**Example** - -```javascript -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values() - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "inplace": true }) - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "ascending": false, "inplace": true }) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.std.md b/api-reference-v1-stable/series/danfo.series.std.md deleted file mode 100644 index 8f48ef2..0000000 --- a/api-reference-v1-stable/series/danfo.series.std.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.std - -Return sample standard deviation over requested axis. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.std() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.sub.md b/api-reference-v1-stable/series/danfo.series.sub.md deleted file mode 100644 index 8867c14..0000000 --- a/api-reference-v1-stable/series/danfo.series.sub.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Subtraction of series and other, element-wise (binary operator sub).' ---- - -# danfo.Series.sub - -Returns the subtraction between a series and other, element-wise \(binary operator subtraction\). - -Equivalent to series - other - - **parameter:** {other} Series, Number to subtract - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 39, 1, 2, 1] -let data2 = [1, 2, 3, 4, 5, 6] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.sub(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.sum-1.md b/api-reference-v1-stable/series/danfo.series.sum-1.md deleted file mode 100644 index 6ec14cb..0000000 --- a/api-reference-v1-stable/series/danfo.series.sum-1.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.sum - -Return the sum of the values for the requested axis. - -This is equivalent to the method numpy.sum. - - **parameter:** - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.sum() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.tail.md b/api-reference-v1-stable/series/danfo.series.tail.md deleted file mode 100644 index e83307d..0000000 --- a/api-reference-v1-stable/series/danfo.series.tail.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# danfo.Series.tail - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.tail() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.tostring.md b/api-reference-v1-stable/series/danfo.series.tostring.md deleted file mode 100644 index 5807850..0000000 --- a/api-reference-v1-stable/series/danfo.series.tostring.md +++ /dev/null @@ -1,18 +0,0 @@ -# danfo.Series.toString - - - -Prints the data in a Series as a grid of row and columns - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript - -``` - diff --git a/api-reference-v1-stable/series/danfo.series.var.md b/api-reference-v1-stable/series/danfo.series.var.md deleted file mode 100644 index 822edc7..0000000 --- a/api-reference-v1-stable/series/danfo.series.var.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.var - - - -Return unbiased variance of Series. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.var() -``` - diff --git a/api-reference-v1-stable/series/series.abs.md b/api-reference-v1-stable/series/series.abs.md deleted file mode 100644 index 3c9f46a..0000000 --- a/api-reference-v1-stable/series/series.abs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Returns the absolute value in a Series ---- - -# Series.abs - -> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| - -**Returns: **Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [-10, 45, 56, -25, 23, -20, 10] -let sf = new dfd.Series(data1) - -sf.abs().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.add.md b/api-reference-v1-stable/series/series.add.md deleted file mode 100644 index e55b1b8..0000000 --- a/api-reference-v1-stable/series/series.add.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Addition of series and other, element-wise (binary operator add). ---- - -# Series.add - -> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.add(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 31 ║ -╟───┼──────────────────────╢ -║ 1 │ 42 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.add(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 5 ║ -╟───┼──────────────────────╢ -║ 3 │ 6 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.and.md b/api-reference-v1-stable/series/series.and.md deleted file mode 100644 index 85c22cb..0000000 --- a/api-reference-v1-stable/series/series.and.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical AND between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.and - -> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical AND between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.and(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ false ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.append.md b/api-reference-v1-stable/series/series.append.md deleted file mode 100644 index 9c84620..0000000 --- a/api-reference-v1-stable/series/series.append.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: Add a new value or values to the end of a Series. ---- - -# Series.append - -danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | -| newValue | Array, Series | Object to append | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | -| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | - -**Returns:** - -** **return** Series** - -**** - -### **Append new Series to the end of a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) - -new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) -new_sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` -{% endtab %} -{% endtabs %} - -### **Append new Series to the end of a Series in-place** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) -let newIndex = ["f5", "f6", "f7"] - -sf1.append(sf2, newIndex, { inplace: true }) -sf1.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` - -### **Append an array to the end of Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sfArr = ["a", "b", "c"] - -new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) -new_sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.apply.md b/api-reference-v1-stable/series/series.apply.md deleted file mode 100644 index d5feb72..0000000 --- a/api-reference-v1-stable/series/series.apply.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -description: Invoke a function on each value in a Series. ---- - -# Series.apply - -> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function | Function (can be anonymous) to apply | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** - -** **return** Series** - -**** - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╟───┼──────────────────────╢ -║ 5 │ 12 ║ -╟───┼──────────────────────╢ -║ 6 │ 14 ║ -╟───┼──────────────────────╢ -║ 7 │ 16 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0.6931471805599453 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.0986122886681096 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.3862943611198906 ║ -╟───┼──────────────────────╢ -║ 4 │ 1.6094379124341003 ║ -╟───┼──────────────────────╢ -║ 5 │ 1.791759469228055 ║ -╟───┼──────────────────────╢ -║ 6 │ 1.9459101490553132 ║ -╟───┼──────────────────────╢ -║ 7 │ 2.0794415416798357 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ rice ║ -╟───┼──────────────────────╢ -║ 1 │ beans ║ -╟───┼──────────────────────╢ -║ 2 │ yam ║ -╟───┼──────────────────────╢ -║ 3 │ banana ║ -╟───┼──────────────────────╢ -║ 4 │ wheat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argmax.md b/api-reference-v1-stable/series/series.argmax.md deleted file mode 100644 index d7927d2..0000000 --- a/api-reference-v1-stable/series/series.argmax.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the largest value in the series ---- - -# Series.argmax - -> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmax() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -7 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argmin.md b/api-reference-v1-stable/series/series.argmin.md deleted file mode 100644 index dfc661f..0000000 --- a/api-reference-v1-stable/series/series.argmin.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the smallest value in the series ---- - -# Series.argmin - -> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmin() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -0 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argsort.md b/api-reference-v1-stable/series/series.argsort.md deleted file mode 100644 index 443935e..0000000 --- a/api-reference-v1-stable/series/series.argsort.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Return the integer indices that would sort the Series values ---- - -# Series.argsort - -> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | -| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| - -**Returns: ** Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [10, 45, 20, 10, 23, 20, 30, 11] -let sf = new dfd.Series(data) - -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 7 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 6 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -//sorted in descending order -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 6 ║ -╟───┼───╢ -║ 2 │ 4 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╟───┼───╢ -║ 6 │ 0 ║ -╟───┼───╢ -║ 7 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.astype.md b/api-reference-v1-stable/series/series.astype.md deleted file mode 100644 index 15a61ae..0000000 --- a/api-reference-v1-stable/series/series.astype.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.astype - diff --git a/api-reference-v1-stable/series/series.copy.md b/api-reference-v1-stable/series/series.copy.md deleted file mode 100644 index 9bbdb47..0000000 --- a/api-reference-v1-stable/series/series.copy.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Makes a deep copy of a Series ---- - -# Series.copy - -> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] - -**parameter:** - -**Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.copy() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21091 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.190901 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.564 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.0212 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.corr.md b/api-reference-v1-stable/series/series.corr.md deleted file mode 100644 index ee3263f..0000000 --- a/api-reference-v1-stable/series/series.corr.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.corr - diff --git a/api-reference-v1-stable/series/series.count.md b/api-reference-v1-stable/series/series.count.md deleted file mode 100644 index 832c794..0000000 --- a/api-reference-v1-stable/series/series.count.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the total number of values in a series ---- - -# Series.count - -> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.count()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -9 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.cummax.md b/api-reference-v1-stable/series/series.cummax.md deleted file mode 100644 index 8aded1a..0000000 --- a/api-reference-v1-stable/series/series.cummax.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns cumulative maximum over a series ---- - -# Series.cummax - -> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummax().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 56 ║ -╟───┼──────────────────────╢ -║ 5 │ 56 ║ -╟───┼──────────────────────╢ -║ 6 │ 56 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cummin.md b/api-reference-v1-stable/series/series.cummin.md deleted file mode 100644 index 736cee5..0000000 --- a/api-reference-v1-stable/series/series.cummin.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns the cumulative min of a Series ---- - -# Series.cummin - -> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 5, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummin().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ 10 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 5 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumprod.md b/api-reference-v1-stable/series/series.cumprod.md deleted file mode 100644 index 84ec0e7..0000000 --- a/api-reference-v1-stable/series/series.cumprod.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Return the cumulative product of a series ---- - -# Series.cumprod - -> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumprod().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 450 ║ -╟───┼──────────────────────╢ -║ 2 │ 25200 ║ -╟───┼──────────────────────╢ -║ 3 │ 630000 ║ -╟───┼──────────────────────╢ -║ 4 │ 14490000 ║ -╟───┼──────────────────────╢ -║ 5 │ 289800000 ║ -╟───┼──────────────────────╢ -║ 6 │ 2898000000 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumsum.md b/api-reference-v1-stable/series/series.cumsum.md deleted file mode 100644 index 7b7a19a..0000000 --- a/api-reference-v1-stable/series/series.cumsum.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a cumulative sum of a series ---- - -# Series.cumsum - -> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumsum().print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 55 ║ -╟───┼──────────────────────╢ -║ 2 │ 111 ║ -╟───┼──────────────────────╢ -║ 3 │ 136 ║ -╟───┼──────────────────────╢ -║ 4 │ 159 ║ -╟───┼──────────────────────╢ -║ 5 │ 179 ║ -╟───┼──────────────────────╢ -║ 6 │ 189 ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference-v1-stable/series/series.describe.md b/api-reference-v1-stable/series/series.describe.md deleted file mode 100644 index f532bac..0000000 --- a/api-reference-v1-stable/series/series.describe.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -description: >- - Generate descriptive statistics. Descriptive statistics include those that - summarize the central tendency, dispersion and shape of a dataset’s - distribution, excluding NaN values ---- - -# Series.describe - -> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] - -**Parameters: **No parameter - -**return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) -sf.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔══════════╤══════════════════════╗ -║ │ 0 ║ -╟──────────┼──────────────────────╢ -║ count │ 6 ║ -╟──────────┼──────────────────────╢ -║ mean │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ std │ 1.8708286933869707 ║ -╟──────────┼──────────────────────╢ -║ min │ 1 ║ -╟──────────┼──────────────────────╢ -║ median │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ max │ 6 ║ -╟──────────┼──────────────────────╢ -║ variance │ 3.5 ║ -╚══════════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.div.md b/api-reference-v1-stable/series/series.div.md deleted file mode 100644 index 656a796..0000000 --- a/api-reference-v1-stable/series/series.div.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# Series.div - -> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -divide with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.div(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 20 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### divide with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.div(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.5 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.5 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dot.md b/api-reference-v1-stable/series/series.dot.md deleted file mode 100644 index 61a8bc2..0000000 --- a/api-reference-v1-stable/series/series.dot.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.dot - diff --git a/api-reference-v1-stable/series/series.drop_duplicates.md b/api-reference-v1-stable/series/series.drop_duplicates.md deleted file mode 100644 index c169043..0000000 --- a/api-reference-v1-stable/series/series.drop_duplicates.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Remove duplicate rows ---- - -# Series.drop_duplicates - -> danfo.Series.**drop_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | -| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| - -**Returns: **Series - -**Examples** - -### Drop duplicate by keeping the first occurrence of the duplicate value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates() - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop duplicate and keep only the last duplicated value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates({keep:"last"}) - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Remove duplicate value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] -let sf = new dfd.Series(data1) -sf.drop_duplicates({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ A ║ -╟───┼──────────────────────╢ -║ 3 │ B ║ -╟───┼──────────────────────╢ -║ 5 │ C ║ -╟───┼──────────────────────╢ -║ 7 │ D ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dropna.md b/api-reference-v1-stable/series/series.dropna.md deleted file mode 100644 index 2fab716..0000000 --- a/api-reference-v1-stable/series/series.dropna.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -description: Remove missing values from Series ---- - -# Series.dropna - -> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Drop all nan value and then return New Series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.dropna() - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop nan values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -sf.dropna({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.day.md b/api-reference-v1-stable/series/series.dt.day.md deleted file mode 100644 index d3722c4..0000000 --- a/api-reference-v1-stable/series/series.dt.day.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the numerical representation of the week day. ---- - -# Series.dt.day - -> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] - -**Parameters**: None - -**Returns: **Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) -let sf = new dfd.Series(data) - -sf.dt.day().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═══╗ -║ 0 │ 6 ║ -╟───┼───╢ -║ 1 │ 0 ║ -╟───┼───╢ -║ 2 │ 1 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 4 ║ -╟───┼───╢ -║ 6 │ 5 ║ -╟───┼───╢ -║ 7 │ 6 ║ -╟───┼───╢ -║ 8 │ 0 ║ -╟───┼───╢ -║ 9 │ 1 ║ -╚═══╧═══╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.hour.md b/api-reference-v1-stable/series/series.dt.hour.md deleted file mode 100644 index 9656aff..0000000 --- a/api-reference-v1-stable/series/series.dt.hour.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the hours in a time series ---- - -# Series.dt.hour - -> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] - -**Parameters: **None - -**Returns: **Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) -let sf = new dfd.Series(data) -// print series -sf.print() -// print hour series -sf.dt.hours().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 2:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.minute.md b/api-reference-v1-stable/series/series.dt.minute.md deleted file mode 100644 index 97baa73..0000000 --- a/api-reference-v1-stable/series/series.dt.minute.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the minutes in a Time Series ---- - -# Series.dt.minutes - -> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] - -**Parameters**: None - -**Returns: **Series (int Elements) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) -let sf = new dfd.Series(data) -//print the series -sf.print() -//print the minutes series -sf.dt.minutes().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:01:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:02:00 AM ║ -╚═══╧══════════════════════╝ - -//print the minutes series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.month.md b/api-reference-v1-stable/series/series.dt.month.md deleted file mode 100644 index 09841bc..0000000 --- a/api-reference-v1-stable/series/series.dt.month.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: Obtain the month in a date time series ---- - -# Series.dt.month - -> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] - -**Parameters**: None - -**Returns: **Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) -let sf = new dfd.Series(data) - -sf.dt.month().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 0 │ 6 ║ -╟───┼────╢ -║ 1 │ 7 ║ -╟───┼────╢ -║ 2 │ 9 ║ -╟───┼────╢ -║ 3 │ 9 ║ -╟───┼────╢ -║ 4 │ 11 ║ -╟───┼────╢ -║ 5 │ 11 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.month_name.md b/api-reference-v1-stable/series/series.dt.month_name.md deleted file mode 100644 index 2deb259..0000000 --- a/api-reference-v1-stable/series/series.dt.month_name.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: obtain the month name in a Time Series ---- - -# Series.dt.month_name - -> danfo.Series.dt.month_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] - -**Parameters**: None - -**Returns: **Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print month names -sf.dt.month_name().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 2/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 3/1/2018, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═════╗ -║ 0 │ Jan ║ -╟───┼─────╢ -║ 1 │ Feb ║ -╟───┼─────╢ -║ 2 │ Mar ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.monthday.md b/api-reference-v1-stable/series/series.dt.monthday.md deleted file mode 100644 index 70026a5..0000000 --- a/api-reference-v1-stable/series/series.dt.monthday.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the day of the month ---- - -# Series.dt.monthday - -> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] - -**Parameters: **None - -**Returns**: Series (Int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print monthdays -sf.dt.monthday().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/2/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/3/2000, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.second.md b/api-reference-v1-stable/series/series.dt.second.md deleted file mode 100644 index 68d63b3..0000000 --- a/api-reference-v1-stable/series/series.dt.second.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the seconds in Date series ---- - -# Series.dt.seconds - -> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] - -**Parameters**: None - -**Returns: **Series (Int elements) - -**Example** - -Obtain the seconds of the datetime - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) -let sf = new dfd.Series(data) -//print the series frame -sf.print() - -//print the seconds obtained -sf.dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:00:01 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:00:02 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 0 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.weekdays.md b/api-reference-v1-stable/series/series.dt.weekdays.md deleted file mode 100644 index 101bd50..0000000 --- a/api-reference-v1-stable/series/series.dt.weekdays.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -description: Obtain the days of the weeks ---- - -# Series.dt.weekdays - -> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] - -**Parameters**: None - -**Returns: **Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print days of the week -sf.dt.weekdays().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════════════════════════╗ -║ 0 │ 12/31/2016, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 9 │ 1/9/2017, 1:00:00 AM ║ -╚═══╧════════════════════════╝ - -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.year.md b/api-reference-v1-stable/series/series.dt.year.md deleted file mode 100644 index db495d9..0000000 --- a/api-reference-v1-stable/series/series.dt.year.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Obtain the year in a date time series ---- - -# Series.dt.year - -> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] - -**Parameters**: None - -**Returns: **Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) -let sf = new dfd.Series(data) -sf.print() -sf.dt.year().print() -``` -{% endtab %} -{% endtabs %} - -``` -//print date time series -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2001, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2002, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤══════╗ -║ 0 │ 2000 ║ -╟───┼──────╢ -║ 1 │ 2001 ║ -╟───┼──────╢ -║ 2 │ 2002 ║ -╚═══╧══════╝ -``` diff --git a/api-reference-v1-stable/series/series.dtype.md b/api-reference-v1-stable/series/series.dtype.md deleted file mode 100644 index c4634cb..0000000 --- a/api-reference-v1-stable/series/series.dtype.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dtype of a series ---- - -# Series.dtype - -> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] - -**Parameters**: None - -**Returns: **String - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.dtype) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.eq.md b/api-reference-v1-stable/series/series.eq.md deleted file mode 100644 index 43a3ece..0000000 --- a/api-reference-v1-stable/series/series.eq.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check all the values in a series is equal to another value ---- - -# Series.eq - -> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Examples** - -Compare all the values in a series to another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.eq(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check it all the values are equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.eq(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.fillna.md b/api-reference-v1-stable/series/series.fillna.md deleted file mode 100644 index a1db3a8..0000000 --- a/api-reference-v1-stable/series/series.fillna.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Replace all NaN value with specified value ---- - -# Series.fillna - -> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| - -**Examples** - -### Fill nan value and then return new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) - -let sf_rep = sf.fillna({ value: -999}) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill nan value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) -sf.fillna({ value: -999, inplace: true }) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ge.md b/api-reference-v1-stable/series/series.ge.md deleted file mode 100644 index ec83ef9..0000000 --- a/api-reference-v1-stable/series/series.ge.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the values in a series is greater than or equal a value ---- - -# Series.ge - -> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns: **Series (Boolean element) - -**Example** - -Compare all the value in a Series to the values in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ge(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check if all the value in a Series is greater than or equal a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ge(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.gt.md b/api-reference-v1-stable/series/series.gt.md deleted file mode 100644 index 184ca28..0000000 --- a/api-reference-v1-stable/series/series.gt.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the value in a series is greater than a value ---- - -# Series.gt - -> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are greater than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.gt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are greater than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.gt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.head.md b/api-reference-v1-stable/series/series.head.md deleted file mode 100644 index 2892263..0000000 --- a/api-reference-v1-stable/series/series.head.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Obtain the first n rows for the object based on position. ---- - -# Series.head - -> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of first n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.head().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.iloc.md b/api-reference-v1-stable/series/series.iloc.md deleted file mode 100644 index ab578cf..0000000 --- a/api-reference-v1-stable/series/series.iloc.md +++ /dev/null @@ -1,158 +0,0 @@ -# Series.iloc - -danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - -** **return** Series** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `"1:7"` - -_**Note: **only** **the start label is included, and the end label is ignored. _ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc([0,5]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["0:5"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 2.2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["5:"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╟───┼──────────────────────╢ -║ 6 │ 2.1 ║ -╟───┼──────────────────────╢ -║ 7 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.index.md b/api-reference-v1-stable/series/series.index.md deleted file mode 100644 index 1cc95da..0000000 --- a/api-reference-v1-stable/series/series.index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -description: Obtain the index of a Series ---- - -# Series.index - -> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.index) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 0, 1, 2, 3 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.isna.md b/api-reference-v1-stable/series/series.isna.md deleted file mode 100644 index cdf6343..0000000 --- a/api-reference-v1-stable/series/series.isna.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Detect Missing values ---- - -# Series.isna - -> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] - -**Parameters**: None - -**Returns**: Series \(Boolean element\) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, undefined, "girl", "Man"] -let sf = new dfd.Series(data1) - -sf.isna().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.le.md b/api-reference-v1-stable/series/series.le.md deleted file mode 100644 index 4571b72..0000000 --- a/api-reference-v1-stable/series/series.le.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all the values in a series is less than or equal to a value ---- - -# Series.le - -> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns: **Series (Boolean Element) - -**Example** - -Check if all the values in a series is less than or equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.le(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than equal to values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.le(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.loc.md b/api-reference-v1-stable/series/series.loc.md deleted file mode 100644 index aa36e72..0000000 --- a/api-reference-v1-stable/series/series.loc.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -description: Access a group of rows by label(s) or a boolean array. ---- - -# Series.loc - -danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - -** **return** Series** - -## **Examples** - -`.loc()` is label position based (from `0` to `length-1` of the row axis). - -Allowed inputs are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note: **only** **the start label is included, and the end label is ignored. _ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Indexing by specific row index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc(["a", "g"]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╟───┼─────╢ -║ e │ 30 ║ -╟───┼─────╢ -║ f │ 30 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╟───┼─────╢ -║ h │ 7 ║ -╚═══╧═════╝ - -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc([`"a":"e"`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -`s.loc([a:e]).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -`s.loc(["a":"e"]).print()`\ -\ -_**Inner quotes are not needed for numeric indices!**_ -{% endhint %} - -### By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -let s = new dfd.Series(data) - -s.loc([`1:`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 1 │ 34 ║ -╟───┼─────╢ -║ 2 │ 2.2 ║ -╟───┼─────╢ -║ 3 │ 2 ║ -╟───┼─────╢ -║ 4 │ 30 ║ -╟───┼─────╢ -║ 5 │ 30 ║ -╟───┼─────╢ -║ 6 │ 2.1 ║ -╟───┼─────╢ -║ 7 │ 7 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.loc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.lt.md b/api-reference-v1-stable/series/series.lt.md deleted file mode 100644 index 7af18bc..0000000 --- a/api-reference-v1-stable/series/series.lt.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all values in a Series are less than a value. ---- - -# Series.lt - -> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are less than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.lt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.lt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.map.md b/api-reference-v1-stable/series/series.map.md deleted file mode 100644 index 0e0850a..0000000 --- a/api-reference-v1-stable/series/series.map.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -description: Map the value of a series to a function or Object ---- - -# Series.map - -> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] - -| Parameter | Type | Description | Default | -| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function or Object | A function or object({}) | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Example** - -Mapping the element in a Series words in an Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ ok ║ -╟───┼──────────────────────╢ -║ 1 │ okie ║ -╟───┼──────────────────────╢ -║ 2 │ frit ║ -╟───┼──────────────────────╢ -║ 3 │ gop ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Mapping values in a Series to a representation using functions. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ I have 1 cat(s) ║ -╟───┼──────────────────────╢ -║ 1 │ I have 2 cat(s) ║ -╟───┼──────────────────────╢ -║ 2 │ I have 3 cat(s) ║ -╟───┼──────────────────────╢ -║ 3 │ I have 4 cat(s) ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.max.md b/api-reference-v1-stable/series/series.max.md deleted file mode 100644 index 4f7193a..0000000 --- a/api-reference-v1-stable/series/series.max.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the maximum value in a Series ---- - -# Series.max - -> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.max()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -89 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.maximum.md b/api-reference-v1-stable/series/series.maximum.md deleted file mode 100644 index afc5a48..0000000 --- a/api-reference-v1-stable/series/series.maximum.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Obtain the maximum number between two series ---- - -# Series.maximum - -> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.maximum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 41 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.mean.md b/api-reference-v1-stable/series/series.mean.md deleted file mode 100644 index 17d97e6..0000000 --- a/api-reference-v1-stable/series/series.mean.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the mean of a series ---- - -# Series.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mean()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -23.000001907348633 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.median.md b/api-reference-v1-stable/series/series.median.md deleted file mode 100644 index d1cde75..0000000 --- a/api-reference-v1-stable/series/series.median.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the median of a series ---- - -# Series.median - -> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.median()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -4 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.min.md b/api-reference-v1-stable/series/series.min.md deleted file mode 100644 index 6e11a67..0000000 --- a/api-reference-v1-stable/series/series.min.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the minimum value in a series ---- - -# Series.min - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.min()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -0 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.minimum.md b/api-reference-v1-stable/series/series.minimum.md deleted file mode 100644 index a06ba69..0000000 --- a/api-reference-v1-stable/series/series.minimum.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Obtain the minimum value between two series (element wise) ---- - -# Series.minimum - -> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.minimum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 40 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.mod.md b/api-reference-v1-stable/series/series.mod.md deleted file mode 100644 index fdf0555..0000000 --- a/api-reference-v1-stable/series/series.mod.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -description: Return Modulo of series and other, element-wise (binary operator mod). ---- - -# Series.mod - -> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\|float | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Modulus with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mod(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.8999999761581421 ║ -╟───┼──────────────────────╢ -║ 1 │ 1.3999993801116943 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.7000000476837158 ║ -╟───┼──────────────────────╢ -║ 3 │ 0.19999980926513672 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Modulo with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mod(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.mode.md b/api-reference-v1-stable/series/series.mode.md deleted file mode 100644 index 6077686..0000000 --- a/api-reference-v1-stable/series/series.mode.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the center value in a series ---- - -# Series.mode - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mode()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 4 ] -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.mul.md b/api-reference-v1-stable/series/series.mul.md deleted file mode 100644 index d5d33de..0000000 --- a/api-reference-v1-stable/series/series.mul.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Multiplication of series and other, element-wise (binary operator mul). ---- - -# Series.mul - -> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -multiplication with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mul(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 80 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -multiply with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mul(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.ndim.md b/api-reference-v1-stable/series/series.ndim.md deleted file mode 100644 index 8258e46..0000000 --- a/api-reference-v1-stable/series/series.ndim.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dimension of a series ---- - -# Series.ndim - -> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] - -**Parameters: **None - -**Returns: **int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.ndim) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -1 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ne.md b/api-reference-v1-stable/series/series.ne.md deleted file mode 100644 index 16cf1dc..0000000 --- a/api-reference-v1-stable/series/series.ne.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all values in a series is not equal to a value(s) ---- - -# Series.ne - -> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Example** - -Compare all the values in a series to that in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ne(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Compare all the values in a Series to a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ne(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.nunique.md b/api-reference-v1-stable/series/series.nunique.md deleted file mode 100644 index 1adfe98..0000000 --- a/api-reference-v1-stable/series/series.nunique.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Returns the number of unique values in a series ---- - -# Series.nunique - -> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters**: None - -**Returns: **int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -console.log(sf.nunique()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Ouptut" %} -``` -9 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.or.md b/api-reference-v1-stable/series/series.or.md deleted file mode 100644 index 948c61d..0000000 --- a/api-reference-v1-stable/series/series.or.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical OR between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.or - -> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical OR between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.or(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.pow.md b/api-reference-v1-stable/series/series.pow.md deleted file mode 100644 index 2fbe542..0000000 --- a/api-reference-v1-stable/series/series.pow.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# Series.pow - -> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Exponential power with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.pow(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 9 ║ -╟───┼──────────────────────╢ -║ 2 │ 64 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Exponential value with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.pow(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 16 ║ -╟───┼──────────────────────╢ -║ 4 │ 25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.replace.md b/api-reference-v1-stable/series/series.replace.md deleted file mode 100644 index 8a1f48b..0000000 --- a/api-reference-v1-stable/series/series.replace.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -description: Replace values given in replace param with value ---- - -# Series.replace - -> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Replace a value in a series and return a new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Replace a value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` diff --git a/api-reference-v1-stable/series/series.reset_index.md b/api-reference-v1-stable/series/series.reset_index.md deleted file mode 100644 index 7ff93af..0000000 --- a/api-reference-v1-stable/series/series.reset_index.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -description: Reset the index of a series. ---- - -# Series.reset_index - -> danfo.series.reset_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object | **inplace: **Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | - -**Returns : **Series - -`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. - -### **Reset index to default values** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [20, 30, 40] -let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) -sf.print() - -let sf_reset = sf.reset_index() -sf_reset.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ a │ 20 ║ -╟───┼────╢ -║ b │ 30 ║ -╟───┼────╢ -║ c │ 40 ║ -╚═══╧════╝ - -╔═══╤════╗ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 2 │ 40 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Reset index to new values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) -sf.print() - -sf.reset_index({ inplace: true }) -sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╟───┼───╢ -║ f │ 6 ║ -╚═══╧═══╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 4 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 6 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.round.md b/api-reference-v1-stable/series/series.round.md deleted file mode 100644 index 7b7ed7c..0000000 --- a/api-reference-v1-stable/series/series.round.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: round off floating values in series ---- - -# Series.round - -> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| dp | int | decimal place to round off to | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns: **Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -sf1.round(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.19 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.56 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.02 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.sample.md b/api-reference-v1-stable/series/series.sample.md deleted file mode 100644 index 762e635..0000000 --- a/api-reference-v1-stable/series/series.sample.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# Series.sample - -> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| num | Int | The number of rows to return. | | -| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| - -**Returns:** - -** **return** {Promies} resolves to Series** - -**Example** - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5) - sample.print() - -} -load_data() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤════╗ -║ 2 │ 3 ║ -╟───┼────╢ -║ 4 │ 5 ║ -╟───┼────╢ -║ 0 │ 1 ║ -╟───┼────╢ -║ 7 │ 40 ║ -╟───┼────╢ -║ 6 │ 30 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Specify a seed when sampling - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5, { seed: 2 }) - sample.print() - -} -load_data() - -``` diff --git a/api-reference-v1-stable/series/series.set_index.md b/api-reference-v1-stable/series/series.set_index.md deleted file mode 100644 index 0b9cad9..0000000 --- a/api-reference-v1-stable/series/series.set_index.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# Series.set_index - -> danfo.series.**set_index(**options**) **\[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] - -| Parameter | Type | Description | Default | -| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| index | Array | new index values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns: **Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let sf = new dfd.Series(data) -sf.print() - -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════════════════════════╗ -║ 0 │ {"alpha":"A","count":1} ║ -╟───┼─────────────────────────╢ -║ 1 │ {"alpha":"B","count":2} ║ -╟───┼─────────────────────────╢ -║ 2 │ {"alpha":"C","count":3} ║ -╚═══╧═════════════════════════╝ - -╔═══════╤═════════════════════════╗ -║ one │ {"alpha":"A","count":1} ║ -╟───────┼─────────────────────────╢ -║ two │ {"alpha":"B","count":2} ║ -╟───────┼─────────────────────────╢ -║ three │ {"alpha":"C","count":3} ║ -╚═══════╧═════════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ H │ Humans ║ -╟───┼──────────────────────╢ -║ L │ Life ║ -╟───┼──────────────────────╢ -║ M │ Meaning ║ -╟───┼──────────────────────╢ -║ F │ Fact ║ -╟───┼──────────────────────╢ -║ T │ Truth ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Set index in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data) -sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) -sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤═══╗ -║ one │ 1 ║ -╟───────┼───╢ -║ two │ 2 ║ -╟───────┼───╢ -║ three │ 3 ║ -╟───────┼───╢ -║ four │ 4 ║ -╟───────┼───╢ -║ five │ 5 ║ -╟───────┼───╢ -║ six │ 6 ║ -╚═══════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.shape.md b/api-reference-v1-stable/series/series.shape.md deleted file mode 100644 index 9eb5031..0000000 --- a/api-reference-v1-stable/series/series.shape.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the shape of a Series ---- - -# Series.shape - -> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] - -**Parameters**: None - -**Returns**: Array \[int, int\] - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.shape) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 4, 1 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.size.md b/api-reference-v1-stable/series/series.size.md deleted file mode 100644 index 9665b65..0000000 --- a/api-reference-v1-stable/series/series.size.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Obtain the size of a series ---- - -# Series.size - -> danfo.Series.size \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] - -**Parameters**: None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.size) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -4 -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.sort_values.md b/api-reference-v1-stable/series/series.sort_values.md deleted file mode 100644 index 5c7e5fa..0000000 --- a/api-reference-v1-stable/series/series.sort_values.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Sorts a Series in ascending or descending order ---- - -# Series.sort_values - -> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| - - **Return:** Series - -### Sort values in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.sort_values() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Sort Series in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ inplace: true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ - -``` -{% endtab %} -{% endtabs %} - -Sort Series values in descending order - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ "ascending": false, "inplace": true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 6 │ 89 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 7 │ 0 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.std.md b/api-reference-v1-stable/series/series.std.md deleted file mode 100644 index 8d83e32..0000000 --- a/api-reference-v1-stable/series/series.std.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -description: Obtain the standard deviation for a series ---- - -# Series.std - -> danfo.Series.std\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)\] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.std()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -31.11671576500322 -``` -{% endtab %} -{% endtabs %} - - **** - - - diff --git a/api-reference-v1-stable/series/series.str.capitalize.md b/api-reference-v1-stable/series/series.str.capitalize.md deleted file mode 100644 index aea9e91..0000000 --- a/api-reference-v1-stable/series/series.str.capitalize.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Capitalize the first character of each string ---- - -# Series.str.capitalize - -> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert the first character of a string to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'capitals', 'sentence', 'swApCaSe'] -let sf = new dfd.Series(data) -sf.str.capitalize().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ Capitals ║ -╟───┼──────────────────────╢ -║ 2 │ Sentence ║ -╟───┼──────────────────────╢ -║ 3 │ Swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.charat.md b/api-reference-v1-stable/series/series.str.charat.md deleted file mode 100644 index 931bb48..0000000 --- a/api-reference-v1-stable/series/series.str.charat.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Obtain the character at the specified index (position) ---- - -# Series.str.charAt - -> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| index | int | the index at which to obtain the character | 0 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Character element) - -**Example** - -Obtain the character at index 2 of all string elements in the series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.charAt(2).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ w ║ -╟───┼──────────────────────╢ -║ 1 │ P ║ -╟───┼──────────────────────╢ -║ 2 │ n ║ -╟───┼──────────────────────╢ -║ 3 │ A ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.concat.md b/api-reference-v1-stable/series/series.str.concat.md deleted file mode 100644 index 2fa49d4..0000000 --- a/api-reference-v1-stable/series/series.str.concat.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -description: Joins two or more strings/arrays ---- - -# Series.str.concat - -> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other **(string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns: **Series (String element) - -**Examples** - -Add the strings from an Array to the start of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ XXlower boy ║ -╟───┼──────────────────────╢ -║ 1 │ YYCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ BBsentence ║ -╟───┼──────────────────────╢ -║ 3 │ 01SwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add the strings from an Array to the end of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boyXX ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSYY ║ -╟───┼──────────────────────╢ -║ 2 │ sentenceBB ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSe01 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the start of each string element in a Series - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("pre",0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ prelower boy ║ -╟───┼──────────────────────╢ -║ 1 │ preCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ presentence ║ -╟───┼──────────────────────╢ -║ 3 │ preSwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the end of each string element in a series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("post",1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boypost ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSpost ║ -╟───┼──────────────────────╢ -║ 2 │ sentencepost ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSepost ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference-v1-stable/series/series.str.endswith.md b/api-reference-v1-stable/series/series.str.endswith.md deleted file mode 100644 index 2fb44cc..0000000 --- a/api-reference-v1-stable/series/series.str.endswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string ends with specified characters ---- - -# Series.str.endsWith - -> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.endsWith("e").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.includes.md b/api-reference-v1-stable/series/series.str.includes.md deleted file mode 100644 index 8918773..0000000 --- a/api-reference-v1-stable/series/series.str.includes.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string contains the specified string/characters ---- - -# Series.str.includes - -> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.includes("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.indexof.md b/api-reference-v1-stable/series/series.str.indexof.md deleted file mode 100644 index 8328d8b..0000000 --- a/api-reference-v1-stable/series/series.str.indexof.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: the position of the first found occurrence of a specified value in a string ---- - -# Series.str.indexOf - -> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to obtain its index | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns: **Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.indexOf("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.join.md b/api-reference-v1-stable/series/series.str.join.md deleted file mode 100644 index 386da02..0000000 --- a/api-reference-v1-stable/series/series.str.join.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Join a new string value to all string elements in a Series. ---- - -# Series.str.join - -> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - -** **return **Series** - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part', 'CAPITALS city', 'this is a sentence', 'SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.join("new", "_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════════════════════════╗ -║ 0 │ lower part_new ║ -╟───┼────────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼────────────────────────╢ -║ 2 │ this is a sentence_new ║ -╟───┼────────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧════════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.lastindexof.md b/api-reference-v1-stable/series/series.str.lastindexof.md deleted file mode 100644 index 889a1f4..0000000 --- a/api-reference-v1-stable/series/series.str.lastindexof.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Obtain the position of the last found occurrence of a specified value in a - string ---- - -# Series.str.lastIndexOf - -danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.lastIndexOf("r").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.str.len.md b/api-reference-v1-stable/series/series.str.len.md deleted file mode 100644 index 0ef06b2..0000000 --- a/api-reference-v1-stable/series/series.str.len.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the length of each string element in a Series ---- - -# Series.str.len - -> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Examples** - -Returns the length (number of character) of a string, and also return the length (number of elements) of Array - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["dog", 5,"cat","fog","mug","animals"] -let sf = new dfd.Series(data) -sf.str.len().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.repeat.md b/api-reference-v1-stable/series/series.str.repeat.md deleted file mode 100644 index 76f9073..0000000 --- a/api-reference-v1-stable/series/series.str.repeat.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Repeat the the character(s) in a string for a specified number of time ---- - -# Series.str.repeat - -> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] - -| Parameters | Type | Description | Default | -| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | -| num | integer | the string to search for | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns: **Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['a', 'b', 'c', 'd'] -let sf = new dfd.Series(data) -sf.str.repeat(4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ aaaa ║ -╟───┼──────────────────────╢ -║ 1 │ bbbb ║ -╟───┼──────────────────────╢ -║ 2 │ cccc ║ -╟───┼──────────────────────╢ -║ 3 │ dddd ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.replace.md b/api-reference-v1-stable/series/series.str.replace.md deleted file mode 100644 index da02575..0000000 --- a/api-reference-v1-stable/series/series.str.replace.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Replace a word or character(s) in a String element ---- - -# Series.str.replace - -> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] - -| Parameters | Type | Description | Default | -| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| searchValue | string | String \| Character value to replace. Supports regex. | "" | -| replaceValue | String | string to replace the searched string | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns: **Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.replace("A", "XXX").print() -``` -{% endtab %} - -{% tab title="Browse" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower ║ -╟───┼──────────────────────╢ -║ 1 │ CXXXPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwXXXpCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.search.md b/api-reference-v1-stable/series/series.str.search.md deleted file mode 100644 index 9dc48e0..0000000 --- a/api-reference-v1-stable/series/series.str.search.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Obtain the index position of a searched character in a String ---- - -# Series.str.search - -> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] - - - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | String | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - -** **return Series: Series of index position - -**Example** - -obtain the index position for a character - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 8 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Obtain the index position for a searched word - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower city ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("city").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.slice.md b/api-reference-v1-stable/series/series.str.slice.md deleted file mode 100644 index a807a36..0000000 --- a/api-reference-v1-stable/series/series.str.slice.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.slice - -> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - -** **return Series. - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.slice(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.split.md b/api-reference-v1-stable/series/series.str.split.md deleted file mode 100644 index 8ba84b6..0000000 --- a/api-reference-v1-stable/series/series.str.split.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: >- - Split string around a given separator/delimiter. The array of strings are then - converted to a string. ---- - -# Series.str.split - -> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | -| splitVal | String | separator or delimiter used to split the string | " " | -| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| - -**Returns** - - return **Series** - -**Examples** - -Split the string value in the Series by space and obtain the Series values - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king of the music","the lamba queen","I love the hat"] -let sf = new dfd.Series(data) -console.log(sf.str.split().values) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -**OUTPUT: **`[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king_of_the_music","the_lamba_queen","I_love_the_hat"] -let sf = new dfd.Series(data) -sf.str.split("_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ king,of,the,music ║ -╟───┼──────────────────────╢ -║ 1 │ the,lamba,queen ║ -╟───┼──────────────────────╢ -║ 2 │ I,love,the,hat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.startswith.md b/api-reference-v1-stable/series/series.str.startswith.md deleted file mode 100644 index 6290122..0000000 --- a/api-reference-v1-stable/series/series.str.startswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Test whether a string begins with specified characters ---- - -# Series.str.startsWith - -> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns: **Series (Boolean element) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.startsWith("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substr.md b/api-reference-v1-stable/series/series.str.substr.md deleted file mode 100644 index bb58cfd..0000000 --- a/api-reference-v1-stable/series/series.str.substr.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: >- - Obtain the substring from a String element in a Series, by specifying the - number of string to obtain starting from a specific index. ---- - -# Series.str.substr - -> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - -** **return Series - -**Example** - -Obtain substring( containing 4 characters) starting from the third character (2nd index). - -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substr(2, 4).print() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ wer ║ -╟───┼──────────────────────╢ -║ 1 │ APIT ║ -╟───┼──────────────────────╢ -║ 2 │ his ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substring.md b/api-reference-v1-stable/series/series.str.substring.md deleted file mode 100644 index 39bd460..0000000 --- a/api-reference-v1-stable/series/series.str.substring.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.substring - -> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns** - -** **return **Series** - -**Example** - -Obtain the substring from index 2 to index 4 of the string elements in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substring(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.tolowercase.md b/api-reference-v1-stable/series/series.str.tolowercase.md deleted file mode 100644 index 9abe0f5..0000000 --- a/api-reference-v1-stable/series/series.str.tolowercase.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Converts all characters to lower case. ---- - -# Series.str.toLowerCase - -> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -Convert all characters in each string element to small letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['LOWER BOY', 'CAPITALS', 'SENTENCE', 'SWAPCASE'] -let sf = new dfd.Series(data) -sf.str.toLowerCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ capitals ║ -╟───┼──────────────────────╢ -║ 2 │ sentence ║ -╟───┼──────────────────────╢ -║ 3 │ swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.touppercase.md b/api-reference-v1-stable/series/series.str.touppercase.md deleted file mode 100644 index f484390..0000000 --- a/api-reference-v1-stable/series/series.str.touppercase.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Converts all characters to uppercase. ---- - -# Series.str.toUpperCase - -> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert all characters in each string element to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.toUpperCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ LOWER BOY ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ SENTENCE ║ -╟───┼──────────────────────╢ -║ 3 │ SWAPCASE ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.trim.md b/api-reference-v1-stable/series/series.str.trim.md deleted file mode 100644 index c5df92a..0000000 --- a/api-reference-v1-stable/series/series.str.trim.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Remove leading and trailing Whitespace from a String element ---- - -# Series.str.trim - -> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - -** **return Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.trim().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.sub.md b/api-reference-v1-stable/series/series.sub.md deleted file mode 100644 index e281d06..0000000 --- a/api-reference-v1-stable/series/series.sub.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Subtraction of series and other, element-wise (binary operator sub). ---- - -# Series.sub - -> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.sub(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 29 ║ -╟───┼──────────────────────╢ -║ 1 │ 38 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.sub(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.sum.md b/api-reference-v1-stable/series/series.sum.md deleted file mode 100644 index fabcba7..0000000 --- a/api-reference-v1-stable/series/series.sum.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# Series.sum - -> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.sum()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -207 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.tail.md b/api-reference-v1-stable/series/series.tail.md deleted file mode 100644 index 7f986a1..0000000 --- a/api-reference-v1-stable/series/series.tail.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# Series.tail - -> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of last n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.tail().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 6 │ 30 ║ -╟────┼──────────────────────╢ -║ 7 │ 40 ║ -╟────┼──────────────────────╢ -║ 8 │ 39 ║ -╟────┼──────────────────────╢ -║ 9 │ 89 ║ -╟────┼──────────────────────╢ -║ 10 │ 78 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.tensor.md b/api-reference-v1-stable/series/series.tensor.md deleted file mode 100644 index a5c112c..0000000 --- a/api-reference-v1-stable/series/series.tensor.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: Obtain the tensor representation of the values in a Series ---- - -# Series.tensor - -> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] - -**Parameters**: None - -**Returns**: Tensorflow tensor - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.tensor) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 4 ], - dtype: 'float32', - size: 4, - strides: [], - dataId: {}, - id: 2, - rankType: '1', - scopeId: 0 -} -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.unique.md b/api-reference-v1-stable/series/series.unique.md deleted file mode 100644 index c89d187..0000000 --- a/api-reference-v1-stable/series/series.unique.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the unique value in a Series ---- - -# Series.unique - -> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] - -**Parameters**: None - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.unique().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╟───┼──────────────────────╢ -║ 6 │ 7 ║ -╟───┼──────────────────────╢ -║ 7 │ 8 ║ -╟───┼──────────────────────╢ -║ 8 │ 22 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.value_counts.md b/api-reference-v1-stable/series/series.value_counts.md deleted file mode 100644 index e8d0ad7..0000000 --- a/api-reference-v1-stable/series/series.value_counts.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Count the number of occurrence for each element in a Series ---- - -# Series.value_counts - -> danfo.Series.value_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters: **None - -**Returns: **Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.value_counts().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 1 │ 3 ║ -╟────┼──────────────────────╢ -║ 2 │ 1 ║ -╟────┼──────────────────────╢ -║ 3 │ 1 ║ -╟────┼──────────────────────╢ -║ 4 │ 1 ║ -╟────┼──────────────────────╢ -║ 5 │ 4 ║ -╟────┼──────────────────────╢ -║ 6 │ 1 ║ -╟────┼──────────────────────╢ -║ 7 │ 1 ║ -╟────┼──────────────────────╢ -║ 8 │ 2 ║ -╟────┼──────────────────────╢ -║ 22 │ 1 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.values.md b/api-reference-v1-stable/series/series.values.md deleted file mode 100644 index 4857487..0000000 --- a/api-reference-v1-stable/series/series.values.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the values in a series ---- - -# Series.values - -> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] - -**Parameters:** None - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.values) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 30.21091, 40.190901, 3.564, 5.0212 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.var.md b/api-reference-v1-stable/series/series.var.md deleted file mode 100644 index 4fdcbc2..0000000 --- a/api-reference-v1-stable/series/series.var.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Calculate the variance of a Series ---- - -# Series.var - -> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.var()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -968.25 -``` -{% endtab %} -{% endtabs %} - From 346e5fd733d7cf96a929741e41b0c29808c0fd80 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 2 Jan 2022 21:14:53 +0100 Subject: [PATCH 157/202] duplicate api reference --- api-reference copy/README.md | 54 +++ api-reference copy/configuration-options.md | 128 +++++ api-reference copy/dataframe/README.md | 145 ++++++ .../dataframe/creating-a-dataframe.md | 355 ++++++++++++++ .../dataframe/danfo.dataframe.abs.md | 74 +++ .../dataframe/danfo.dataframe.add.md | 246 ++++++++++ .../dataframe/danfo.dataframe.addcolumn.md | 118 +++++ .../dataframe/danfo.dataframe.apply.md | 106 ++++ .../dataframe/danfo.dataframe.column.md | 72 +++ .../dataframe/danfo.dataframe.copy.md | 53 ++ .../dataframe/danfo.dataframe.count.md | 100 ++++ .../dataframe/danfo.dataframe.cummax.md | 99 ++++ .../dataframe/danfo.dataframe.cummin.md | 99 ++++ .../dataframe/danfo.dataframe.cumprod.md | 99 ++++ .../dataframe/danfo.dataframe.cumsum.md | 99 ++++ .../dataframe/danfo.dataframe.describe.md | 61 +++ .../dataframe/danfo.dataframe.div.md | 254 ++++++++++ .../dataframe/danfo.dataframe.dropna.md | 96 ++++ .../dataframe/danfo.dataframe.eq.md | 190 ++++++++ .../dataframe/danfo.dataframe.fillna.md | 178 +++++++ .../dataframe/danfo.dataframe.ge.md | 195 ++++++++ .../dataframe/danfo.dataframe.groupby.md | 148 ++++++ .../dataframe/danfo.dataframe.gt.md | 191 ++++++++ .../dataframe/danfo.dataframe.head.md | 53 ++ .../dataframe/danfo.dataframe.iloc.md | 331 +++++++++++++ .../dataframe/danfo.dataframe.isna.md | 54 +++ .../dataframe/danfo.dataframe.it.md | 194 ++++++++ .../dataframe/danfo.dataframe.le.md | 194 ++++++++ .../dataframe/danfo.dataframe.loc.md | 367 ++++++++++++++ .../dataframe/danfo.dataframe.max.md | 118 +++++ .../dataframe/danfo.dataframe.mean.md | 120 +++++ .../dataframe/danfo.dataframe.median.md | 120 +++++ .../dataframe/danfo.dataframe.min.md | 120 +++++ .../dataframe/danfo.dataframe.mod.md | 258 ++++++++++ .../dataframe/danfo.dataframe.mul.md | 252 ++++++++++ .../dataframe/danfo.dataframe.ne.md | 187 ++++++++ .../dataframe/danfo.dataframe.pow.md | 260 ++++++++++ .../dataframe/danfo.dataframe.query.md | 278 +++++++++++ .../dataframe/danfo.dataframe.replace.md | 102 ++++ .../dataframe/danfo.dataframe.round.md | 128 +++++ .../dataframe/danfo.dataframe.sample.md | 112 +++++ .../dataframe/danfo.dataframe.std.md | 94 ++++ .../dataframe/danfo.dataframe.sub.md | 250 ++++++++++ .../dataframe/danfo.dataframe.sum.md | 121 +++++ .../dataframe/danfo.dataframe.tail.md | 53 ++ .../dataframe/danfo.dataframe.var.md | 94 ++++ .../dataframe/dataframe.append.md | 76 +++ .../dataframe/dataframe.apply_map.md | 68 +++ .../dataframe/dataframe.astype.md | 222 +++++++++ .../dataframe/dataframe.axes.md | 47 ++ .../dataframe/dataframe.drop.md | 143 ++++++ .../dataframe/dataframe.dtypes.md | 100 ++++ .../dataframe/dataframe.index.md | 69 +++ .../dataframe/dataframe.ndim.md | 46 ++ .../dataframe/dataframe.nunique-1.md | 98 ++++ .../dataframe/dataframe.print.md | 105 ++++ .../dataframe/dataframe.rename.md | 148 ++++++ .../dataframe/dataframe.reset_index.md | 73 +++ .../dataframe/dataframe.select_dtypes.md | 94 ++++ .../dataframe/dataframe.set_index.md | 176 +++++++ .../dataframe/dataframe.shape.md | 43 ++ .../dataframe/dataframe.sort_index.md | 74 +++ .../dataframe/dataframe.sort_values.md | 99 ++++ .../dataframe/dataframe.tensor.md | 110 +++++ .../dataframe/dataframe.to_csv.md | 114 +++++ .../dataframe/dataframe.to_excel.md | 53 ++ .../dataframe/dataframe.to_json.md | 127 +++++ .../dataframe/dataframe.values.md | 50 ++ .../general-functions/README.md | 27 ++ .../general-functions/danfo.concat.md | 187 ++++++++ .../general-functions/danfo.date_range.md | 111 +++++ .../general-functions/danfo.get_dummies.md | 188 ++++++++ .../general-functions/danfo.labelencoder.md | 140 ++++++ .../general-functions/danfo.merge.md | 453 ++++++++++++++++++ .../general-functions/danfo.minmaxscaler.md | 125 +++++ .../general-functions/danfo.onehotencoder.md | 148 ++++++ .../general-functions/danfo.standardscaler.md | 132 +++++ .../general-functions/danfo.to_datetime.md | 141 ++++++ api-reference copy/groupby.md | 122 +++++ api-reference copy/groupby/README.md | 34 ++ api-reference copy/groupby/groupby.agg.md | 93 ++++ api-reference copy/groupby/groupby.apply.md | 84 ++++ api-reference copy/groupby/groupby.col.md | 105 ++++ api-reference copy/groupby/groupby.count.md | 175 +++++++ api-reference copy/groupby/groupby.cummax.md | 258 ++++++++++ api-reference copy/groupby/groupby.cummin.md | 258 ++++++++++ api-reference copy/groupby/groupby.cumprod.md | 258 ++++++++++ api-reference copy/groupby/groupby.cumsum.md | 259 ++++++++++ .../groupby/groupby.get_groups.md | 129 +++++ api-reference copy/groupby/groupby.max.md | 170 +++++++ api-reference copy/groupby/groupby.mean.md | 173 +++++++ api-reference copy/groupby/groupby.min.md | 171 +++++++ api-reference copy/groupby/groupby.std.md | 175 +++++++ api-reference copy/groupby/groupby.sum.md | 172 +++++++ api-reference copy/groupby/groupby.var.md | 175 +++++++ api-reference copy/input-output/README.md | 18 + .../input-output/danfo.read_csv.md | 134 ++++++ .../input-output/danfo.read_excel.md | 68 +++ .../input-output/danfo.read_json.md | 127 +++++ .../input-output/danfo.to_csv.md | 115 +++++ .../input-output/danfo.to_excel.md | 54 +++ .../input-output/danfo.to_json.md | 124 +++++ api-reference copy/input-output/read.md | 138 ++++++ api-reference copy/plotting/README.md | 19 + api-reference copy/plotting/bar-charts.md | 75 +++ api-reference copy/plotting/box-plots.md | 116 +++++ .../plotting/configuring-your-plots.md | 68 +++ api-reference copy/plotting/histograms.md | 117 +++++ api-reference copy/plotting/line-charts.md | 109 +++++ api-reference copy/plotting/pie-charts.md | 123 +++++ api-reference copy/plotting/scatter-plots.md | 88 ++++ api-reference copy/plotting/tables.md | 95 ++++ .../plotting/timeseries-plots.md | 58 +++ api-reference copy/plotting/violin-plots.md | 112 +++++ api-reference copy/series/README.md | 182 +++++++ .../series/creating-a-series.md | 210 ++++++++ api-reference copy/series/danfo.series.add.md | 22 + .../series/danfo.series.apply.md | 63 +++ .../series/danfo.series.copy.md | 22 + .../series/danfo.series.count.md | 24 + .../series/danfo.series.describe.md | 26 + api-reference copy/series/danfo.series.div.md | 26 + .../series/danfo.series.head.md | 25 + api-reference copy/series/danfo.series.map.md | 42 ++ api-reference copy/series/danfo.series.max.md | 2 + .../series/danfo.series.maximum.md | 22 + .../series/danfo.series.mean.md | 2 + .../series/danfo.series.median.md | 2 + api-reference copy/series/danfo.series.min.md | 2 + .../series/danfo.series.minimum.md | 22 + api-reference copy/series/danfo.series.mod.md | 24 + .../series/danfo.series.mode.md | 2 + api-reference copy/series/danfo.series.mul.md | 26 + api-reference copy/series/danfo.series.pow.md | 26 + .../series/danfo.series.reset_index.md | 31 ++ .../series/danfo.series.round.md | 20 + .../series/danfo.series.sample.md | 22 + .../series/danfo.series.set_index.md | 40 ++ .../series/danfo.series.sort_values.md | 27 ++ api-reference copy/series/danfo.series.std.md | 20 + api-reference copy/series/danfo.series.sub.md | 24 + .../series/danfo.series.sum-1.md | 22 + .../series/danfo.series.tail.md | 22 + .../series/danfo.series.tostring.md | 18 + api-reference copy/series/danfo.series.var.md | 20 + api-reference copy/series/series.abs.md | 52 ++ api-reference copy/series/series.add.md | 86 ++++ api-reference copy/series/series.and.md | 132 +++++ api-reference copy/series/series.append.md | 135 ++++++ api-reference copy/series/series.apply.md | 149 ++++++ api-reference copy/series/series.argmax.md | 35 ++ api-reference copy/series/series.argmin.md | 35 ++ api-reference copy/series/series.argsort.md | 75 +++ api-reference copy/series/series.astype.md | 2 + api-reference copy/series/series.copy.md | 45 ++ api-reference copy/series/series.corr.md | 2 + api-reference copy/series/series.count.md | 36 ++ api-reference copy/series/series.cummax.md | 51 ++ api-reference copy/series/series.cummin.md | 51 ++ api-reference copy/series/series.cumprod.md | 51 ++ api-reference copy/series/series.cumsum.md | 74 +++ api-reference copy/series/series.describe.md | 57 +++ api-reference copy/series/series.div.md | 87 ++++ api-reference copy/series/series.dot.md | 2 + .../series/series.drop_duplicates.md | 121 +++++ api-reference copy/series/series.dropna.md | 91 ++++ api-reference copy/series/series.dt.day.md | 55 +++ api-reference copy/series/series.dt.hour.md | 52 ++ api-reference copy/series/series.dt.minute.md | 60 +++ api-reference copy/series/series.dt.month.md | 47 ++ .../series/series.dt.month_name.md | 55 +++ .../series/series.dt.monthday.md | 55 +++ api-reference copy/series/series.dt.second.md | 60 +++ .../series/series.dt.weekdays.md | 79 +++ api-reference copy/series/series.dt.year.md | 45 ++ api-reference copy/series/series.dtype.md | 34 ++ api-reference copy/series/series.eq.md | 95 ++++ api-reference copy/series/series.fillna.md | 106 ++++ api-reference copy/series/series.ge.md | 95 ++++ api-reference copy/series/series.gt.md | 95 ++++ api-reference copy/series/series.head.md | 51 ++ api-reference copy/series/series.iloc.md | 158 ++++++ api-reference copy/series/series.index.md | 33 ++ api-reference copy/series/series.isna.md | 45 ++ api-reference copy/series/series.le.md | 96 ++++ api-reference copy/series/series.loc.md | 198 ++++++++ api-reference copy/series/series.lt.md | 96 ++++ api-reference copy/series/series.map.md | 92 ++++ api-reference copy/series/series.max.md | 36 ++ api-reference copy/series/series.maximum.md | 50 ++ api-reference copy/series/series.mean.md | 36 ++ api-reference copy/series/series.median.md | 36 ++ api-reference copy/series/series.min.md | 36 ++ api-reference copy/series/series.minimum.md | 48 ++ api-reference copy/series/series.mod.md | 85 ++++ api-reference copy/series/series.mode.md | 36 ++ api-reference copy/series/series.mul.md | 86 ++++ api-reference copy/series/series.ndim.md | 34 ++ api-reference copy/series/series.ne.md | 95 ++++ api-reference copy/series/series.nunique.md | 34 ++ api-reference copy/series/series.or.md | 132 +++++ api-reference copy/series/series.pow.md | 87 ++++ api-reference copy/series/series.replace.md | 89 ++++ .../series/series.reset_index.md | 113 +++++ api-reference copy/series/series.round.md | 48 ++ api-reference copy/series/series.sample.md | 65 +++ api-reference copy/series/series.set_index.md | 136 ++++++ api-reference copy/series/series.shape.md | 35 ++ api-reference copy/series/series.size.md | 37 ++ .../series/series.sort_values.md | 140 ++++++ api-reference copy/series/series.std.md | 37 ++ .../series/series.str.capitalize.md | 52 ++ .../series/series.str.charat.md | 53 ++ .../series/series.str.concat.md | 165 +++++++ .../series/series.str.endswith.md | 51 ++ .../series/series.str.includes.md | 51 ++ .../series/series.str.indexof.md | 51 ++ api-reference copy/series/series.str.join.md | 52 ++ .../series/series.str.lastindexof.md | 54 +++ api-reference copy/series/series.str.len.md | 52 ++ .../series/series.str.repeat.md | 51 ++ .../series/series.str.replace.md | 50 ++ .../series/series.str.search.md | 94 ++++ api-reference copy/series/series.str.slice.md | 54 +++ api-reference copy/series/series.str.split.md | 74 +++ .../series/series.str.startswith.md | 51 ++ .../series/series.str.substr.md | 50 ++ .../series/series.str.substring.md | 56 +++ .../series/series.str.tolowercase.md | 50 ++ .../series/series.str.touppercase.md | 52 ++ api-reference copy/series/series.str.trim.md | 50 ++ api-reference copy/series/series.sub.md | 86 ++++ api-reference copy/series/series.sum.md | 36 ++ api-reference copy/series/series.tail.md | 49 ++ api-reference copy/series/series.tensor.md | 46 ++ api-reference copy/series/series.unique.md | 55 +++ .../series/series.value_counts.md | 54 +++ api-reference copy/series/series.values.md | 35 ++ api-reference copy/series/series.var.md | 35 ++ 239 files changed, 22625 insertions(+) create mode 100644 api-reference copy/README.md create mode 100644 api-reference copy/configuration-options.md create mode 100644 api-reference copy/dataframe/README.md create mode 100644 api-reference copy/dataframe/creating-a-dataframe.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.abs.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.add.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.addcolumn.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.apply.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.column.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.copy.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.count.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.cummax.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.cummin.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.cumprod.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.cumsum.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.describe.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.div.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.dropna.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.eq.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.fillna.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.ge.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.groupby.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.gt.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.head.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.iloc.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.isna.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.it.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.le.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.loc.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.max.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.mean.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.median.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.min.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.mod.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.mul.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.ne.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.pow.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.query.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.replace.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.round.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.sample.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.std.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.sub.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.sum.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.tail.md create mode 100644 api-reference copy/dataframe/danfo.dataframe.var.md create mode 100644 api-reference copy/dataframe/dataframe.append.md create mode 100644 api-reference copy/dataframe/dataframe.apply_map.md create mode 100644 api-reference copy/dataframe/dataframe.astype.md create mode 100644 api-reference copy/dataframe/dataframe.axes.md create mode 100644 api-reference copy/dataframe/dataframe.drop.md create mode 100644 api-reference copy/dataframe/dataframe.dtypes.md create mode 100644 api-reference copy/dataframe/dataframe.index.md create mode 100644 api-reference copy/dataframe/dataframe.ndim.md create mode 100644 api-reference copy/dataframe/dataframe.nunique-1.md create mode 100644 api-reference copy/dataframe/dataframe.print.md create mode 100644 api-reference copy/dataframe/dataframe.rename.md create mode 100644 api-reference copy/dataframe/dataframe.reset_index.md create mode 100644 api-reference copy/dataframe/dataframe.select_dtypes.md create mode 100644 api-reference copy/dataframe/dataframe.set_index.md create mode 100644 api-reference copy/dataframe/dataframe.shape.md create mode 100644 api-reference copy/dataframe/dataframe.sort_index.md create mode 100644 api-reference copy/dataframe/dataframe.sort_values.md create mode 100644 api-reference copy/dataframe/dataframe.tensor.md create mode 100644 api-reference copy/dataframe/dataframe.to_csv.md create mode 100644 api-reference copy/dataframe/dataframe.to_excel.md create mode 100644 api-reference copy/dataframe/dataframe.to_json.md create mode 100644 api-reference copy/dataframe/dataframe.values.md create mode 100644 api-reference copy/general-functions/README.md create mode 100644 api-reference copy/general-functions/danfo.concat.md create mode 100644 api-reference copy/general-functions/danfo.date_range.md create mode 100644 api-reference copy/general-functions/danfo.get_dummies.md create mode 100644 api-reference copy/general-functions/danfo.labelencoder.md create mode 100644 api-reference copy/general-functions/danfo.merge.md create mode 100644 api-reference copy/general-functions/danfo.minmaxscaler.md create mode 100644 api-reference copy/general-functions/danfo.onehotencoder.md create mode 100644 api-reference copy/general-functions/danfo.standardscaler.md create mode 100644 api-reference copy/general-functions/danfo.to_datetime.md create mode 100644 api-reference copy/groupby.md create mode 100644 api-reference copy/groupby/README.md create mode 100644 api-reference copy/groupby/groupby.agg.md create mode 100644 api-reference copy/groupby/groupby.apply.md create mode 100644 api-reference copy/groupby/groupby.col.md create mode 100644 api-reference copy/groupby/groupby.count.md create mode 100644 api-reference copy/groupby/groupby.cummax.md create mode 100644 api-reference copy/groupby/groupby.cummin.md create mode 100644 api-reference copy/groupby/groupby.cumprod.md create mode 100644 api-reference copy/groupby/groupby.cumsum.md create mode 100644 api-reference copy/groupby/groupby.get_groups.md create mode 100644 api-reference copy/groupby/groupby.max.md create mode 100644 api-reference copy/groupby/groupby.mean.md create mode 100644 api-reference copy/groupby/groupby.min.md create mode 100644 api-reference copy/groupby/groupby.std.md create mode 100644 api-reference copy/groupby/groupby.sum.md create mode 100644 api-reference copy/groupby/groupby.var.md create mode 100644 api-reference copy/input-output/README.md create mode 100644 api-reference copy/input-output/danfo.read_csv.md create mode 100644 api-reference copy/input-output/danfo.read_excel.md create mode 100644 api-reference copy/input-output/danfo.read_json.md create mode 100644 api-reference copy/input-output/danfo.to_csv.md create mode 100644 api-reference copy/input-output/danfo.to_excel.md create mode 100644 api-reference copy/input-output/danfo.to_json.md create mode 100644 api-reference copy/input-output/read.md create mode 100644 api-reference copy/plotting/README.md create mode 100644 api-reference copy/plotting/bar-charts.md create mode 100644 api-reference copy/plotting/box-plots.md create mode 100644 api-reference copy/plotting/configuring-your-plots.md create mode 100644 api-reference copy/plotting/histograms.md create mode 100644 api-reference copy/plotting/line-charts.md create mode 100644 api-reference copy/plotting/pie-charts.md create mode 100644 api-reference copy/plotting/scatter-plots.md create mode 100644 api-reference copy/plotting/tables.md create mode 100644 api-reference copy/plotting/timeseries-plots.md create mode 100644 api-reference copy/plotting/violin-plots.md create mode 100644 api-reference copy/series/README.md create mode 100644 api-reference copy/series/creating-a-series.md create mode 100644 api-reference copy/series/danfo.series.add.md create mode 100644 api-reference copy/series/danfo.series.apply.md create mode 100644 api-reference copy/series/danfo.series.copy.md create mode 100644 api-reference copy/series/danfo.series.count.md create mode 100644 api-reference copy/series/danfo.series.describe.md create mode 100644 api-reference copy/series/danfo.series.div.md create mode 100644 api-reference copy/series/danfo.series.head.md create mode 100644 api-reference copy/series/danfo.series.map.md create mode 100644 api-reference copy/series/danfo.series.max.md create mode 100644 api-reference copy/series/danfo.series.maximum.md create mode 100644 api-reference copy/series/danfo.series.mean.md create mode 100644 api-reference copy/series/danfo.series.median.md create mode 100644 api-reference copy/series/danfo.series.min.md create mode 100644 api-reference copy/series/danfo.series.minimum.md create mode 100644 api-reference copy/series/danfo.series.mod.md create mode 100644 api-reference copy/series/danfo.series.mode.md create mode 100644 api-reference copy/series/danfo.series.mul.md create mode 100644 api-reference copy/series/danfo.series.pow.md create mode 100644 api-reference copy/series/danfo.series.reset_index.md create mode 100644 api-reference copy/series/danfo.series.round.md create mode 100644 api-reference copy/series/danfo.series.sample.md create mode 100644 api-reference copy/series/danfo.series.set_index.md create mode 100644 api-reference copy/series/danfo.series.sort_values.md create mode 100644 api-reference copy/series/danfo.series.std.md create mode 100644 api-reference copy/series/danfo.series.sub.md create mode 100644 api-reference copy/series/danfo.series.sum-1.md create mode 100644 api-reference copy/series/danfo.series.tail.md create mode 100644 api-reference copy/series/danfo.series.tostring.md create mode 100644 api-reference copy/series/danfo.series.var.md create mode 100644 api-reference copy/series/series.abs.md create mode 100644 api-reference copy/series/series.add.md create mode 100644 api-reference copy/series/series.and.md create mode 100644 api-reference copy/series/series.append.md create mode 100644 api-reference copy/series/series.apply.md create mode 100644 api-reference copy/series/series.argmax.md create mode 100644 api-reference copy/series/series.argmin.md create mode 100644 api-reference copy/series/series.argsort.md create mode 100644 api-reference copy/series/series.astype.md create mode 100644 api-reference copy/series/series.copy.md create mode 100644 api-reference copy/series/series.corr.md create mode 100644 api-reference copy/series/series.count.md create mode 100644 api-reference copy/series/series.cummax.md create mode 100644 api-reference copy/series/series.cummin.md create mode 100644 api-reference copy/series/series.cumprod.md create mode 100644 api-reference copy/series/series.cumsum.md create mode 100644 api-reference copy/series/series.describe.md create mode 100644 api-reference copy/series/series.div.md create mode 100644 api-reference copy/series/series.dot.md create mode 100644 api-reference copy/series/series.drop_duplicates.md create mode 100644 api-reference copy/series/series.dropna.md create mode 100644 api-reference copy/series/series.dt.day.md create mode 100644 api-reference copy/series/series.dt.hour.md create mode 100644 api-reference copy/series/series.dt.minute.md create mode 100644 api-reference copy/series/series.dt.month.md create mode 100644 api-reference copy/series/series.dt.month_name.md create mode 100644 api-reference copy/series/series.dt.monthday.md create mode 100644 api-reference copy/series/series.dt.second.md create mode 100644 api-reference copy/series/series.dt.weekdays.md create mode 100644 api-reference copy/series/series.dt.year.md create mode 100644 api-reference copy/series/series.dtype.md create mode 100644 api-reference copy/series/series.eq.md create mode 100644 api-reference copy/series/series.fillna.md create mode 100644 api-reference copy/series/series.ge.md create mode 100644 api-reference copy/series/series.gt.md create mode 100644 api-reference copy/series/series.head.md create mode 100644 api-reference copy/series/series.iloc.md create mode 100644 api-reference copy/series/series.index.md create mode 100644 api-reference copy/series/series.isna.md create mode 100644 api-reference copy/series/series.le.md create mode 100644 api-reference copy/series/series.loc.md create mode 100644 api-reference copy/series/series.lt.md create mode 100644 api-reference copy/series/series.map.md create mode 100644 api-reference copy/series/series.max.md create mode 100644 api-reference copy/series/series.maximum.md create mode 100644 api-reference copy/series/series.mean.md create mode 100644 api-reference copy/series/series.median.md create mode 100644 api-reference copy/series/series.min.md create mode 100644 api-reference copy/series/series.minimum.md create mode 100644 api-reference copy/series/series.mod.md create mode 100644 api-reference copy/series/series.mode.md create mode 100644 api-reference copy/series/series.mul.md create mode 100644 api-reference copy/series/series.ndim.md create mode 100644 api-reference copy/series/series.ne.md create mode 100644 api-reference copy/series/series.nunique.md create mode 100644 api-reference copy/series/series.or.md create mode 100644 api-reference copy/series/series.pow.md create mode 100644 api-reference copy/series/series.replace.md create mode 100644 api-reference copy/series/series.reset_index.md create mode 100644 api-reference copy/series/series.round.md create mode 100644 api-reference copy/series/series.sample.md create mode 100644 api-reference copy/series/series.set_index.md create mode 100644 api-reference copy/series/series.shape.md create mode 100644 api-reference copy/series/series.size.md create mode 100644 api-reference copy/series/series.sort_values.md create mode 100644 api-reference copy/series/series.std.md create mode 100644 api-reference copy/series/series.str.capitalize.md create mode 100644 api-reference copy/series/series.str.charat.md create mode 100644 api-reference copy/series/series.str.concat.md create mode 100644 api-reference copy/series/series.str.endswith.md create mode 100644 api-reference copy/series/series.str.includes.md create mode 100644 api-reference copy/series/series.str.indexof.md create mode 100644 api-reference copy/series/series.str.join.md create mode 100644 api-reference copy/series/series.str.lastindexof.md create mode 100644 api-reference copy/series/series.str.len.md create mode 100644 api-reference copy/series/series.str.repeat.md create mode 100644 api-reference copy/series/series.str.replace.md create mode 100644 api-reference copy/series/series.str.search.md create mode 100644 api-reference copy/series/series.str.slice.md create mode 100644 api-reference copy/series/series.str.split.md create mode 100644 api-reference copy/series/series.str.startswith.md create mode 100644 api-reference copy/series/series.str.substr.md create mode 100644 api-reference copy/series/series.str.substring.md create mode 100644 api-reference copy/series/series.str.tolowercase.md create mode 100644 api-reference copy/series/series.str.touppercase.md create mode 100644 api-reference copy/series/series.str.trim.md create mode 100644 api-reference copy/series/series.sub.md create mode 100644 api-reference copy/series/series.sum.md create mode 100644 api-reference copy/series/series.tail.md create mode 100644 api-reference copy/series/series.tensor.md create mode 100644 api-reference copy/series/series.unique.md create mode 100644 api-reference copy/series/series.value_counts.md create mode 100644 api-reference copy/series/series.values.md create mode 100644 api-reference copy/series/series.var.md diff --git a/api-reference copy/README.md b/api-reference copy/README.md new file mode 100644 index 0000000..b5d5d28 --- /dev/null +++ b/api-reference copy/README.md @@ -0,0 +1,54 @@ +--- +description: >- + This page gives an overview of all public danfo objects, functions and + methods. All classes and functions exposed in danfo.* namespace are public. +--- + +# API reference + +* [General Functions](general-functions/) + * [Data manipulations](general-functions/#data-manipulations) + * [Data Processing/Normalization](general-functions/#data-processing-normalization) + * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) +* [Input/output](input-output/) + * [CSV](input-output/#csv) + * [JSON](input-output/#json) +* [Series](series/) + * [Attributes](series/#attributes) + * [Conversion](series/#conversion) + * [Indexing, iteration](series/#indexing-iteration) + * [Binary operator functions](series/#binary-operator-functions) + * [Function application, GroupBy & window](series/#function-application-and-groupby) + * [Computations / descriptive stats](series/#computations-descriptive-stats) + * [Reindexing / selection / label manipulation](series/#reindexing-selection-label-manipulation) + * [Missing data handling](series/#missing-data-handling) + * [Reshaping, sorting](series/#reshaping-sorting) + * [Accessors](series/#accessors) + * [Serialization / IO / conversion](series/#serialization-io-conversion) +* [DataFrame](dataframe/) + * [Attributes ](dataframe/#attributes) + * [Conversion](dataframe/#conversion) + * [Indexing, iteration](dataframe/#indexing-iteration) + * [Binary operator functions](dataframe/#binary-operator-functions) + * [Function application, GroupBy & window](dataframe/#function-application-and-groupby) + * [Computations / descriptive stats](dataframe/#computations-descriptive-stats) + * [Reindexing / selection / label manipulation](dataframe/#reindexing-selection-label-manipulation) + * [Missing data handling](dataframe/#missing-data-handling) + * [Reshaping, sorting, transposing](dataframe/#sorting-and-transposing) + * [Combining / comparing / joining / merging](dataframe/#combining-comparing-joining-merging) + * [Serialization / IO / conversion](dataframe/#serialization-io-conversion) +* [Plotting](plotting/) + * [Line Charts](plotting/line-charts.md) + * [Bar Charts](plotting/bar-charts.md) + * [Scatter Plots](plotting/scatter-plots.md) + * [Histograms](plotting/histograms.md) + * [Pie Charts](plotting/pie-charts.md) + * [Tables](plotting/tables.md) + * [Box Plots](plotting/box-plots.md) + * [Violin Plots](plotting/violin-plots.md) + * [Timeseries Plots](plotting/timeseries-plots.md) +* [GroupBy](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html) + * [Indexing, iteration](groupby/#indexing-iteration) + * [Function application](groupby/#function-application) + * [Computations / descriptive stats](groupby/#computations-descriptive-stats) + diff --git a/api-reference copy/configuration-options.md b/api-reference copy/configuration-options.md new file mode 100644 index 0000000..f4c2136 --- /dev/null +++ b/api-reference copy/configuration-options.md @@ -0,0 +1,128 @@ +--- +description: >- + This section describes all user configurable options available on + DataFrame/Series creation. +--- + +# Configuration Options + +On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. + +| Parameter | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | +| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | +| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | +| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| + +> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) + +## Examples of setting configs + +### Add a DataFrame header + +```javascript + const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] + }; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + }, + } +}); +df.print() +``` + +```javascript +╔════════════════════════════════════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟────────────┬───────────────────┬───────────────────┬───────────────────╢ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Configure column size and display format of DataFrame + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +}; +const df = new DataFrame(data, { + config: { + tableDisplayConfig: { + header: { + alignment: 'center', + content: 'THE HEADER\nThis is the table about something', + }, + columns: [ + { alignment: 'left' }, + { alignment: 'center', width: 20 }, + { alignment: 'right' }, + { alignment: 'justify' } + ], + }, + } +}); +df.print() +``` + +```javascript +╔══════════════════════════════════════════╗ +║ THE HEADER ║ +║ This is the table about something ║ +╟───┬──────────────────────┬───────┬───────╢ +║ │ Name │ Count │ Price ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼──────────────────────┼───────┼───────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧══════════════════════╧═══════╧═══════╝ +``` + +### Configure the number of rows displayed when **print** is called + +```javascript +const data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250], + +}; +const df = new DataFrame(data, { + config: { + tableMaxColInConsole: 6, + tableMaxRow: 1 + } +}); +df.print() +``` + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference copy/dataframe/README.md b/api-reference copy/dataframe/README.md new file mode 100644 index 0000000..d48a28d --- /dev/null +++ b/api-reference copy/dataframe/README.md @@ -0,0 +1,145 @@ +--- +description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. +--- + +# Dataframe + +> `DataFrame`(data, {\ +> **columns:** \[ Array ],\ +> **dtypes:** \[ Array ], **** \ +> **index:** \[Array], \ +> **options**: Object}) + +### Attributes + +| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | +| ------------------------------------------------ | ---------------------------------------- | +| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | + +| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | +| -------------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.select_dtypes`](dataframe.select\_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | +| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | +| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | +| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | +| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | +| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | + +### Conversion + +| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | +| ------------------------------------------- | -------------------------------------------------- | +| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | + +### Indexing, iteration + +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | +| --------------------------------------------- | ------------------------------------------------------------------ | +| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | +| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | + +### Binary operator functions + +| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | +| ----------------------------------------- | --------------------------------------------------------------------------------------- | +| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | +| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | +| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | +| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | +| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | +| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | +| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | +| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | +| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | +| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | +| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | + +### Function application & GroupBy + +| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | +| --------------------------------------------- | --------------------------------------------------------- | +| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | +| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | + +### Computations / descriptive stats + +| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | +| --------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | +| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | +| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | +| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | +| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | +| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | +| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | +| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | +| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | +| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | +| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | +| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | + +### Reindexing / selection / label manipulation + +| | | +| ---------------------------------------------------- | ------------------------------------------------------- | +| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | +| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | +| [`DataFrame.reset_index`](dataframe.reset\_index.md) | Reset the index of a DataFrame | +| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | +| [`DataFrame.set_index`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | + +### Missing data handling + +| | | +| ------------------------------------------------- | ------------------------------------------- | +| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | +| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | +| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | +| [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | + +### Sorting & transposing + +| | | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| [`DataFrame.sort_values`](dataframe.sort\_values.md) | Sort by the values along either axis. | +| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | + +### Combining / comparing / joining / merging + +| | | +| ---------------------------------------------------------- | ------------------------------------------------------------------- | +| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | +| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | +| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | + +### Plotting + +`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. + +| | | +| -------------------------------------------------------- | ------------------------------------------------------------- | +| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | +| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | +| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | + +### Serialization / IO / conversion + +| | | +| -------------------------------------------- | ---------------------------------------------------- | +| [`DataFrame.to_csv`](dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | +| [`DataFrame.to_json`](dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference copy/dataframe/creating-a-dataframe.md b/api-reference copy/dataframe/creating-a-dataframe.md new file mode 100644 index 0000000..0228131 --- /dev/null +++ b/api-reference copy/dataframe/creating-a-dataframe.md @@ -0,0 +1,355 @@ +--- +description: Creates a DataFrame object from flat structure +--- + +# Creating a DataFrame + +new danfo.**DataFrame**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

columns: Array of column names. If not specified, column names are + auto generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ +In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. + +### Creating a `DataFrame` from a JSON object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +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 }] + +df = new dfd.DataFrame(json_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Creating a `DataFrame` from an array of array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] +let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` from a 2D tensor + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const tf = require("@tensorflow/tfjs-node") + + +let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) +let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) +df.print() +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ int32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ +``` + +### Creating a `DataFrame` from an object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) + +console.log(dates); + +obj_data = {'A': dates, + 'B': ["bval1", "bval2", "bval3", "bval4"], + 'C': [10, 20, 30, 40], + 'D': [1.2, 3.45, 60.1, 45], + 'E': ["test", "train", "test", "train"] + } + +df = new dfd.DataFrame(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +//output in console +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D │ E ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying index, dtypes, columns + +You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. + +> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; +let index = ["a", "b"]; +let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] +let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] + +let df = new DataFrame(data1, { index, columns, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +### Creating a `DataFrame` and specifying memory mode + +To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: + +```javascript +import { DataFrame } from "danfojs" + +let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; + +let df = new DataFrame(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. +{% endhint %} + +For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) + diff --git a/api-reference copy/dataframe/danfo.dataframe.abs.md b/api-reference copy/dataframe/danfo.dataframe.abs.md new file mode 100644 index 0000000..8504222 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.abs.md @@ -0,0 +1,74 @@ +--- +description: Return a DataFrame with the absolute numeric value of each element. +--- + +# DataFrame.abs + +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | + +**Returns:** + + **** return **Series** + +## **Examples** + +The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let df_abs = df.abs() +df_abs.abs().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after applying abs function + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.add.md b/api-reference copy/dataframe/danfo.dataframe.add.md new file mode 100644 index 0000000..925a3cd --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.add.md @@ -0,0 +1,246 @@ +--- +description: Get Addition of DataFrame and other, element-wise (binary operator add). +--- + +# DataFrame.add + +danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Addition of **scalar to** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.add(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of **Series to** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.add(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 8 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 8 │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 9 │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of **** DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.add(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 2 │ 22 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 9 │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 25 │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Addition of **** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.add(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Addition works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.add(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 12 │ 25 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 47 │ 22 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 58 │ 12 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 26 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.addcolumn.md b/api-reference copy/dataframe/danfo.dataframe.addcolumn.md new file mode 100644 index 0000000..ef0ecc9 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.addcolumn.md @@ -0,0 +1,118 @@ +--- +description: Add new column to a DataFrame +--- + +# DataFrame.addColumn + +danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | + +**Returns:** + +## **Examples** + +## **Add Array as a new column to DataFrame** + +New columns get added at the end of the DataFrame, and this happens so returns nothing, + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) +df.print() + +let new_col = [1, 2, 3, 4] +df.addColumn({ "column": "D", "values": new_col, inplace: true }); + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Add Series as a new column to DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) +let s = new dfd.Series([1, 2, 3, 4]) +df.addColumn({ "column": "D", "values": s, inplace: true }); + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.apply.md b/api-reference copy/dataframe/danfo.dataframe.apply.md new file mode 100644 index 0000000..de42294 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.apply.md @@ -0,0 +1,106 @@ +--- +description: Apply a function to each element or along a specified axis of a DataFrame. +--- + +# DataFrame.apply + +danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Apply a function along default axis 1 (columns) + +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); +} + +let df_new = df.apply(sum_vals, { axis: 1 }) +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ A │ 64 ║ +╟───┼─────╢ +║ B │ 126 ║ +╟───┼─────╢ +║ C │ 127 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +### Apply a function along axis 0 (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +function sum_vals(col) { + return col.reduce((a, b) => a + b, 0); +} + +let df_new = df.apply(sum_vals, { axis: 0 }) +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 0 │ 6 ║ +╟───┼─────╢ +║ 1 │ 15 ║ +╟───┼─────╢ +║ 2 │ 90 ║ +╟───┼─────╢ +║ 3 │ 206 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.column.md b/api-reference copy/dataframe/danfo.dataframe.column.md new file mode 100644 index 0000000..7d963a2 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.column.md @@ -0,0 +1,72 @@ +--- +description: Return the elements of the specified column in the DataFrame +--- + +# DataFrame.column + +danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------- | ------- | +| column | String | The name of a column in the DataFrame | | + +**Returns:** + + **** return **Series** + +## **Examples** + +## **Select a single column from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = { "Name": ["Apples", "App", "Banana", undefined], + "Count": [NaN, 5, NaN, 10] , + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) + +df.column("Name").print() + +//Alternatively, you can retrieve columns by using the object property +df['Name'].print() //produces the same result as above + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + +╔═══╤═══════════╗ +║ 0 │ Apples ║ +╟───┼───────────╢ +║ 1 │ App ║ +╟───┼───────────╢ +║ 2 │ Banana ║ +╟───┼───────────╢ +║ 3 │ undefined ║ +╚═══╧═══════════╝ + +``` +{% endtab %} +{% endtabs %} + +To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) diff --git a/api-reference copy/dataframe/danfo.dataframe.copy.md b/api-reference copy/dataframe/danfo.dataframe.copy.md new file mode 100644 index 0000000..188179d --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.copy.md @@ -0,0 +1,53 @@ +--- +description: Makes a new copy of the DataFrame +--- + +# DataFrame.copy + +danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] + +**Returns:** + + **** return **new DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) +let new_df = df.copy() +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.count.md b/api-reference copy/dataframe/danfo.dataframe.count.md new file mode 100644 index 0000000..637cbf4 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.count.md @@ -0,0 +1,100 @@ +--- +description: >- + Count non-NaN cells for each column or row. The values NaN and undefined are + considered NaN +--- + +# DataFrame.count + +danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Count Non-NaN values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.count().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══════╤══════════════════════╗ +║ │ 0 ║ +╟───────┼──────────────────────╢ +║ Name │ 3 ║ +╟───────┼──────────────────────╢ +║ Count │ 2 ║ +╟───────┼──────────────────────╢ +║ Price │ 4 ║ +╚═══════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Count Non-NaN values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.count({axis: 0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 3 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## + diff --git a/api-reference copy/dataframe/danfo.dataframe.cummax.md b/api-reference copy/dataframe/danfo.dataframe.cummax.md new file mode 100644 index 0000000..fb69bb5 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.cummax.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative maximum over a DataFrame or Series axis. +--- + +# DataFrame.cummax + +danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +## Cumulative maximum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummax({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 11 │ 20 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 11 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 11 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative maximum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummax({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 15 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 89 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cummin.md b/api-reference copy/dataframe/danfo.dataframe.cummin.md new file mode 100644 index 0000000..be026a6 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.cummin.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative minimum over a DataFrame or Series axis. +--- + +# DataFrame.cummin + +danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +## Cumulative minimum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummin({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 15 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 15 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative minimum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cummin({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 11 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 2 │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cumprod.md b/api-reference copy/dataframe/danfo.dataframe.cumprod.md new file mode 100644 index 0000000..06ad53a --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.cumprod.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative product over a DataFrame or Series axis. +--- + +# DataFrame.cumprod + +danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +## Cumulative product of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumprod() + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 10 │ 18 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 300 │ 720 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 4 │ 26700 │ 56160 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative product of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumprod({axis: 1}) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 60 │ 2400 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 178 │ 13884 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cumsum.md b/api-reference copy/dataframe/danfo.dataframe.cumsum.md new file mode 100644 index 0000000..07be896 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.cumsum.md @@ -0,0 +1,99 @@ +--- +description: Return cumulative sum over a DataFrame or Series axis. +--- + +# DataFrame.cumsum + +danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +## Cumulative sum of elements along default axis (row) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumsum({ axis: 0 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 12 │ 35 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 14 │ 65 │ 49 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 16 │ 154 │ 127 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Cumulative sum of elements along column axis (1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let new_df = df.cumsum({ axis: 1 }) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 31 │ 34 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 16 │ 22 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 32 │ 72 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 91 │ 169 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.describe.md b/api-reference copy/dataframe/danfo.dataframe.describe.md new file mode 100644 index 0000000..0540873 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.describe.md @@ -0,0 +1,61 @@ +--- +description: >- + Generate descriptive statistics for each numeric column. Numeric columns are + of type Int and float. +--- + +# DataFrame.describe + +danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] +let col_names = ["col1", "col2", "col3", "col4"] +let df = new dfd.DataFrame(data, {columns: col_names}) + +df.describe().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ count │ 3 │ 3 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ min │ 0 │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ median │ 2 │ 4 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ max │ 360 │ 180 │ 360 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## diff --git a/api-reference copy/dataframe/danfo.dataframe.div.md b/api-reference copy/dataframe/danfo.dataframe.div.md new file mode 100644 index 0000000..c98c66e --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.div.md @@ -0,0 +1,254 @@ +--- +description: >- + Get Float division of DataFrame and other, element-wise (binary operator + truediv). +--- + +# DataFrame.div + +danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Division of **scalar with** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.div(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Division of **Series with** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.div(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0.25 │ 0.6000000238418… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0.4000000059604… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1.25 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0.25 │ 0.8000000119209… ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Division of **** DataFrame **with** a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.div(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0.1000000014901… ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0.8000000119209… │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0.25 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Division of **** Array **with** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.div(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Division works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.div(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 5 │ 11.5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 22.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 28 │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 5 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.dropna.md b/api-reference copy/dataframe/danfo.dataframe.dropna.md new file mode 100644 index 0000000..429bcbe --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.dropna.md @@ -0,0 +1,96 @@ +--- +description: Remove missing values (NaNs, undefined, null) for DataFrame +--- + +# DataFrame.dropna + +danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | +| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace:** false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Drop rows (axis=0) with missing values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.print() + +let df_drop = df.dropna(0) +df_drop.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop columns (axis=1) with missing values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.print() + +df.dropna({axis: 1, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╗ +║ │ C ║ +╟───┼───────────────────╢ +║ 0 │ 3 ║ +╟───┼───────────────────╢ +║ 1 │ 6 ║ +╟───┼───────────────────╢ +║ 2 │ 40 ║ +╟───┼───────────────────╢ +║ 3 │ 78 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.eq.md b/api-reference copy/dataframe/danfo.dataframe.eq.md new file mode 100644 index 0000000..5f3cf2a --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.eq.md @@ -0,0 +1,190 @@ +--- +description: Get Equal to of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.eq + +danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +**** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.eq(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.eq(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.eq(df2) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.eq(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.fillna.md b/api-reference copy/dataframe/danfo.dataframe.fillna.md new file mode 100644 index 0000000..2ddb860 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.fillna.md @@ -0,0 +1,178 @@ +--- +description: >- + Fill NaN/undefined values using the specified method. Detect missing values + for an array-like object. +--- + +# DataFrame.fillna + +danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] + +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| values | Array \| Scalar | The list of value(s) to use for replacement. | | +| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Fill missing values in specified columns with specified values + +Missing values are NaN, undefined or null values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +df.print() + +let values = ["Apples", df["Count"].mean()] +let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) +df_filled.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Before filling +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ NaN │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ NaN │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ NaN │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After filling + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 7.5 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 7.5 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ +``` +{% endtab %} +{% endtabs %} + +### Fill all columns with NaNs with a specified value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +let df_filled = df.fillna("Apples") + +df_filled.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ Apples │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Fill NaNs inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = { + "Name": ["Apples", "Mango", "Banana", undefined], + "Count": [NaN, 5, NaN, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data) +let values = ["Apples", df["Count"].mean()] +df.fillna(values, { + columns: ["Name", "Count"], + inplace: true +}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ Apples │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ Apples │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.ge.md b/api-reference copy/dataframe/danfo.dataframe.ge.md new file mode 100644 index 0000000..8e5401b --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.ge.md @@ -0,0 +1,195 @@ +--- +description: >- + Get Greater or Equal to of DataFrame and other, element-wise (binary operator + eq). +--- + +# DataFrame.ge + +danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + + **DataFrame** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) + +let df_rep = df.ge(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.ge(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.ge(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.ge(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.groupby.md b/api-reference copy/dataframe/danfo.dataframe.groupby.md new file mode 100644 index 0000000..e7d084f --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.groupby.md @@ -0,0 +1,148 @@ +--- +description: Group DataFrame using a mapper or by a Series of columns. +--- + +# DataFrame.groupby + +danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] + +| Parameters | Type | Description | Default | +| ---------- | ----- | ----------------------------------------------------- | ------- | +| columns | Array | The names of a column(s) in the DataFrame to group by | | + +**Returns:** + + **** return **DataFrame.groups** + +## **Examples** + +## **Groupby a single column from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]) +console.log(group_df) + +//GroupBy Object +GroupBy { + key_col: [ 'A' ], + col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, + data: [ + [ 'Pear', 2, 3 ], + [ 'Pear', 5, 6 ], + [ 'Apple', 30, 40 ], + [ 'Apple', 89, 78 ] + ], + column_name: [ 'A', 'B', 'C' ], + data_tensors: { + Pear: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + '$index': [Array], + '$dtypes': [Array], + '$columns': [Array] + }, + Apple: DataFrame { + '$isSeries': false, + '$config': [Configs], + '$data': [Array], + '$dataIncolumnFormat': [Array], + ... + '$columns': [Array] + } + }, + col_dtype: [ 'string' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: + +1. [count](danfo.dataframe.count.md) +2. [sum](danfo.dataframe.sum.md) +3. [std](danfo.dataframe.std.md) +4. [var](danfo.dataframe.var.md) +5. [mean](danfo.dataframe.mean.md) +6. [cumsum](danfo.dataframe.cumsum.md) +7. [cummax](danfo.dataframe.cummax.md) +8. [cumprod](danfo.dataframe.cumprod.md) +9. [cummin](danfo.dataframe.cummin.md) +10. [max](danfo.dataframe.max.md) +11. [min](danfo.dataframe.min.md) + +## Example of Groupby and apply a sum function + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A"]).sum() + +group_df.print() + +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B_sum │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 119 │ 118 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +## **Groupby a two columns from a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +let group_df = df.groupby(["A", "B"]).sum() + +group_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Pear │ 2 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Apple │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Apple │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference copy/dataframe/danfo.dataframe.gt.md b/api-reference copy/dataframe/danfo.dataframe.gt.md new file mode 100644 index 0000000..ec3f7ba --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.gt.md @@ -0,0 +1,191 @@ +--- +description: Get Greater than of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.gt + +danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.gt(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.gt(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.gt(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.gt(val, axis=1) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.head.md b/api-reference copy/dataframe/danfo.dataframe.head.md new file mode 100644 index 0000000..3fe62c4 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.head.md @@ -0,0 +1,53 @@ +--- +description: Returns the first n rows of the DataFrame based on position. +--- + +# DataFrame.head + +danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let s_df = df.head(2) +s_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.iloc.md b/api-reference copy/dataframe/danfo.dataframe.iloc.md new file mode 100644 index 0000000..ffd7e25 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.iloc.md @@ -0,0 +1,331 @@ +--- +description: Purely integer-location based indexing for selection by position. +--- + +# DataFrame.iloc + +danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). + +Allowed inputs are: + +* An integer, e.g. `5`. +* A list or array of integers, e.g. `[4, 3, 0]`. +* A string slice object with ints, e.g. `"1:7"` +* A boolean array. + +_**Note:** only the start index is included._ + +`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. + +### **Indexing specific rows by index and return all columns** + +If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: [0,1,3]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row and return all columns** + +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: ["1:3"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of column and return all rows** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({columns: ["1:"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Indexing both axes by the specified index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let sub_df = df.iloc({rows: [0,3], columns: [1,2]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after indexing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Indexing both axes by slices + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +╔═══╤═══════════════════╗ +║ │ Count ║ +╟───┼───────────────────╢ +║ 2 │ 30 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### More default slicing behavior + +If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +df.print() + +let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) +sub_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.isna.md b/api-reference copy/dataframe/danfo.dataframe.isna.md new file mode 100644 index 0000000..830bda5 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.isna.md @@ -0,0 +1,54 @@ +--- +description: >- + Return a boolean same-sized object indicating if the values are NaN. + NaN/undefined values gets mapped to true values, and everything else gets + mapped to false values. +--- + +# DataFrame.isna + +danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.isna().print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ false │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ true │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ true │ false │ false ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ false │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.it.md b/api-reference copy/dataframe/danfo.dataframe.it.md new file mode 100644 index 0000000..3759197 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.it.md @@ -0,0 +1,194 @@ +--- +description: Get Less than of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.It + +danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.lt(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10, 40]) + +let df_rep = df.lt(sf, { axis: 1 }) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.lt(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with an Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.lt(val, axis=1) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.le.md b/api-reference copy/dataframe/danfo.dataframe.le.md new file mode 100644 index 0000000..31ce3f7 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.le.md @@ -0,0 +1,194 @@ +--- +description: >- + Get Less than or Equal to of DataFrame and other, element-wise (binary + operator eq). +--- + +# DataFrame.le + +danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) + +let df_rep = df.le(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.le(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.le(df2) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with an Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10,40] + +let df_rep = df.le(val, {axis:1}) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.loc.md b/api-reference copy/dataframe/danfo.dataframe.loc.md new file mode 100644 index 0000000..abdcdd9 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.loc.md @@ -0,0 +1,367 @@ +--- +description: Access a group of rows and columns by label(s) +--- + +# DataFrame.loc + +danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | +| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +`.loc()` is label position based-from `0` to `length-1` of the row axis. + +Allowed inputs for are: + +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` + +_**Note:** only **** the start label is included, and the end label is ignored._ + +`.loc` will raise a `ValueEror` if a requested label is not found. + +### **Index by specific rows and return all columns** + +If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.print() +let sub_df = df.loc({rows: ["a", "c"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a list of column names and return all rows** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.print() +let sub_df = df.loc({columns: ["Count", "Price"]}) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after indexing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Count │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ a │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────╢ +║ b │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────╢ +║ c │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ d │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Index both axes by the specified labels + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +df.print() +let sub_df = df.loc({ rows: ["c","d"], columns: ["Name", "Price"] }) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//after slicing + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ c │ Banana │ 40 ║ +╟───┼───────────────────┼───────────────────╢ +║ d │ Pear │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +df.print() +let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) +sub_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Price ║ +╟────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 200 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 300 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +df`.loc({ row: [a:e]}).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +df``.loc({ row: [`"a":"e"`]}).print()``\ +\ +_**Inner**_ _**quotes are not needed for numeric indices!**_ +{% endhint %} + +### Slice DataFrame rows by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let sub_df = df.loc({ rows: df["Count"].gt(6) }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + +### Slice DataFrame rows by multiple boolean conditions + +{% hint style="info" %} +_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame._ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) +let condition = df["Count"].gt(6).and(df["Price"].lt(250)) +let sub_df = df.loc({ rows: condition }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ Apples │ 21 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +### Slice DataFrame with boolean mask + +{% hint style="info" %} +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) + +let sub_df = df.loc({ rows: [false, true, true, true] }) +sub_df.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ Pear │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` diff --git a/api-reference copy/dataframe/danfo.dataframe.max.md b/api-reference copy/dataframe/danfo.dataframe.max.md new file mode 100644 index 0000000..a5c2119 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.max.md @@ -0,0 +1,118 @@ +--- +description: Return the maximum of the values for the requested axis. +--- + +# DataFrame.max + +danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Return the maximum value along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.max().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 11 ║ +╟───┼──────────────────────╢ +║ B │ 89 ║ +╟───┼──────────────────────╢ +║ C │ 78 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Return the maximum value along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.max({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 20 ║ +╟───┼──────────────────────╢ +║ 1 │ 15 ║ +╟───┼──────────────────────╢ +║ 2 │ 40 ║ +╟───┼──────────────────────╢ +║ 3 │ 89 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.mean.md b/api-reference copy/dataframe/danfo.dataframe.mean.md new file mode 100644 index 0000000..172cff5 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.mean.md @@ -0,0 +1,120 @@ +--- +description: Return the mean of the values for the requested axis. +--- + +# DataFrame.mean + +danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Computes the mean of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.mean().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 4 ║ +╟───┼──────────────────────╢ +║ B │ 38.5 ║ +╟───┼──────────────────────╢ +║ C │ 31.75 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Computes the mean of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.mean({ axis: 0 }).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 11.333333015441895 ║ +╟───┼──────────────────────╢ +║ 1 │ 7.333333492279053 ║ +╟───┼──────────────────────╢ +║ 2 │ 24 ║ +╟───┼──────────────────────╢ +║ 3 │ 56.33333206176758 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.median.md b/api-reference copy/dataframe/danfo.dataframe.median.md new file mode 100644 index 0000000..3e33583 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.median.md @@ -0,0 +1,120 @@ +--- +description: Return the median of the values for the requested axis. +--- + +# DataFrame.median + +danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Calculates the median of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.median().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 2 ║ +╟───┼──────────────────────╢ +║ B │ 25 ║ +╟───┼──────────────────────╢ +║ C │ 23 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculates the median of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.median({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 11 ║ +╟───┼──────────────────────╢ +║ 1 │ 6 ║ +╟───┼──────────────────────╢ +║ 2 │ 30 ║ +╟───┼──────────────────────╢ +║ 3 │ 78 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.min.md b/api-reference copy/dataframe/danfo.dataframe.min.md new file mode 100644 index 0000000..49a13d6 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.min.md @@ -0,0 +1,120 @@ +--- +description: Return the minimum of the values for the requested axis. +--- + +# DataFrame.min + +danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Returns the minimum value along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() + +let df = new dfd.DataFrame(data) +df.min().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ 1 ║ +╟───┼──────────────────────╢ +║ B │ 15 ║ +╟───┼──────────────────────╢ +║ C │ 3 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Return the minimum value along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +df.print() +let df = new dfd.DataFrame(data) +df.min({axis: 0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.mod.md b/api-reference copy/dataframe/danfo.dataframe.mod.md new file mode 100644 index 0000000..18558e6 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.mod.md @@ -0,0 +1,258 @@ +--- +description: Get Modulo of DataFrame and other, element-wise (binary operator mod). +--- + +# DataFrame.mod + +danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Modulo of **scalar with** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.mod(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of **Series with** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.mod(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 4 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.mod(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 5 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Modulo of **** Array with DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.mod(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Modulo works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.mod(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.mul.md b/api-reference copy/dataframe/danfo.dataframe.mul.md new file mode 100644 index 0000000..3303d77 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.mul.md @@ -0,0 +1,252 @@ +--- +description: Get Multiplication of dataframe and other, element-wise (binary operator mul). +--- + +# DataFrame.mul + +danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Multiplication of **scalar to** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.mul(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Multiplication of **Series to** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.mul(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 4 │ 15 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 16 │ 10 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 4 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Multiplication of **** DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.mul(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 100 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 8 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Multiplication of **** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.mul(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Multiplication works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.mul(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 46 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 90 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 112 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 48 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.ne.md b/api-reference copy/dataframe/danfo.dataframe.ne.md new file mode 100644 index 0000000..dd45cf0 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.ne.md @@ -0,0 +1,187 @@ +--- +description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). +--- + +# DataFrame.ne + +danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | +| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | +| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | + +**Returns:** + +**** + +## **Examples** + +### Comparing **** DataFrame with a scalar value: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) + +let df_rep = df.ne(20) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ false ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ true │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a Series along the column axis: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([10,40]) + +let df_rep = df.ne(sf, {axis:1}) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ true ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let data2 = {"new_col1": [10, 45, 200, 10], + "new_Col2": [230, 200, 110, 24]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_rep = df.ne(df2) + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ false │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ true │ true ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ false │ false ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Comparing **** DataFrame with a JavaScript Array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24]} +let df = new dfd.DataFrame(data) +let val = [10, 40, 30, 20] + +let df_rep = df.le(val) + +df_rep.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ true │ false │ false │ true ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ false │ true │ true │ false ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.pow.md b/api-reference copy/dataframe/danfo.dataframe.pow.md new file mode 100644 index 0000000..e6f1e6c --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.pow.md @@ -0,0 +1,260 @@ +--- +description: >- + Get Exponential power of dataframe and other, element-wise (binary operator + pow). +--- + +# DataFrame.pow + +danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Exponential of **scalar with** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.pow(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of **Series with** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.pow(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 243 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 256 │ 32 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 625 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1 │ 1024 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of **** DataFrame with a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.pow(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 1048576 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1024 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 95367433551872 │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 16 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + +### Exponential of **** Array with DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.pow(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Exponential works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.pow(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 529 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 2025 │ 400 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 3136 │ 100 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 100 │ 576 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.query.md b/api-reference copy/dataframe/danfo.dataframe.query.md new file mode 100644 index 0000000..129c8e7 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.query.md @@ -0,0 +1,278 @@ +--- +description: >- + Query the DataFrame by the result of a logical comparison or boolean mask. + Supports logical operations like (">", "<", ">=", "<=", and. "==") +--- + +# DataFrame.query + +danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | + +**Returns:** + + **** return **new DataFrame** + +## **Examples** + +## **Query a DataFrame using a boolean mask** + +{% hint style="info" %} +Querying by a boolean condition is supported from v0.3.0 and above. +{% endhint %} + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5) }) +query_df.print() //after query +``` + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: + +```javascript +let data = { + "A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} +let df = new dfd.DataFrame(data) + +let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) +query_df.print() //after query + +//output +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` + +## **Query a DataFrame using logical operators** + +To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() //before query + +let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) +query_df.print() //after query +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//before query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 4 │ 5 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 20 │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 89 │ 78 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) +query_df.print() //after query + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Query by a string column in a DataFrame** + +The query method also works on string columns. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": ["Ng", "Yu", "Mo", "Ng"], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let df = new dfd.DataFrame(data) + +df.print() + +let query_df = df.query({ column: "A", is: "==", to: "Ng"}) +query_df.print() //after query + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//after query + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Query a DataFrame inplace** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40]} + +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) + +df.query({ + column: "B", + is: ">", + to: 5, + inplace: true +}) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 30 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 3 │ 6 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.replace.md b/api-reference copy/dataframe/danfo.dataframe.replace.md new file mode 100644 index 0000000..82fa16d --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.replace.md @@ -0,0 +1,102 @@ +--- +description: Replaces values in a DataFrame with specified values +--- + +# DataFrame.replace + +> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| oldValue | String, boolean, Number | The value you want to replace | | +| newValue | String, boolean, Number | The new value you want to replace the old value with | | +| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | + +**Returns:** + + **** return **DataFrame** + +**** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_rep = df.replace(10, -999, { columns: ["Col1"] }) + +df_rep.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ -999 │ 23 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 45 │ 20 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 56 │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ -999 │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +By not specifying a **** column**,** the **** replace works on all columns **** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] +let df = new dfd.DataFrame(data) +//replace value in all column +let df_rep = df.replace("A", "BOY") + +df_rep.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```javascript + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ BOY │ BOY │ BOY │ B ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ B │ C │ C │ D ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.round.md b/api-reference copy/dataframe/danfo.dataframe.round.md new file mode 100644 index 0000000..e12cb52 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.round.md @@ -0,0 +1,128 @@ +--- +description: Round elements in a DataFrame to a specified number of decimal places. +--- + +# DataFrame.round + +danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | +| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +## Round elements to 1dp (Default) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() + +let new_df = df.round() + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.234 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after round + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1 │ 3.6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.1 │ 40.2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Round elements to a specified number of decimal places + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() + +let new_df = df.round(2) + +new_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.234 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after round operation + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11.2 │ 20.12 │ 3.57 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15.1 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 3.09 │ 40.23 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## diff --git a/api-reference copy/dataframe/danfo.dataframe.sample.md b/api-reference copy/dataframe/danfo.dataframe.sample.md new file mode 100644 index 0000000..b8a4c96 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.sample.md @@ -0,0 +1,112 @@ +--- +description: Return a random sample of rows from DataFrame. +--- + +# DataFrame.sample + +danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | +| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | +| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | + +**Returns:** + + **** return **{Promies} resolves to DataFrame** + +**** + +## Sample a DataFrame randomly + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(2); + s_df.print(); + +} + +load_data() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Sample a DataFrame randomly with seed + +By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(3, { seed: 2 }); + s_df.print(); + +} + +load_data() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 21 │ 200 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.std.md b/api-reference copy/dataframe/danfo.dataframe.std.md new file mode 100644 index 0000000..1a37e2e --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.std.md @@ -0,0 +1,94 @@ +--- +description: Return sample standard deviation over requested axis. +--- + +# DataFrame.std + +danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Calculates the standard deviation of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.std().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4.69041575982343 ║ +╟───┼──────────────────────╢ +║ 1 │ 34.23935357645254 ║ +╟───┼──────────────────────╢ +║ 2 │ 35.103418636936205 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculates the standard deviation of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.std({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 8.504900548115383 ║ +╟───┼──────────────────────╢ +║ 1 │ 7.094598884597588 ║ +╟───┼──────────────────────╢ +║ 2 │ 19.697715603592208 ║ +╟───┼──────────────────────╢ +║ 3 │ 47.37439533475159 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## + diff --git a/api-reference copy/dataframe/danfo.dataframe.sub.md b/api-reference copy/dataframe/danfo.dataframe.sub.md new file mode 100644 index 0000000..e36ddcc --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.sub.md @@ -0,0 +1,250 @@ +--- +description: Get Subtraction of dataframe and other, element-wise (binary operator sub). +--- + +# DataFrame.sub + +danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to add with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Subtraction of **scalar to** DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) + +let df_new = df.sub(2) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Subtraction of **Series to** DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [1, 4, 5, 1], + "Col2": [3, 2, 0, 4] +} + +let df = new dfd.DataFrame(data) +let sf = new dfd.Series([4, 5]) + +let df_new = df.sub(sf, { axis: 1 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ -3 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ -3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ -5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -3 │ -1 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Subtraction of **** DataFrame to a DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = {"Col1": [1, 4, 5, 0], + "Col2": [2, 0, 1, 4]} + +let data2 = {"new_col1": [1, 5, 20, 10], + "new_Col2": [20, 2, 1, 2]} + +let df = new dfd.DataFrame(data) +let df2 = new dfd.DataFrame(data2) + +let df_new = df.sub(df2) + +df_new.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ -18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ -1 │ -2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ -15 │ 0 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ -10 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### Subtraction of **** Array to DataFrame along axis 0 + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +let df_new = df.sub(val, { axis: 0 }) + +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + +### Subtraction works inplace + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} + +let df = new dfd.DataFrame(data) +let val = [2, 2, 2, 2] + +df.sub(val, { axis: 0, inplace: true }) + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 8 │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 43 │ 18 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 54 │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 8 │ 22 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + + +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/dataframe/danfo.dataframe.sum.md b/api-reference copy/dataframe/danfo.dataframe.sum.md new file mode 100644 index 0000000..3937d3f --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.sum.md @@ -0,0 +1,121 @@ +--- +description: Return the sum of the values for the requested axis. +--- + +# DataFrame.sum + +danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Sum elements along default axis (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +df.print() + +let df_sum = df.sum() +df_sum.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════════════════════╗ +║ A │ 37.199999999999996 ║ +╟───┼────────────────────╢ +║ B │ 41 ║ +╟───┼────────────────────╢ +║ C │ -10 ║ +╚═══╧════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Sum elements along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +df.print() + +let df_sum = df.sum({axis: 0}) +df_sum.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ sum ║ +╟───┼──────────────────────╢ +║ 0 │ 33.9 ║ +╟───┼──────────────────────╢ +║ 1 │ 6 ║ +╟───┼──────────────────────╢ +║ 2 │ 82.3 ║ +╟───┼──────────────────────╢ +║ 3 │ -54 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.tail.md b/api-reference copy/dataframe/danfo.dataframe.tail.md new file mode 100644 index 0000000..165acac --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.tail.md @@ -0,0 +1,53 @@ +--- +description: Returns the last n rows from the DataFrame based on position. +--- + +# DataFrame.tail + +danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | ---------------------------- | ------- | +| rows | Int | The number of rows to return | 5 | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] } + +let df = new dfd.DataFrame(data) +let s_df = df.tail(3) +s_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 30 │ 40 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Pear │ 10 │ 250 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.var.md b/api-reference copy/dataframe/danfo.dataframe.var.md new file mode 100644 index 0000000..ea0daf2 --- /dev/null +++ b/api-reference copy/dataframe/danfo.dataframe.var.md @@ -0,0 +1,94 @@ +--- +description: Return unbiased variance over requested axis. +--- + +# DataFrame.var + +danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | +| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | + +**Returns:** + + **** return **Series** + +## **Examples** + +## Calculate variance of values along default axis 1 (column) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.var().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 22 ║ +╟───┼──────────────────────╢ +║ 1 │ 1172.3333333333333 ║ +╟───┼──────────────────────╢ +║ 2 │ 1232.25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## Calculate variance of values along row axis (0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data) +df.var({axis:0}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 72.33333333333334 ║ +╟───┼──────────────────────╢ +║ 1 │ 50.33333333333333 ║ +╟───┼──────────────────────╢ +║ 2 │ 388 ║ +╟───┼──────────────────────╢ +║ 3 │ 2244.333333333333 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference copy/dataframe/dataframe.append.md b/api-reference copy/dataframe/dataframe.append.md new file mode 100644 index 0000000..bc2e29d --- /dev/null +++ b/api-reference copy/dataframe/dataframe.append.md @@ -0,0 +1,76 @@ +--- +description: Adds new row to the end of a DataFrame +--- + +# DataFrame.append + +danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] + +| Parameters | Type | Description | Default | +| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | +| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | +| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Appends a new row to the end of a DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = [[0, 2, 4, "b"], + [360, 180, 360, "a"], + [2, 4, 6, "c"]] + +let df = new dfd.DataFrame(data) +df.print() + +let new_df = df.append([[20, 40, 60, "d"]], [3]) +new_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 4 │ 6 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (4,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 4 │ 6 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 40 │ 60 │ d ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/dataframe/dataframe.apply_map.md b/api-reference copy/dataframe/dataframe.apply_map.md new file mode 100644 index 0000000..3819821 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.apply_map.md @@ -0,0 +1,68 @@ +--- +description: Apply a function to a Dataframe values element-wise. +--- + +# DataFrame.apply\_map + +danfo.DataFrame.**apply\_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | --------------------------------------------------------------------- | --------- | +| callable | Function | Function to apply to each column or row | | +| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Apply a function to all values in a DataFrame + +{% hint style="info" %} +Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + short_name: ["NG", "GH", "EGY", "SA"], + long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] +} +let df = new dfd.DataFrame(data) + +function lower(x) { + return `${x}`.toLowerCase() +} + +let df_new = df.apply_map(lower) +df_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ short_name │ long_name ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ ng │ nigeria ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ gh │ ghana ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ egy │ eqypt ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ sa │ south africa ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.astype.md b/api-reference copy/dataframe/dataframe.astype.md new file mode 100644 index 0000000..e6434dc --- /dev/null +++ b/api-reference copy/dataframe/dataframe.astype.md @@ -0,0 +1,222 @@ +--- +description: Cast column of a DataFrame to a specified dtype. +--- + +# DataFrame.astype + +danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Cast a float dtype column to int** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.print() +df.ctypes.print() + +let df_new = df.astype({column: "A", dtype: "int32"}) +df_new.print() + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//before casting +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ + + + //after casting + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20.1 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47 │ 5 │ 30.3 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ int32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Casting a string column of numbers to int** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["20", "13", "45", "90"] } + +let df = new dfd.DataFrame(data) +let df_new = df.astype({column: "D", dtype: "int32"}) +df_new.print() + +df_new.ctypes.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ 13 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ 45 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +**Note:** Casting a string column of alphabets/words to numeric form will return NaNs as values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20.1, 30, 47.3, -20] , + "B": [34, -4, 5, 6], + "C": [20.1, -20.23, 30.3, 40.11], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +let df_new = df.astype({column: "D", dtype: "int32"}) +df_new.print() + +df_new.ctypes.print() + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20.1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20.23 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30.3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ float32 ║ +╟───┼──────────────────────╢ +║ D │ int32 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.axes.md b/api-reference copy/dataframe/dataframe.axes.md new file mode 100644 index 0000000..399a0a4 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.axes.md @@ -0,0 +1,47 @@ +--- +description: >- + Return an Object containing the axes of the DataFrame. It has the row axis + labels and column axis labels as the only members. They are returned in that + order. +--- + +# DataFrame.axis + +danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + + **** return **Object** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) + +console.log(df.axis) + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +{ index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.drop.md b/api-reference copy/dataframe/dataframe.drop.md new file mode 100644 index 0000000..0b742aa --- /dev/null +++ b/api-reference copy/dataframe/dataframe.drop.md @@ -0,0 +1,143 @@ +--- +description: >- + Drop specified labels from rows or columns.Remove rows or columns by + specifying label names and corresponding axis. +--- + +# DataFrame.drop + +danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Drop columns by specifying the names + +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.drop({ columns: ["C", "B"], inplace: true }); +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ D ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ a ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ b ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ c ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ c ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop rows by specifying int labels/index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] +} + +let df = new dfd.DataFrame(data) +df.drop({ index: [0, 2], inplace: true }); +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ 30 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop rows by specifying string labels/index + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20], + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) +df.drop({ index: ["a", "c"], inplace: true }); +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -4 │ 20 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ d │ -20 │ 6 │ 30 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.dtypes.md b/api-reference copy/dataframe/dataframe.dtypes.md new file mode 100644 index 0000000..791d296 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.dtypes.md @@ -0,0 +1,100 @@ +--- +description: >- + Return the inferred column types in the DataFrame. This returns a Series with + the data type of each column. The result’s index is the original DataFrame’s + columns. +--- + +# DataFrame.ctypes + +danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] + +**Returns:** + + **** return **Series** + +## **Examples** + +Returns auto-generated **** index of a **** DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Columns with mixed types are represented as **string.** + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40], + "D": ["a", "b", 20, 2.5]} + +let df = new dfd.DataFrame(data) + +df.ctypes.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ A │ float32 ║ +╟───┼──────────────────────╢ +║ B │ int32 ║ +╟───┼──────────────────────╢ +║ C │ int32 ║ +╟───┼──────────────────────╢ +║ D │ string ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference copy/dataframe/dataframe.index.md b/api-reference copy/dataframe/dataframe.index.md new file mode 100644 index 0000000..a185e63 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.index.md @@ -0,0 +1,69 @@ +--- +description: The index (row labels) of the DataFrame. +--- + +# DataFrame.index + +danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] + +## **Examples** + +Returns auto-generated **** index of a **** DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +console.log(df.index); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[0, 1, 2, 3] +``` +{% endtab %} +{% endtabs %} + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data, {index: ["r1", "r2", "r3", "r4"]) + +console.log(df.index); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ 'r1', 'r2', 'r3', 'r4' ] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.ndim.md b/api-reference copy/dataframe/dataframe.ndim.md new file mode 100644 index 0000000..c64dd09 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.ndim.md @@ -0,0 +1,46 @@ +--- +description: >- + Return an int representing the number of axes / array dimensions. Returns 1 if + Series. Otherwise return 2 for DataFrame. +--- + +# DataFrame.ndim + +danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + + **** return **Int** + +**Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data) + +console.log(df.ndim) + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +2 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.nunique-1.md b/api-reference copy/dataframe/dataframe.nunique-1.md new file mode 100644 index 0000000..8166904 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.nunique-1.md @@ -0,0 +1,98 @@ +# DataFrame.nunique + +danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] + +| Parameters | Type | Description | Default | +| ---------- | ---- | -------------------------------------- | ------- | +| axis | Int | 0 for row axis, and 1 for column axis | 1 | + +**Returns:** + + **** return **Series** + +## **Examples** + +### Return number of unique values along column axis (axis=1) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.nunique().print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 4 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} + +### Return number of unique values in row axis (axis=0) + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30], + "D": ["a", "b", "c", "c"] } + +let df = new dfd.DataFrame(data) +df.nunique(axis=0).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 4 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note:** To get the unique elements along an axis, use **** [DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference copy/dataframe/dataframe.print.md b/api-reference copy/dataframe/dataframe.print.md new file mode 100644 index 0000000..d03232d --- /dev/null +++ b/api-reference copy/dataframe/dataframe.print.md @@ -0,0 +1,105 @@ +--- +description: >- + Pretty prints default (10) number of rows in a DataFrame or Series to the + console +--- + +# DataFrame.print + +danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 4, 5] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Abs │ Count │ country code ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.2 │ 34 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 4 │ FR ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ GH ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Using JavaScript default **console.log** to display a DataFrame will return the Object instead unless you manually cast it to a String + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 4, 5, 6] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +console.log(df) +console.log(String(df)); +// console.log(df + ""); //same result as above +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +DataFrame { + '$isSeries': false, + '$config': Configs { + tableDisplayConfig: {}, + tableMaxRow: 10, + tableMaxColInConsole: 21, + dtypeTestLim: 7, + lowMemoryMode: false + }, + '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], + '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], + '$index': [ 0, 1, 2 ], + '$dtypes': [ 'float32', 'int32', 'string' ], + '$columns': [ 'Abs', 'Count', 'country code' ] +} +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Abs │ Count │ country code ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20.2 │ 34 │ NG ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ FR ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ GH ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.rename.md b/api-reference copy/dataframe/dataframe.rename.md new file mode 100644 index 0000000..c33ce99 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.rename.md @@ -0,0 +1,148 @@ +--- +description: >- + Change axes labels. Object values must be unique (1-to-1). Labels not + contained in a dict / Series will be left as-is. Extra labels listed don’t + throw an error. +--- + +# DataFrame.rename + +danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | +| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### Rename columns + +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -4, 5], + "C": [20, 2, 30] } + + +let df = new dfd.DataFrame(data) +df.rename({ mapper: {"A": "new_name"},inplace: true }) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ new_name │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Rename more the one column at time + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -4, 6], + "C": [20, 2, 30] } + + +let df = new dfd.DataFrame(data) +df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ new_name │ B │ new_c ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Rename index by labels + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3], + "B": [34, -4, 6], + "C": [20, 2, 30] +} + + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) +df = df.rename({ mapper: { "a": 0 }, axis: 0 }) +df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -4 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 47.3 │ 5 │ 30 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.reset_index.md b/api-reference copy/dataframe/dataframe.reset_index.md new file mode 100644 index 0000000..ddee8e0 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.reset_index.md @@ -0,0 +1,73 @@ +--- +description: Reset the index of the DataFrame, and use the default one instead. +--- + +# DataFrame.reset\_index + +danfo.DataFrame.**reset\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] +} + + +let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) +df.print() + +df.reset_index({ inplace: true }) //inplace +//df = df.reset_index() //not in inplace + +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.select_dtypes.md b/api-reference copy/dataframe/dataframe.select_dtypes.md new file mode 100644 index 0000000..ba5044e --- /dev/null +++ b/api-reference copy/dataframe/dataframe.select_dtypes.md @@ -0,0 +1,94 @@ +--- +description: Return a subset of the DataFrame’s columns based on the column dtypes. +--- + +# DataFrame.select\_dtypes + +danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] + +| Parameters | Type | Description | Default | +| ---------- | ----- | -------------------------------- | ------- | +| include | Array | List of column dtypes to return | | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40], + "D": ["a", "b", 20, 2.5]} + +let df = new dfd.DataFrame(data) + +float_df = df.select_dtypes(['float32']) +float_df.print() + +mix_df = df.select_dtypes(include=['float32', "int32"]) +mix_df.print() + +str_df = df.select_dtypes(include=['string']) +str_df.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//select float column(s) +╔═══╤══════════════════════╗ +║ │ A ║ +╟───┼──────────────────────╢ +║ 0 │ -20.1 ║ +╟───┼──────────────────────╢ +║ 1 │ 30 ║ +╟───┼──────────────────────╢ +║ 2 │ 47.3 ║ +╟───┼──────────────────────╢ +║ 3 │ -20 ║ +╚═══╧══════════════════════╝ + + + //select both float and int columns + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20.1 │ 34 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ -20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ -20 │ 6 │ -40 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//return string type column +╔═══╤══════════════════════╗ +║ │ D ║ +╟───┼──────────────────────╢ +║ 0 │ a ║ +╟───┼──────────────────────╢ +║ 1 │ b ║ +╟───┼──────────────────────╢ +║ 2 │ 20 ║ +╟───┼──────────────────────╢ +║ 3 │ 2.5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.set_index.md b/api-reference copy/dataframe/dataframe.set_index.md new file mode 100644 index 0000000..e82c213 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.set_index.md @@ -0,0 +1,176 @@ +--- +description: >- + Set the DataFrame index using existing columns or an array (of the equal + length). +--- + +# DataFrame.set_index + +danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | + +## **Examples** + +### **Setting index to a column in the DataFrame** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) +df.print() + +df.set_index({column: "A", inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ -20 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 30 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **** + +### **Setting index to a column in the DataFrame and dropping the column** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) +df.print() + +df.set_index({column: "A", drop: true, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ B │ C ║ +╟────────────┼───────────────────┼───────────────────╢ +║ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Set index to an array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, -5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.print() + +let new_index = ["a", "b", "c"] +df.set_index({index: new_index, inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 30 │ -5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). diff --git a/api-reference copy/dataframe/dataframe.shape.md b/api-reference copy/dataframe/dataframe.shape.md new file mode 100644 index 0000000..746491d --- /dev/null +++ b/api-reference copy/dataframe/dataframe.shape.md @@ -0,0 +1,43 @@ +--- +description: Returns an Array representing the dimensionality of the DataFrame. +--- + +# DataFrame.shape + +danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + + **** return **Int** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} +let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) + +console.log(df.shape) + + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[4,3] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.sort_index.md b/api-reference copy/dataframe/dataframe.sort_index.md new file mode 100644 index 0000000..81d5b7f --- /dev/null +++ b/api-reference copy/dataframe/dataframe.sort_index.md @@ -0,0 +1,74 @@ +--- +description: Sort DataFrame by index +--- + +# DataFrame.sort\_index + +DataFrame.**sort\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Sort DataFrame by a column in ascending order** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [[0, 2, 4, "b"], + [360, 180, 360, "a"], + [2, 4, 6, "c"]] + +let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], + index: ["b", "a", "c"] }) +df.print() + +let df2 = df.sort_index({ ascending: false }) +df2.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 360 │ 180 │ 360 │ a ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 2 │ 4 │ 6 │ c ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after sorting in descending order + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ col1 │ col2 │ col3 │ col4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ c │ 2 │ 4 │ 6 │ c ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ b │ 0 │ 2 │ 4 │ b ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ a │ 360 │ 180 │ 360 │ a ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/dataframe/dataframe.sort_values.md b/api-reference copy/dataframe/dataframe.sort_values.md new file mode 100644 index 0000000..54345b1 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.sort_values.md @@ -0,0 +1,99 @@ +--- +description: Sort a Dataframe in ascending or descending order by a specified column name. +--- + +# DataFrame.sort\_values + +danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Sort DataFrame by a column in ascending order** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.sort_values({by: "C", inplace: true}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Sort DataFrame by a column in descending order** + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] } + + +let df = new dfd.DataFrame(data) +df.sort_values({by: "B", inplace: true, ascending: false}) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 6 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 5 │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.tensor.md b/api-reference copy/dataframe/dataframe.tensor.md new file mode 100644 index 0000000..822886e --- /dev/null +++ b/api-reference copy/dataframe/dataframe.tensor.md @@ -0,0 +1,110 @@ +--- +description: >- + Return a Tensorflow tensor representation of the DataFrame. Only the values in + the DataFrame will be returned, the axes labels will be removed. +--- + +# DataFrame.tensor + +danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + + **** return **tf.tensor** + +> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "A": [-20, 30, 47.3, -20] , + "B": [34, -4, 5, 6] , + "C": [20, 20, 30, 30]} + +let df = new dfd.DataFrame(data) +let tf_tensor = df.tensor + +console.log(tf_tensor.dtype); + +console.log(tf_tensor); + +tf_tensor.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 +Tensor + [[-20 , 34, 20], + [30 , -4, 20], + [47.2999992, 5 , 30], + [-20 , 6 , 30]] +``` +{% endtab %} +{% endtabs %} + +String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { "Abs": [20.2, 30, 47.3] , + "Count": [34, 5, 6] , + "country code": ["NG", "FR", "GH"] } + + +let df = new dfd.DataFrame(data) +let tf_tensor = df.tensor + +console.log(tf_tensor.dtype); + +console.log(tf_tensor); + +tf_tensor.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 + +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 3, 3 ], + dtype: 'float32', + size: 9, + strides: [ 3 ], + dataId: {}, + id: 0, + rankType: '2' +} + +Tensor + [[20.2000008, 34, NaN], + [30 , 4 , NaN], + [47.2999992, 5 , NaN]] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.to_csv.md b/api-reference copy/dataframe/dataframe.to_csv.md new file mode 100644 index 0000000..8e84e9a --- /dev/null +++ b/api-reference copy/dataframe/dataframe.to_csv.md @@ -0,0 +1,114 @@ +--- +description: Convert DataFrame data to a comma-separated values (csv) +--- + +# DataFrame.to\_csv + +DataFrame.**to\_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] + +| | | | | +| -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +*** + +### Convert DataFrame to CSV string and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const csv = df.to_csv({ download: false }); +console.log(csv); + +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ filePath: "testOut.csv"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and download file in browser + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_csv({ fileName: "testOut.csv", download: true}); +``` diff --git a/api-reference copy/dataframe/dataframe.to_excel.md b/api-reference copy/dataframe/dataframe.to_excel.md new file mode 100644 index 0000000..4adf437 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.to_excel.md @@ -0,0 +1,53 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# DataFrame.to_excel + +> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] + +| **Parameters** | Type | Description | Default | +| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| + +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in a browser + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_excel({ fileName: "testOut.xlsx"}); +``` diff --git a/api-reference copy/dataframe/dataframe.to_json.md b/api-reference copy/dataframe/dataframe.to_json.md new file mode 100644 index 0000000..326f422 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.to_json.md @@ -0,0 +1,127 @@ +--- +description: Convert DataFrame to JSON format +--- + +# DataFrame.to\_json + +> DataFrame.**to\_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] + +| | | | | +| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. + +### Convert DataFrame/Series to JSON and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = df.to_json({ download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = df.to_json({ + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ filePath: "./testOutput.json" }); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +df.to_json({ fileName: "test_out.json" }); +``` diff --git a/api-reference copy/dataframe/dataframe.values.md b/api-reference copy/dataframe/dataframe.values.md new file mode 100644 index 0000000..598e395 --- /dev/null +++ b/api-reference copy/dataframe/dataframe.values.md @@ -0,0 +1,50 @@ +--- +description: Return a the JavaScript array representation of the DataFrame. +--- + +# DataFrame.values + +danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] + +**Returns:** + + **** return **Array** + +**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = {"A": [-20.1, 30, 47.3, -20], + "B": [34, -4, 5, 6], + "C": [20, -20, 30, -40]} + +let df = new dfd.DataFrame(data) + +console.log(df.values) + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + [ -20.1, 34, 20 ], + [ 30, -4, -20 ], + [ 47.3, 5, 30 ], + [ -20, 6, -40 ] +] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/general-functions/README.md b/api-reference copy/general-functions/README.md new file mode 100644 index 0000000..07815b0 --- /dev/null +++ b/api-reference copy/general-functions/README.md @@ -0,0 +1,27 @@ +--- +description: Top level functions that can be called from the Danfo namespace +--- + +# General Functions + +### Data manipulations + +| | | +| ------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | +| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | +| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | + +### Data Processing/Normalization + +| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | +| ----------------------------------------- | ---------------------------------------------------------------------- | +| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | +| [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | +| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | + +### Top-level dealing with datetime + +| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | +| ------------------------------------ | --------------------------------------- | +| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference copy/general-functions/danfo.concat.md b/api-reference copy/general-functions/danfo.concat.md new file mode 100644 index 0000000..e248f46 --- /dev/null +++ b/api-reference copy/general-functions/danfo.concat.md @@ -0,0 +1,187 @@ +--- +description: Concatenate DataFrames and Series along an axis +--- + +# danfo.concat + +danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | +| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Concatenate two DataFrames along column axis (1)** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) +com_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Concatenate two DataFrames along row axis (0)** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +com_df.print(10) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Concatenate two Series along row axis (0)** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], +['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], +['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) + + +let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +com_df.print(10) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. diff --git a/api-reference copy/general-functions/danfo.date_range.md b/api-reference copy/general-functions/danfo.date_range.md new file mode 100644 index 0000000..9c4a337 --- /dev/null +++ b/api-reference copy/general-functions/danfo.date_range.md @@ -0,0 +1,111 @@ +--- +description: Return a fixed frequency Dates spread between start and end parameters. +--- + +# danfo.date\_range + +danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) +console.log(data); +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + '1/1/2018, 12:00:00 AM', + '2/1/2018, 12:00:00 AM', + '3/1/2018, 12:00:00 AM', + '4/1/2018, 12:00:00 AM', + '5/1/2018, 12:00:00 AM' +] +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) +console.log(data); +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ + '1/1/2018, 12:00:00 AM', + '1/1/2019, 12:00:00 AM', + '1/1/2020, 12:00:00 AM', + '1/1/2021, 12:00:00 AM', + '1/1/2022, 12:00:00 AM', + '1/1/2023, 12:00:00 AM', + '1/1/2024, 12:00:00 AM', + '1/1/2025, 12:00:00 AM', + '1/1/2026, 12:00:00 AM', + '1/1/2027, 12:00:00 AM', + '1/1/2028, 12:00:00 AM', + '1/1/2029, 12:00:00 AM' +] +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +{% endhint %} diff --git a/api-reference copy/general-functions/danfo.get_dummies.md b/api-reference copy/general-functions/danfo.get_dummies.md new file mode 100644 index 0000000..e53fd81 --- /dev/null +++ b/api-reference copy/general-functions/danfo.get_dummies.md @@ -0,0 +1,188 @@ +--- +description: Convert categorical variable into dummy/indicator variables. +--- + +# danfo.get\_dummies + +danfo.**get\_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| data | Series or Dataframe | The data to dummify | | +| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +### **Convert Series to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] +let sf1 = new dfd.Series(datasf) + +let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Convert all categorical columns in a DataFrame to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + +let df = new dfd.DataFrame(data) +df.print() + +let dum_df = dfd.get_dummies(df) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruits │ Count │ Country ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ pear │ 20 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ mango │ 30 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ pawpaw │ 89 │ GH ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ mango │ 12 │ RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bean │ 30 │ RU ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after dummification + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Count │ fruits_pear │ fruits_mango │ ... │ fruits_bean │ Country_NG │ Country_GH │ Country_RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ 1 │ 0 │ ... │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ 0 │ 1 │ ... │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 89 │ 0 │ 0 │ ... │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ 0 │ 1 │ ... │ 0 │ 0 │ 0 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 30 │ 0 │ 0 │ ... │ 1 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Convert a specific column in a DataFrame to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + +let df = new dfd.DataFrame(data) +df.print() + +let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +dum_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ fruits │ Count │ Country ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ pear │ 20 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ mango │ 30 │ NG ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ pawpaw │ 89 │ GH ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ mango │ 12 │ RU ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bean │ 30 │ RU ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //after dummification + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Count │ Country │ fruits_pear │ fruits_mango │ fruits_pawpaw │ fruits_bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 20 │ NG │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ NG │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 89 │ GH │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 12 │ RU │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 30 │ RU │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) +{% endhint %} diff --git a/api-reference copy/general-functions/danfo.labelencoder.md b/api-reference copy/general-functions/danfo.labelencoder.md new file mode 100644 index 0000000..b0745a8 --- /dev/null +++ b/api-reference copy/general-functions/danfo.labelencoder.md @@ -0,0 +1,140 @@ +--- +description: Encode target labels with value between 0 and n_classes-1. +--- + +# danfo.LabelEncoder + +class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. + +The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. + +## **Examples** + +### **Label Encode values in a Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = ["dog","cat","man","dog","cat","man","man","cat"] +let series = new dfd.Series(data) + +let encode = new dfd.LabelEncoder() + +encode.fit(series) +console.log(encode); + +let sf_enc = encode.transform(series.values) +sf_enc.print() + +let new_sf = encode.transform(["dog","man"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +LabelEncoder { label: [ 'dog', 'cat', 'man' ] } +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 1 ║ +╟───┼──────────────────────╢ +║ 5 │ 2 ║ +╟───┼──────────────────────╢ +║ 6 │ 2 ║ +╟───┼──────────────────────╢ +║ 7 │ 1 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +**Labels not found in the original data used for fitting are represented with -1** +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.LabelEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","man"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference copy/general-functions/danfo.merge.md b/api-reference copy/general-functions/danfo.merge.md new file mode 100644 index 0000000..0c4b760 --- /dev/null +++ b/api-reference copy/general-functions/danfo.merge.md @@ -0,0 +1,453 @@ +--- +description: >- + Merge DataFrame or named Series objects with a database-style join.The join is + done on columns or indexes. +--- + +# danfo.merge + +danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. + +danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. + +For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user\_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. + +### **Merging by a single key found in both axis** + +By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + + //first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //Second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After inner join on column 'Key1' + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +### **Inner Join/Merge by multiple keys found in both axis** + +Merging by two keys takes into consideration the keys appearing in both`left` and `right DataFrame.` + +{% tabs %} +{% tab title="Node" %} +```javascript + +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", 'Key2'], how: "inner"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //After inner join on two keys + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent + +### Outer join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1"], how: "outer"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//First DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //Second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//After outer join + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Left join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", "Key2"], how: "left"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + After left join +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ K2 │ K2 │ A3 │ B3 │ NaN │ NaN ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Right join/merge on DataFrame + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], + ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] + +let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], + ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] + +let colum1 = ['Key1', 'Key2', 'A', 'B'] +let colum2 = ['Key1', 'Key2', 'A', 'D'] + +let df1 = new dfd.DataFrame(data, { columns: colum1 }) +let df2 = new dfd.DataFrame(data2, { columns: colum2 }) +df1.print() +df2.print() + +let merge_df = dfd.merge({ left: df1, right: df2, + on: ["Key1", "Key2"], how: "right"}) +merge_df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//first DataFrame +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + //second DataFrame + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + +//after right join + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K0 │ NaN │ NaN │ C3 │ D3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. +{% endhint %} diff --git a/api-reference copy/general-functions/danfo.minmaxscaler.md b/api-reference copy/general-functions/danfo.minmaxscaler.md new file mode 100644 index 0000000..d58af8b --- /dev/null +++ b/api-reference copy/general-functions/danfo.minmaxscaler.md @@ -0,0 +1,125 @@ +--- +description: Transform features by scaling each feature to a range of max and min values. +--- + +# danfo.MinMaxScaler + +class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. + +This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). + +The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. + +## **Examples** + +### Standardize DataFrame Object using MinMaxScaler + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let scaler = new dfd.MinMaxScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 20, 10], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +df.print() + +scaler.fit(df) + +let df_enc = scaler.transform(df) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 30 │ 20 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 1 │ 1 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 1 │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0.19191919267... │ 0.02902902849... │ 0.00950475223... │ 0.00333333341... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Standardize Series Object Using MinMaxScaler + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let scaler = new dfd.MinMaxScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 20, 10], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +let sf = df.iloc({columns: ["0"]}) + +scaler.fit(sf) + +let df_enc = scaler.transform(sf) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + + Shape: (3,1) + +╔═══╤═══════════════════╗ +║ │ 0 ║ +╟───┼───────────────────╢ +║ 0 │ 1 ║ +╟───┼───────────────────╢ +║ 1 │ 0.19191919267... ║ +╟───┼───────────────────╢ +║ 2 │ 0 ║ +╚═══╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference copy/general-functions/danfo.onehotencoder.md b/api-reference copy/general-functions/danfo.onehotencoder.md new file mode 100644 index 0000000..81c913d --- /dev/null +++ b/api-reference copy/general-functions/danfo.onehotencoder.md @@ -0,0 +1,148 @@ +--- +description: Encode categorical features as a one-hot numeric array. +--- + +# danfo.OneHotEncoder + +class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] + +danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. + +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. + +## **Examples** + +### **Convert Series to Dummy codes** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.OneHotEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","bean"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (2,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +**Labels not found in the original data used for fitting are represented with 0s all through** +{% endhint %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"]} + + +let df = new dfd.DataFrame(data) +let encode = new dfd.OneHotEncoder() + +encode.fit(df['fruits']) +console.log(encode); + +let sf_enc = encode.transform(df['fruits'].values) +sf_enc.print() + +let new_sf = encode.transform(["mango","woman", "cup"]) +new_sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 1 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ 0 │ 0 │ 0 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ pear │ mango │ pawpaw │ bean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 0 │ 1 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 0 │ 0 │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` +{% endtab %} +{% endtabs %} + +See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference copy/general-functions/danfo.standardscaler.md b/api-reference copy/general-functions/danfo.standardscaler.md new file mode 100644 index 0000000..89ce861 --- /dev/null +++ b/api-reference copy/general-functions/danfo.standardscaler.md @@ -0,0 +1,132 @@ +--- +description: Standardize features by removing the mean and scaling to unit variance. +--- + +# danfo.StandardScaler + +class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: + +> z = (x - u) / s + +where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. + +The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. + +## **Examples** + +### Standardize Series Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let scaler = new dfd.StandardScaler() + +let sf = new dfd.Series([100,1000,2000, 3000]) +sf.print() + +scaler.fit(sf) + +let sf_enc = scaler.transform(sf) +sf_enc.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 100 ║ +╟───┼──────────────────────╢ +║ 1 │ 1000 ║ +╟───┼──────────────────────╢ +║ 2 │ 2000 ║ +╟───┼──────────────────────╢ +║ 3 │ 3000 ║ +╚═══╧══════════════════════╝ + +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1.1375757455825806 ║ +╟───┼──────────────────────╢ +║ 1 │ -0.4191068708896637 ║ +╟───┼──────────────────────╢ +║ 2 │ 0.37919193506240845 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.1774907112121582 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Standardize DataFrame Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let scaler = new dfd.StandardScaler() + +let data = [[100,1000,2000, 3000] , + [20, 30, 89, 12], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data) +df.print() + +scaler.fit(df) + +let df_enc = scaler.transform(df) +df_enc.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 30 │ 20 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 1 │ 1 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ 0 │ 1 │ 2 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference copy/general-functions/danfo.to_datetime.md b/api-reference copy/general-functions/danfo.to_datetime.md new file mode 100644 index 0000000..7012100 --- /dev/null +++ b/api-reference copy/general-functions/danfo.to_datetime.md @@ -0,0 +1,141 @@ +--- +description: Converts an array of Date time string to Date object. +--- + +# danfo.toDateTime + +danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | +| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | + +**Returns:** + + **** return **DataFrame** + +## **Examples** + +Converts a **Series** of Date strings to Date time and get time properties + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) +let sf = new dfd.Series(data) +sf.print() + +let dt = dfd.toDateTime(data) + +dt.month().print() +dt.month_name().print() +dt.weekdays().print() +dt.day().print() +dt.seconds().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + 0 +0 1/1/2018, 12:00:00 AM +1 2/1/2018, 12:00:00 AM +2 3/1/2018, 12:00:00 AM +3 4/1/2018, 12:00:00 AM +4 5/1/2018, 12:00:00 AM +5 6/1/2018, 12:00:00 AM +6 7/1/2018, 12:00:00 AM +7 8/1/2018, 12:00:00 AM +8 9/1/2018, 12:00:00 AM +9 10/1/2018, 12:00:00 AM +10 11/1/2018, 12:00:00 AM +11 12/1/2018, 12:00:00 AM + +//Int representation for month + 0 +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +10 10 +11 11 + +//string representation for month +0 +0 Jan +1 Feb +2 Mar +3 Apr +4 May +5 Jun +6 Jul +7 Aug +8 Sep +9 Oct +10 Nov +11 Dec + +//string representation for day of the week +0 +0 Mon +1 Thur +2 Thur +3 Sun +4 Tue +5 Fri +6 Sun +7 Wed +8 Sat +9 Mon +10 Thur +11 Sat + +0 +0 1 +1 4 +2 4 +3 0 +4 2 +5 5 +6 0 +7 3 +8 6 +9 1 +10 4 +11 6 + +//Hour of the day +0 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +10 0 +11 0 + +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +{% endhint %} diff --git a/api-reference copy/groupby.md b/api-reference copy/groupby.md new file mode 100644 index 0000000..1db2e52 --- /dev/null +++ b/api-reference copy/groupby.md @@ -0,0 +1,122 @@ +--- +description: >- + GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby(), + danfo.Series.groupby() +--- + +# Groupby + +### Indexing, iteration + +| [`GroupBy.__iter__`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.__iter__.html#pandas.core.groupby.GroupBy.__iter__)\(\) | Groupby iterator. | +| :--- | :--- | +| [`GroupBy.groups`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups) | Dict {group name -> group labels}. | +| [`GroupBy.indices`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.indices.html#pandas.core.groupby.GroupBy.indices) | Dict {group name -> group indices}. | +| [`GroupBy.get_group`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.get_group.html#pandas.core.groupby.GroupBy.get_group)\(name\[, obj\]\) | Construct DataFrame from group with provided name. | + +| [`Grouper`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Grouper.html#pandas.Grouper)\(\*args, \*\*kwargs\) | A Grouper allows the user to specify a groupby instruction for an object. | +| :--- | :--- | + + +### Function application + +| [`GroupBy.apply`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.apply.html#pandas.core.groupby.GroupBy.apply)\(func, \*args, \*\*kwargs\) | Apply function func group-wise and combine the results together. | +| :--- | :--- | +| [`GroupBy.agg`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.agg.html#pandas.core.groupby.GroupBy.agg)\(func, \*args, \*\*kwargs\) | | +| [`SeriesGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.aggregate.html#pandas.core.groupby.SeriesGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | +| [`DataFrameGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html#pandas.core.groupby.DataFrameGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | +| [`SeriesGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.transform.html#pandas.core.groupby.SeriesGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed Series on each group and return a Series having the same indexes as the original object filled with the transformed values | +| [`DataFrameGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.transform.html#pandas.core.groupby.DataFrameGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed DataFrame on each group and return a DataFrame having the same indexes as the original object filled with the transformed values | +| [`GroupBy.pipe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pipe.html#pandas.core.groupby.GroupBy.pipe)\(func, \*args, \*\*kwargs\) | Apply a function func with arguments to this GroupBy object and return the function’s result. | + +### Computations / descriptive stats + +| [`GroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.all.html#pandas.core.groupby.GroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | +| :--- | :--- | +| [`GroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.any.html#pandas.core.groupby.GroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | +| [`GroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.bfill.html#pandas.core.groupby.GroupBy.bfill)\(\[limit\]\) | Backward fill the values. | +| [`GroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.backfill.html#pandas.core.groupby.GroupBy.backfill)\(\[limit\]\) | Backward fill the values. | +| [`GroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.count.html#pandas.core.groupby.GroupBy.count)\(\) | Compute count of group, excluding missing values. | +| [`GroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumcount.html#pandas.core.groupby.GroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | +| [`GroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummax.html#pandas.core.groupby.GroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | +| [`GroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummin.html#pandas.core.groupby.GroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | +| [`GroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumprod.html#pandas.core.groupby.GroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | +| [`GroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumsum.html#pandas.core.groupby.GroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | +| [`GroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ffill.html#pandas.core.groupby.GroupBy.ffill)\(\[limit\]\) | Forward fill the values. | +| [`GroupBy.first`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html#pandas.core.groupby.GroupBy.first)\(\[numeric\_only, min\_count\]\) | Compute first of group values. | +| [`GroupBy.head`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.head.html#pandas.core.groupby.GroupBy.head)\(\[n\]\) | Return first n rows of each group. | +| [`GroupBy.last`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html#pandas.core.groupby.GroupBy.last)\(\[numeric\_only, min\_count\]\) | Compute last of group values. | +| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max)\(\[numeric\_only, min\_count\]\) | Compute max of group values. | +| [`GroupBy.mean`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.mean.html#pandas.core.groupby.GroupBy.mean)\(\[numeric\_only\]\) | Compute mean of groups, excluding missing values. | +| [`GroupBy.median`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.median.html#pandas.core.groupby.GroupBy.median)\(\[numeric\_only\]\) | Compute median of groups, excluding missing values. | +| [`GroupBy.min`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.min.html#pandas.core.groupby.GroupBy.min)\(\[numeric\_only, min\_count\]\) | Compute min of group values. | +| [`GroupBy.ngroup`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ngroup.html#pandas.core.groupby.GroupBy.ngroup)\(\[ascending\]\) | Number each group from 0 to the number of groups - 1. | +| [`GroupBy.nth`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.nth.html#pandas.core.groupby.GroupBy.nth)\(n\[, dropna\]\) | Take the nth row from each group if n is an int, or a subset of rows if n is a list of ints. | +| [`GroupBy.ohlc`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ohlc.html#pandas.core.groupby.GroupBy.ohlc)\(\) | Compute open, high, low and close values of a group, excluding missing values. | +| [`GroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pad.html#pandas.core.groupby.GroupBy.pad)\(\[limit\]\) | Forward fill the values. | +| [`GroupBy.prod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.prod.html#pandas.core.groupby.GroupBy.prod)\(\[numeric\_only, min\_count\]\) | Compute prod of group values. | +| [`GroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html#pandas.core.groupby.GroupBy.rank)\(\[method, ascending, na\_option, …\]\) | Provide the rank of values within each group. | +| [`GroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pct_change.html#pandas.core.groupby.GroupBy.pct_change)\(\[periods, fill\_method, …\]\) | Calculate pct\_change of each value to previous entry in group. | +| [`GroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.size.html#pandas.core.groupby.GroupBy.size)\(\) | Compute group sizes. | +| [`GroupBy.sem`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sem.html#pandas.core.groupby.GroupBy.sem)\(\[ddof\]\) | Compute standard error of the mean of groups, excluding missing values. | +| [`GroupBy.std`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.std.html#pandas.core.groupby.GroupBy.std)\(\[ddof\]\) | Compute standard deviation of groups, excluding missing values. | +| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum)\(\[numeric\_only, min\_count\]\) | Compute sum of group values. | +| [`GroupBy.var`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.var.html#pandas.core.groupby.GroupBy.var)\(\[ddof\]\) | Compute variance of groups, excluding missing values. | +| [`GroupBy.tail`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.tail.html#pandas.core.groupby.GroupBy.tail)\(\[n\]\) | Return last n rows of each group. | + +The following methods are available in both `SeriesGroupBy` and `DataFrameGroupBy` objects, but may differ slightly, usually in that the `DataFrameGroupBy` version usually permits the specification of an axis argument, and often an argument indicating whether to restrict application to columns of a specific data type. + +| [`DataFrameGroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.all.html#pandas.core.groupby.DataFrameGroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | +| :--- | :--- | +| [`DataFrameGroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.any.html#pandas.core.groupby.DataFrameGroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | +| [`DataFrameGroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.backfill.html#pandas.core.groupby.DataFrameGroupBy.backfill)\(\[limit\]\) | Backward fill the values. | +| [`DataFrameGroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.bfill.html#pandas.core.groupby.DataFrameGroupBy.bfill)\(\[limit\]\) | Backward fill the values. | +| [`DataFrameGroupBy.corr`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corr.html#pandas.core.groupby.DataFrameGroupBy.corr) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrameGroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.count.html#pandas.core.groupby.DataFrameGroupBy.count)\(\) | Compute count of group, excluding missing values. | +| [`DataFrameGroupBy.cov`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cov.html#pandas.core.groupby.DataFrameGroupBy.cov) | Compute pairwise covariance of columns, excluding NA/null values. | +| [`DataFrameGroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumcount.html#pandas.core.groupby.DataFrameGroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | +| [`DataFrameGroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummax.html#pandas.core.groupby.DataFrameGroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | +| [`DataFrameGroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummin.html#pandas.core.groupby.DataFrameGroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | +| [`DataFrameGroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumprod.html#pandas.core.groupby.DataFrameGroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | +| [`DataFrameGroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumsum.html#pandas.core.groupby.DataFrameGroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | +| [`DataFrameGroupBy.describe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.describe.html#pandas.core.groupby.DataFrameGroupBy.describe)\(\*\*kwargs\) | Generate descriptive statistics. | +| [`DataFrameGroupBy.diff`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.diff.html#pandas.core.groupby.DataFrameGroupBy.diff) | First discrete difference of element. | +| [`DataFrameGroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.ffill.html#pandas.core.groupby.DataFrameGroupBy.ffill)\(\[limit\]\) | Forward fill the values. | +| [`DataFrameGroupBy.fillna`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.fillna.html#pandas.core.groupby.DataFrameGroupBy.fillna) | Fill NA/NaN values using the specified method. | +| [`DataFrameGroupBy.filter`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.filter.html#pandas.core.groupby.DataFrameGroupBy.filter)\(func\[, dropna\]\) | Return a copy of a DataFrame excluding filtered elements. | +| [`DataFrameGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.hist.html#pandas.core.groupby.DataFrameGroupBy.hist) | Make a histogram of the DataFrame’s. | +| [`DataFrameGroupBy.idxmax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmax.html#pandas.core.groupby.DataFrameGroupBy.idxmax) | Return index of first occurrence of maximum over requested axis. | +| [`DataFrameGroupBy.idxmin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmin.html#pandas.core.groupby.DataFrameGroupBy.idxmin) | Return index of first occurrence of minimum over requested axis. | +| [`DataFrameGroupBy.mad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.mad.html#pandas.core.groupby.DataFrameGroupBy.mad) | Return the mean absolute deviation of the values for the requested axis. | +| [`DataFrameGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.nunique.html#pandas.core.groupby.DataFrameGroupBy.nunique)\(\[dropna\]\) | Return DataFrame with counts of unique elements in each position. | +| [`DataFrameGroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pad.html#pandas.core.groupby.DataFrameGroupBy.pad)\(\[limit\]\) | Forward fill the values. | +| [`DataFrameGroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pct_change.html#pandas.core.groupby.DataFrameGroupBy.pct_change)\(\[periods, …\]\) | Calculate pct\_change of each value to previous entry in group. | +| [`DataFrameGroupBy.plot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.plot.html#pandas.core.groupby.DataFrameGroupBy.plot) | Class implementing the .plot attribute for groupby objects. | +| [`DataFrameGroupBy.quantile`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.quantile.html#pandas.core.groupby.DataFrameGroupBy.quantile)\(\[q, interpolation\]\) | Return group values at the given quantile, a la numpy.percentile. | +| [`DataFrameGroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.rank.html#pandas.core.groupby.DataFrameGroupBy.rank)\(\[method, ascending, …\]\) | Provide the rank of values within each group. | +| [`DataFrameGroupBy.resample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.resample.html#pandas.core.groupby.DataFrameGroupBy.resample)\(rule, \*args, \*\*kwargs\) | Provide resampling when using a TimeGrouper. | +| [`DataFrameGroupBy.sample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html#pandas.core.groupby.DataFrameGroupBy.sample)\(\[n, frac, replace, …\]\) | Return a random sample of items from each group. | +| [`DataFrameGroupBy.shift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.shift.html#pandas.core.groupby.DataFrameGroupBy.shift)\(\[periods, freq, …\]\) | Shift each group by periods observations. | +| [`DataFrameGroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.size.html#pandas.core.groupby.DataFrameGroupBy.size)\(\) | Compute group sizes. | +| [`DataFrameGroupBy.skew`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.skew.html#pandas.core.groupby.DataFrameGroupBy.skew) | Return unbiased skew over requested axis. | +| [`DataFrameGroupBy.take`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.take.html#pandas.core.groupby.DataFrameGroupBy.take) | Return the elements in the given _positional_ indices along an axis. | +| [`DataFrameGroupBy.tshift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.tshift.html#pandas.core.groupby.DataFrameGroupBy.tshift) | \(DEPRECATED\) Shift the time index, using the index’s frequency if available. | + +The following methods are available only for `SeriesGroupBy` objects. + +| [`SeriesGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.hist.html#pandas.core.groupby.SeriesGroupBy.hist) | Draw histogram of the input series using matplotlib. | +| :--- | :--- | +| [`SeriesGroupBy.nlargest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nlargest.html#pandas.core.groupby.SeriesGroupBy.nlargest) | Return the largest n elements. | +| [`SeriesGroupBy.nsmallest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nsmallest.html#pandas.core.groupby.SeriesGroupBy.nsmallest) | Return the smallest n elements. | +| [`SeriesGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nunique.html#pandas.core.groupby.SeriesGroupBy.nunique)\(\[dropna\]\) | Return number of unique elements in the group. | +| [`SeriesGroupBy.unique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.unique.html#pandas.core.groupby.SeriesGroupBy.unique) | Return unique values of Series object. | +| [`SeriesGroupBy.value_counts`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.value_counts.html#pandas.core.groupby.SeriesGroupBy.value_counts)\(\[normalize, …\]\) | | +| [`SeriesGroupBy.is_monotonic_increasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing) | Alias for is\_monotonic. | +| [`SeriesGroupBy.is_monotonic_decreasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing) | Return boolean if values in the object are monotonic\_decreasing. | + +The following methods are available only for `DataFrameGroupBy` objects. + +| [`DataFrameGroupBy.corrwith`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corrwith.html#pandas.core.groupby.DataFrameGroupBy.corrwith) | Compute pairwise correlation. | +| :--- | :--- | +| [`DataFrameGroupBy.boxplot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.boxplot.html#pandas.core.groupby.DataFrameGroupBy.boxplot)\(\[subplots, column, …\]\) | Make box plots from DataFrameGroupBy data. | + diff --git a/api-reference copy/groupby/README.md b/api-reference copy/groupby/README.md new file mode 100644 index 0000000..9a1db65 --- /dev/null +++ b/api-reference copy/groupby/README.md @@ -0,0 +1,34 @@ +--- +description: 'GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby()' +--- + +# Groupby + +### Indexing, iteration + +| | | +| :--- | :--- | +| [`GroupBy.get_group`](groupby.get_groups.md) | Construct DataFrame from group with provided name. | + +### Function application + +| | | +| :--- | :--- | +| [`GroupBy.agg`](groupby.agg.md) | Aggregate using one or more operations over the specified axis. | + +### Computations / descriptive stats + +| | | +| :--- | :--- | +| [`GroupBy.count`](groupby.count.md) | Compute count of group, excluding missing values. | +| [`GroupBy.cummax`](groupby.cummax.md) | Cumulative max for each group. | +| [`GroupBy.cummin`](groupby.cummin.md) | Cumulative min for each group. | +| [`GroupBy.cumprod`](groupby.cumprod.md) | Cumulative product for each group. | +| [`GroupBy.cumsum`](groupby.cumsum.md) | Cumulative sum for each group. | +| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max) | Compute max of group values. | +| [`GroupBy.mean`](groupby.mean.md) | Compute mean of groups, excluding missing values. | +| [`GroupBy.min`](groupby.min.md) | Compute min of group values. | +| [`GroupBy.std`](groupby.std.md) | Compute standard deviation of groups, excluding missing values. | +| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum) | Compute sum of group values. | +| [`GroupBy.var`](groupby.var.md) | Compute variance of groups, excluding missing values. | + diff --git a/api-reference copy/groupby/groupby.agg.md b/api-reference copy/groupby/groupby.agg.md new file mode 100644 index 0000000..fae8802 --- /dev/null +++ b/api-reference copy/groupby/groupby.agg.md @@ -0,0 +1,93 @@ +--- +description: Obtain data aggregate per groups for each column +--- + +# Groupby.agg + +> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | +| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | + +**Return:** DataFrame + +**Examples** + +Using mean and sum aggregate + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.agg({"C":"mean","D":"sum"}).print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... │ 27 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Mean and Sum aggregate on dataframe groupby two column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.agg({"C":"mean","D":"sum"}).print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference copy/groupby/groupby.apply.md b/api-reference copy/groupby/groupby.apply.md new file mode 100644 index 0000000..2150a21 --- /dev/null +++ b/api-reference copy/groupby/groupby.apply.md @@ -0,0 +1,84 @@ +--- +description: Apply custom aggregate function to grouped data +--- + +# Groupby.apply + +danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function \| function to be applied to grouped data | Undefined | | + +**Returns:** + + ****return **DataFrame** + +## **Examples** + +Using apply to create a custom function that subtract the minimum value of each grouped data from each of its values + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + 'A': ['foo', 'bar', 'foo', 'bar', + + 'foo', 'bar', 'foo', 'foo'], + + 'B': ['one', 'one', 'two', 'three', + + 'two', 'two', 'one', 'three'], + + 'C': [1, 3, 2, 4, 5, 2, 6, 7], + + 'D': [3, 2, 4, 1, 5, 6, 7, 8] + }; +let df = new dfd.DataFrame(data); +let group_df = df.groupby(["A", "B"]); + +const subMin = (x) => { + return x.sub(x.min()); +}; + +group_df.apply(subMin).print(); + +``` +{% endtab %} + +{% tab title="Browser" %} +``` + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_apply │ D_apply ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 5 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 3 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +\*\*\*\* diff --git a/api-reference copy/groupby/groupby.col.md b/api-reference copy/groupby/groupby.col.md new file mode 100644 index 0000000..02e7cdd --- /dev/null +++ b/api-reference copy/groupby/groupby.col.md @@ -0,0 +1,105 @@ +--- +description: Obtain the column(s) per groups +--- + +# Groupby.col + +> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| col\_names | Array | List of column | | + +Returns: Groupby Data structure + +Note: This is similar to pandas `df.groupby(["column"])["col_names"]` + +**Examples** + +Obtain a column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]) + +//for more coumns +grp.col(["C","D"]) +``` +{% endtab %} +{% endtabs %} + +Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. + +```text +//it returns the groupby data structure +GroupBy { + key_col: [ 'A' ], + col_dict: { + foo: [ [Array], [Array], [Array], [Array], [Array] ], + bar: [ [Array], [Array], [Array] ] + }, + data: [ + [ 'foo', 'one', 1, 3 ], + [ 'bar', 'one', 3, 2 ], + [ 'foo', 'two', 2, 4 ], + [ 'bar', 'three', 4, 1 ], + [ 'foo', 'two', 5, 5 ], + [ 'bar', 'two', 2, 6 ], + [ 'foo', 'one', 6, 7 ], + [ 'foo', 'three', 7, 8 ] + ], + column_name: [ 'A', 'B', 'C', 'D' ], + data_tensors: { + foo: DataFrame { + kwargs: [Object], + series: false, + data: [Array], + row_data_tensor: [Tensor], + index_arr: [Array], + columns: [Array], + col_data: [Array], + col_data_tensor: [Tensor], + col_types: [Array], + A: [Getter/Setter], + B: [Getter/Setter], + C: [Getter/Setter], + D: [Getter/Setter] + }, + bar: DataFrame { + kwargs: [Object], + series: false, + data: [Array], + row_data_tensor: [Tensor], + index_arr: [Array], + columns: [Array], + col_data: [Array], + col_data_tensor: [Tensor], + col_types: [Array], + A: [Getter/Setter], + B: [Getter/Setter], + C: [Getter/Setter], + D: [Getter/Setter] + } + }, + group_col_name: [ 'C' ], + group_col: { foo: [ [Series] ], bar: [ [Series] ] } +} +``` + + + diff --git a/api-reference copy/groupby/groupby.count.md b/api-reference copy/groupby/groupby.count.md new file mode 100644 index 0000000..36733be --- /dev/null +++ b/api-reference copy/groupby/groupby.count.md @@ -0,0 +1,175 @@ +--- +description: Count the occurrence of values in columns per groups +--- + +# Groupby.count + +> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the variance of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_count ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_count │ D_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).count().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).count().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count │ D_count ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 1 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.cummax.md b/api-reference copy/groupby/groupby.cummax.md new file mode 100644 index 0000000..8231a61 --- /dev/null +++ b/api-reference copy/groupby/groupby.cummax.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cummulative max per groups for each column +--- + +# Groupby.cummax + +> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative max of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cummax().head().print() +grp.col(["C"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + +Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 5 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 4 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cummax().head().print() +grp.col(["C","D"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummax │ D_cummax ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 4 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 4 │ 6 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 4 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 4 │ 6 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummax for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cummax().head().print() +grp.col(["C"]).cummax().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummax for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cummax().head().print() +grp.col(["C","D"]).cummax().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummax │ D_cummax ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference copy/groupby/groupby.cummin.md b/api-reference copy/groupby/groupby.cummin.md new file mode 100644 index 0000000..7fd9ed6 --- /dev/null +++ b/api-reference copy/groupby/groupby.cummin.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cummulative minimum per groups for each column +--- + +# Groupby.cummin + +> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative min of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 2 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 2 │ 1 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference copy/groupby/groupby.cumprod.md b/api-reference copy/groupby/groupby.cumprod.md new file mode 100644 index 0000000..af46123 --- /dev/null +++ b/api-reference copy/groupby/groupby.cumprod.md @@ -0,0 +1,258 @@ +--- +description: Obtain the cumulative product per group for each column +--- + +# Groupby.cumprod + +> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative product of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + +Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 │ 420 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 │ 3360 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 24 │ 12 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 24 │ 12 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() + +``` +{% endtab %} +{% endtabs %} + +```text + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 21 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference copy/groupby/groupby.cumsum.md b/api-reference copy/groupby/groupby.cumsum.md new file mode 100644 index 0000000..3b2b0e6 --- /dev/null +++ b/api-reference copy/groupby/groupby.cumsum.md @@ -0,0 +1,259 @@ +--- +description: Obtain the cumulative sum per groups for each column +--- + +# Groupby.cumsum + +> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative sum of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + +Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 │ 19 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 │ 27 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 9 │ 9 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 9 │ 9 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.get_groups.md b/api-reference copy/groupby/groupby.get_groups.md new file mode 100644 index 0000000..0cdf912 --- /dev/null +++ b/api-reference copy/groupby/groupby.get_groups.md @@ -0,0 +1,129 @@ +--- +description: Obtain the data for each element of the groupby column +--- + +# Groupby.get\_groups + +> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] + +| Parameters | Type | Description | default | +| :--- | :--- | :--- | :--- | +| key | Array | element of the groupby column | | + +**Returns**: DataFrame + +**Example** + +Group the dataframe by column A and obtain the group belonging to the values in column A + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) + +grp.get_groups(["foo"]).print() + +grp.get_groups(["bar"]).print() +``` +{% endtab %} +{% endtabs %} + +```text +//get groups for key "foo" + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get groups for key "bar" + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ three │ 4 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) + +grp.get_groups(["foo","one"]).print() + +grp.get_groups(["bar","one"]).print() +``` +{% endtab %} +{% endtabs %} + +```text +//get_groups(["foo","one"] + + + Shape: (2,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get_groups(["bar","one"]) + + + Shape: (1,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + diff --git a/api-reference copy/groupby/groupby.max.md b/api-reference copy/groupby/groupby.max.md new file mode 100644 index 0000000..43470f6 --- /dev/null +++ b/api-reference copy/groupby/groupby.max.md @@ -0,0 +1,170 @@ +--- +description: Obtain the maximum value of columns per groups +--- + +# Groupby.max + +> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] + +**Parameters:** None + +**Returns**: DataFrame + +**Example** + +Obtain the maximum value for a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_max ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_max │ D_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 4 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).max().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_max │ D_max ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference copy/groupby/groupby.mean.md b/api-reference copy/groupby/groupby.mean.md new file mode 100644 index 0000000..add6958 --- /dev/null +++ b/api-reference copy/groupby/groupby.mean.md @@ -0,0 +1,173 @@ +--- +description: Obtain the mean per groups for each column(s) +--- + +# Groupby.mean + +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the mean of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ D_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.19999980926... │ 5.40000009536... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the mean for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).mean().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean │ D_mean ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 │ 4.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.min.md b/api-reference copy/groupby/groupby.min.md new file mode 100644 index 0000000..0151e64 --- /dev/null +++ b/api-reference copy/groupby/groupby.min.md @@ -0,0 +1,171 @@ +--- +description: Obtain the minimum value per groups for a coumn(s) +--- + +# Groupby.min + +> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the minimum value for a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_min ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the minimum value for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_min │ D_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 2 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the maximum value for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).min().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min │ D_min ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.std.md b/api-reference copy/groupby/groupby.std.md new file mode 100644 index 0000000..c792a8e --- /dev/null +++ b/api-reference copy/groupby/groupby.std.md @@ -0,0 +1,175 @@ +--- +description: Obtain the standard deviation per groups for specified columns +--- + +# Groupby.std + +> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the standard deviation of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_std ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 2.58843582110... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_std │ D_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 2.58843582110... │ 2.07364413533... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 │ 2.64575131106... ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).std().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.53553390593... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2.12132034355... ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the std for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).std().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_std │ D_std ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.53553390593... │ 2.82842712474... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2.12132034355... │ 0.70710678118... ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.sum.md b/api-reference copy/groupby/groupby.sum.md new file mode 100644 index 0000000..f6f2900 --- /dev/null +++ b/api-reference copy/groupby/groupby.sum.md @@ -0,0 +1,172 @@ +--- +description: Obtain the sum per groups for columns +--- + +# Groupby.sum + +> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the sum of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_sum ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 21 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_sum │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 21 │ 27 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 9 │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the sum for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).sum().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum │ D_sum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 7 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/groupby/groupby.var.md b/api-reference copy/groupby/groupby.var.md new file mode 100644 index 0000000..373109f --- /dev/null +++ b/api-reference copy/groupby/groupby.var.md @@ -0,0 +1,175 @@ +--- +description: Obtain the variance per groups for a specified column +--- + +# Groupby.var + +> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the variance of a column for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.col(["C"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (2,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_var ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 6.7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (2,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_var │ D_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 6.7 │ 4.3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 1 │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).var().print() + +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 12.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 4.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the var for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).var().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_var │ D_var ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 12.5 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 4.5 │ 0.5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 0 │ 0 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ two │ 0 │ 0 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference copy/input-output/README.md b/api-reference copy/input-output/README.md new file mode 100644 index 0000000..e86d5de --- /dev/null +++ b/api-reference copy/input-output/README.md @@ -0,0 +1,18 @@ +--- +description: Functions for reading tabular/structured data into DataFrame/Series Objects +--- + +# Input/Output + +## CSV + +| \`\` | | +| ----------------------------------- | -------------------------------------------------------- | +| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | +| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | +| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | +| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | +| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | + +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference copy/input-output/danfo.read_csv.md b/api-reference copy/input-output/danfo.read_csv.md new file mode 100644 index 0000000..a291533 --- /dev/null +++ b/api-reference copy/input-output/danfo.read_csv.md @@ -0,0 +1,134 @@ +--- +description: >- + Reads a comma-separated values (CSV) file into DataFrame. Also supports the + reading of CSV files in chunks. +--- + +# danfo.read\_csv + +> danfo.**read\_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] + +| | | | | +| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | +| **configs**: | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

dynamicTyping: true,

header: true

}

| + +**Returns:** + +\*\* \*\*_**Promise**_. Resolves to DataFrame + +The **read\_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. + +### **Reading files from local disk** + +By specifying a valid file path, you can load CSV files from local disk: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_csv("./user_names.csv") //assumes file is in CWD + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading files from a URL** + +By specifying a valid URL, you can load CSV files from any location into Danfo\*\*'\*\*s data structure: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + +
+ + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/input-output/danfo.read_excel.md b/api-reference copy/input-output/danfo.read_excel.md new file mode 100644 index 0000000..459aa30 --- /dev/null +++ b/api-reference copy/input-output/danfo.read_excel.md @@ -0,0 +1,68 @@ +--- +description: Reads an excel file into DataFrame. +--- + +# danfo.read_excel + +> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] + +| Parameters | Type | Description | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| source | string | **source** : string, URL or local file path to retreive Excel file. | +| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| + +> **Returns:** +> +> ** **return** **{**Promise**} DataFrame structure of parsed Excel data + +### Example + +The **read_excel** method can read excel files saved on a local disk, or over the internet. + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") +const path = require("path") + +let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") + +async function load_process_data() { + let df = await dfd.read_excel(local_xcel) + df.head().print() +} + +load_process_data() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/input-output/danfo.read_json.md b/api-reference copy/input-output/danfo.read_json.md new file mode 100644 index 0000000..3c17457 --- /dev/null +++ b/api-reference copy/input-output/danfo.read_json.md @@ -0,0 +1,127 @@ +--- +description: Reads a JSON file into DataFrame. +--- + +# danfo.read\_json + +> danfo.**read\_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] + +| | | | | +| -------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**source**_ | Input file object, string file\*\* \*\*path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | +| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| + +**Returns:** + +\*\* \*\*_**Promise**_. Resolves to DataFrame + +The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. + +### **Reading JSON files from local disk** + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("./user_names.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} +{% endtabs %} + +### **Reading JSON files from a URL** + +By specifying a valid URL, you can load JSON files from any location: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") + .then(df => { + + df.head().print() + + }).catch(err=>{ + console.log(err); + }) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### **Reading an input file object in the browser** + +By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: + +{% tabs %} +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/input-output/danfo.to_csv.md b/api-reference copy/input-output/danfo.to_csv.md new file mode 100644 index 0000000..c3403cf --- /dev/null +++ b/api-reference copy/input-output/danfo.to_csv.md @@ -0,0 +1,115 @@ +--- +description: Writes a DataFrame or Series to CSV format. +--- + +# danfo.to\_csv + +> danfo.**to\_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] + +| | | | | +| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| + +The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. + +### Convert DataFrame to CSV string and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const csv = dfd.to_csv(df, { download: false }); +console.log(csv); + +//output +Abs,Count,country code +20.2,34,NG +30,4,FR +47.3,5,GH +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and write to file path + +Writing a CSV file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_csv(df, { filePath: "testOut.csv"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to CSV string and download file in Client-side lib + +You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +const dfd = require("danfojs") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_csv(df, { fileName: "testOut.csv", download: true}); +``` diff --git a/api-reference copy/input-output/danfo.to_excel.md b/api-reference copy/input-output/danfo.to_excel.md new file mode 100644 index 0000000..1fe1adf --- /dev/null +++ b/api-reference copy/input-output/danfo.to_excel.md @@ -0,0 +1,54 @@ +--- +description: >- + Converts a DataFrame or Series to Excel file and write file to disk or + download in browser. +--- + +# danfo.to_excel + +> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] + +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| + +The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. + +### Convert DataFrame to Excel and write to file path + +Writing an Excel file to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_excel(df, { filePath: "testOut.xlsx"}); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame to Excel and download the file in Client-side lib + +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_excel(df, { fileName: "testOut.xlsx"}); +``` diff --git a/api-reference copy/input-output/danfo.to_json.md b/api-reference copy/input-output/danfo.to_json.md new file mode 100644 index 0000000..baac615 --- /dev/null +++ b/api-reference copy/input-output/danfo.to_json.md @@ -0,0 +1,124 @@ +# danfo.to\_json + +> danfo.**to\_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] + +| | | | | +| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| + +The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. + +### Convert DataFrame/Series to JSON and return value + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +const jsonObj = dfd.to_json(df, { download: false }); //column format +console.log(jsonObj); + +//output +[ + { Abs: 20.2, Count: 34, 'country code': 'NG' }, + { Abs: 30, Count: 4, 'country code': 'FR' }, + { Abs: 47.3, Count: 5, 'country code': 'GH' } +] + +//row format +const jsonObj = dfd.to_json(df, { + download: false, + format: "row" +}); + +console.log(jsonObj); +//output +{ + Abs: [ 20.2, 30, 47.3 ], + Count: [ 34, 4, 5 ], + 'country code': [ 'NG', 'FR', 'GH' ] +} +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and write to file path + +Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_json(df, { filePath: "./testOutput.json" }); +``` +{% endtab %} +{% endtabs %} + +### Convert DataFrame/Series to JSON and download file in browser + +You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. + +```javascript +let data = { + Abs: [20.2, 30, 47.3], + Count: [34, 4, 5], + "country code": ["NG", "FR", "GH"], +}; + +let df = new dfd.DataFrame(data); + +dfd.to_json(df, { fileName: "test_out.json" }); +``` diff --git a/api-reference copy/input-output/read.md b/api-reference copy/input-output/read.md new file mode 100644 index 0000000..c38778e --- /dev/null +++ b/api-reference copy/input-output/read.md @@ -0,0 +1,138 @@ +--- +description: >- + The generic read function loads a tabular data using the Frictionless + specification. +--- + +# read + +> danfo.**read**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters + TypeDescriptionDefault
source + stringA path to the file/resources. It can be a local file, a URL to tabular + data (CSV, EXCEL) or Datahub.io Data Resource.
configs + object +

+

Configuration options. Supported params are:

+

data_num (Defaults => 0): The specific dataset to load, when + reading data from a datapackage.json,

+

header (Defaults => true): Whether the dataset contains a header + or not.

+

sheet (Defaults => 0): Number of the excel sheet which u want + to load.

+

}

+
+ +**Returns:** + + ****_**Promise**_. Resolves to DataFrame + +The **read** function uses [frictionless.js](https://github.com/frictionlessdata/frictionless-js) underhood.[`frictionless.js`](https://github.com/frictionlessdata/frictionless-js) is a lightweight, standardized "stream-plus-metadata" interface for accessing files and datasets, especially tabular ones \(CSV, Excel\). It follows the [Frictionless spec](https://frictionlessdata.io/specs/) + +> ### **Note**: The `read` method is only available in danfojs-node at the moment. + +### Read a CSV file + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let df = await dfd.read("file.csv") + let sample = await df.sample(10) + sample.print() +} + +load_data() +``` +{% endtab %} +{% endtabs %} + +### **Loading Files from URL** + +By specifying a valid URL, you can load CSV/EXCEL file: + +{% tabs %} +{% tab title="Node.js" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let df = await dfd.read("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") + df.head().print() +} + +load_data() +``` +{% endtab %} +{% endtabs %} + +### Loading Data from a Data Package Descriptor + +You can load data from a frictionless data package [descriptor](https://specs.frictionlessdata.io/data-package/#descriptor). A data package descriptor is a central file in a Data Package. It is a JSON file that provides: + +* General metadata such as the package’s title, license, publisher etc +* A list of the data “resources” that make up the package including their location on disk or online and other relevant information \(including, possibly, schema information about these data resources in a structured form\) + +For instance, in the example below, we load the first resource in the [Natural Gas dataset](https://datahub.io/core/natural-gas) from datahub.io. + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + const package_url = + "https://datahub.io/core/natural-gas/datapackage.json"; + + const df = await dfd.read(package_url, { data_num: 1 }); + df.head().print(); + +load_data() +``` +{% endtab %} +{% endtabs %} + +```bash +╔═══╤═══════════════════╤═══════════════════╗ +║ │ Date │ Price ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ 1997-01-07 │ 3.81999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ 1997-01-08 │ 3.79999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ 1997-01-09 │ 3.60999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ 1997-01-10 │ 3.91999999999... ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ 1997-01-13 │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + + + diff --git a/api-reference copy/plotting/README.md b/api-reference copy/plotting/README.md new file mode 100644 index 0000000..93161e3 --- /dev/null +++ b/api-reference copy/plotting/README.md @@ -0,0 +1,19 @@ +--- +description: >- + DataFrame and Series have inbuilt support for plotting using Plotly's backend. + All customization can be done using Plotly's parameter passed to the config + object. +--- + +# Plotting + +* [Line Charts](line-charts.md) +* [Bar Charts](bar-charts.md) +* [Scatter Plots](scatter-plots.md) +* [Histograms](histograms.md) +* [Pie Charts](pie-charts.md) +* [Tables](tables.md) +* [Box Plots](box-plots.md) +* [Violin Plots](violin-plots.md) +* [Timeseries Plots](timeseries-plots.md) + diff --git a/api-reference copy/plotting/bar-charts.md b/api-reference copy/plotting/bar-charts.md new file mode 100644 index 0000000..6606bdc --- /dev/null +++ b/api-reference copy/plotting/bar-charts.md @@ -0,0 +1,75 @@ +--- +description: Makes a vertical bar plot. +--- + +# Bar Charts + +A bar plot presents categorical data with rectangular bars with lengths proportional to the values that they represent. + +## Examples + +The **bar** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. + +### Bar plot on Series + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (6).png>) + +### Bar plot on DataFrame + +```markup + + + + + + + + + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (7).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/plotting/box-plots.md b/api-reference copy/plotting/box-plots.md new file mode 100644 index 0000000..2adb60a --- /dev/null +++ b/api-reference copy/plotting/box-plots.md @@ -0,0 +1,116 @@ +--- +description: Make a box plot from DataFrame columns. +--- + +# Box Plots + +Make a box-and-whisker plot from DataFrame columns, optionally grouped by some other columns. A box plot is a method for graphically depicting groups of numerical data through their quartiles. + +## Examples + +### Boxplot for a Series Object + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (23).png>) + +### Box plots on a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) + +### Box plot for selected columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (24).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/plotting/configuring-your-plots.md b/api-reference copy/plotting/configuring-your-plots.md new file mode 100644 index 0000000..4cedbb2 --- /dev/null +++ b/api-reference copy/plotting/configuring-your-plots.md @@ -0,0 +1,68 @@ +# Configuring your plots + +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. + +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. + +For example in the following code, we show how to set some basic configuration as well as layout for a line plot. + +```markup + + + + + + + + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (32).png>) diff --git a/api-reference copy/plotting/histograms.md b/api-reference copy/plotting/histograms.md new file mode 100644 index 0000000..adabd84 --- /dev/null +++ b/api-reference copy/plotting/histograms.md @@ -0,0 +1,117 @@ +--- +description: Draw one histogram of the DataFrame’s columns, or single histogram for Series +--- + +# Histograms + +A histogram is a representation of the distribution of data. This function groups the values of all given Series in the DataFrame into bins + +## Examples + +### Histogram of a Column in a DataFrame + +In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (10).png>) + +### Customized Histogram plots on DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (20).png>) + +### Configuring your plots + +danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. + +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: + +```javascript +var layout = { + title: 'A sample plot', + xaxis: { + title: 'X', + }, + yaxis: { + title: 'Y', + } +} + +df.plot("div_tag").histogram({layout: layout}) +``` + +{% hint style="info" %} +For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. +{% endhint %} diff --git a/api-reference copy/plotting/line-charts.md b/api-reference copy/plotting/line-charts.md new file mode 100644 index 0000000..79fe4d3 --- /dev/null +++ b/api-reference copy/plotting/line-charts.md @@ -0,0 +1,109 @@ +--- +description: >- + Plot Series or DataFrame as lines. This function is useful to plot lines using + DataFrame’s values as coordinates. +--- + +# Line Charts + +## Examples + +### Basic Line plot on Series + +The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (4).png>) + +### Line plots on DataFrame + +The example below shows the plot of column values against a common x-axis (index) + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (2).png>) + +The example below shows how to plot two columns in a DataFrame against each other. + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (3).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/plotting/pie-charts.md b/api-reference copy/plotting/pie-charts.md new file mode 100644 index 0000000..6dce73d --- /dev/null +++ b/api-reference copy/plotting/pie-charts.md @@ -0,0 +1,123 @@ +--- +description: Generate a pie plot. +--- + +# Pie Charts + +A pie plot is a proportional representation of the numerical data in a column + +## Examples + +### Pie Chart from Columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (12).png>) + +### Multiple Pie Chart from Columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (21).png>) + +### Configure Position of Pie Charts + +If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (22).png>) + +{% hint style="info" %} +For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. +{% endhint %} diff --git a/api-reference copy/plotting/scatter-plots.md b/api-reference copy/plotting/scatter-plots.md new file mode 100644 index 0000000..77649d1 --- /dev/null +++ b/api-reference copy/plotting/scatter-plots.md @@ -0,0 +1,88 @@ +--- +description: Create a scatter plot of columns in a DataFrame +--- + +# Scatter Plots + +The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. + +## Examples + +### Scatter Plots on Columns in a DataFrame + +In the example below, we use the titanic dataset, to show a close to real-world use case of danfo.js + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot-8- (1) (1).png>) + +### More Examples + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (19).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/plotting/tables.md b/api-reference copy/plotting/tables.md new file mode 100644 index 0000000..c67f0e2 --- /dev/null +++ b/api-reference copy/plotting/tables.md @@ -0,0 +1,95 @@ +--- +description: Turn DataFrame/Series in D3.js-based tables +--- + +# Tables + +## Examples + +### Create Interactive Tables from DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) + +### Configure the header and cell of a table + +To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. + +```markup + + + + + + + + + Document + + + + +
+ + + + + +``` + +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference copy/plotting/timeseries-plots.md b/api-reference copy/plotting/timeseries-plots.md new file mode 100644 index 0000000..7bbb089 --- /dev/null +++ b/api-reference copy/plotting/timeseries-plots.md @@ -0,0 +1,58 @@ +--- +description: Timeseries plot are based on date index +--- + +# Timeseries Plots + +## Examples + +In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot-29- (2) (1).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/plotting/violin-plots.md b/api-reference copy/plotting/violin-plots.md new file mode 100644 index 0000000..a3e6c11 --- /dev/null +++ b/api-reference copy/plotting/violin-plots.md @@ -0,0 +1,112 @@ +# Violin Plots + +Make a violin plot from DataFrame columns, optionally grouped by some other columns. A violin plot is a method for graphically depicting groups of numerical data through their quartiles. See also [Box Plot](box-plots.md) + +## Examples + +### Boxplot for a Series Object + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (25).png>) + +### Box plots on a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (26).png>) + +### Box plot for selected columns in a DataFrame + +```markup + + + + + + + + + Document + + + + +
+ + + + +``` + +![](<../../.gitbook/assets/newplot (27).png>) + +{% hint style="info" %} +To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +{% endhint %} diff --git a/api-reference copy/series/README.md b/api-reference copy/series/README.md new file mode 100644 index 0000000..421bc63 --- /dev/null +++ b/api-reference copy/series/README.md @@ -0,0 +1,182 @@ +--- +description: One-dimensional ndarray with axis labels (including time series). +--- + +# Series + +> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ], **index:** \[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] + +### Attributes + +| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | +| --------------------------------- | ------------------------------------------- | + +| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | +| ----------------------------------- | ---------------------------------------------------------------- | +| [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | +| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | +| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | +| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | +| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | + +### Conversion + +| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | +| --------------------------------------------------- | ---------------------------------------------- | +| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | + +### Indexing, iteration + +| | | +| ------------------------------------------------------- | ------------------------------------------------------------------ | +| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | +| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | + +### Binary operator functions + +| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | +| --------------------------------- | --------------------------------------------------------------------------------------- | +| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | +| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | +| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | +| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | +| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | +| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | +| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | +| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | +| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | +| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | +| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | +| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | +| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | + +### Function application & GroupBy + +| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | +| --------------------------------- | ------------------------------------------------------- | +| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | + +### Computations / descriptive stats + +| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | +| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | +| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | +| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | +| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | +| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | +| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | +| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | +| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | +| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | +| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | +| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | +| [`Series.unique`](series.unique.md) | Return unique values of Series object. | +| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | +| [`Series.value_counts`](series.value\_counts.md) | Return a Series containing counts of unique values. | + +### Reindexing / selection / label manipulation + +| | | +| ------------------------------------------------------ | -------------------------------------------------------- | +| [`Series.drop_duplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | +| [`Series.head`](series.head.md) | Return the first n rows. | +| [`Series.reset_index`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | +| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | +| [`Series.tail`](series.tail.md) | Return the last n rows. | + +### Missing data handling + +| | | +| ------------------------------------- | ------------------------------------------------ | +| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | +| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | +| [`Series.isna`](series.isna.md) | Detect missing values. | +| [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | + +### Reshaping, sorting + +| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | +| ---------------------------------------------- | ------------------------------------------------------------- | +| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | +| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | +| [`Series.sort_values`](series.sort\_values.md) | Sort by the values. | + +### Accessors + +Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. + +| Data Type | Accessor | +| --------- | -------- | +| Datetime | dt | +| String | str | + +#### Datetimelike properties + +`Series.dt` can be used to access the values of the series as datetime and return several properties. These can be accessed like `Series.dt.`. + +**Datetime methods** + +| | | +| -------------------------------------------------- | ------------------------------------------------------------------ | +| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | +| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | +| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | +| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | +| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | +| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | +| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | +| [`Series.dt.month_name`](series.dt.month\_name.md) | Return the month names of the DateTimeIndex with specified locale. | + +#### String handling + +`Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. + +| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | +| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | +| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | +| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | +| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | +| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | +| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | +| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | +| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | +| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | +| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | +| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | +| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | +| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | +| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | +| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | +| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | +| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | +| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | + +### Plotting + +`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. + +| | | +| ----------------------------------------------------- | ------------------------------------------------------------- | +| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | +| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | +| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | +| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | +| [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | +| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | +| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | +| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | + +### Serialization / IO / conversion + +| | | +| ------------------------------------------------------ | ---------------------------------------------------- | +| [`Series.to_csv`](../dataframe/dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | +| [`Series.to_json`](../dataframe/dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference copy/series/creating-a-series.md b/api-reference copy/series/creating-a-series.md new file mode 100644 index 0000000..3c8e4ba --- /dev/null +++ b/api-reference copy/series/creating-a-series.md @@ -0,0 +1,210 @@ +# Creating a Series + +new danfo.**Series**\(data, options\) + + + + + + + + + + + + + + + + + + + + + +
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject +

Optional configuration object. Supported properties are: +
+

+

index: Array of numeric or string names for subseting array. If + not specified, indexes are auto-generated. +
+

+

dtypes: Array of data types for each the column. If not specified, + dtypes are/is inferred. +
+

+

config: General configuration object for extending or setting NDframe + behavior. See full options here

+
+ +In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. + +### Creating a Series from an object: + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```javascript +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series from an array + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +obj_data = ["bval1", "bval2", "bval3", "bval4"] +df = new dfd.Series(obj_data) +df.print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══════╗ +║ 0 │ bval1 ║ +╟───┼───────╢ +║ 1 │ bval2 ║ +╟───┼───────╢ +║ 2 │ bval3 ║ +╟───┼───────╢ +║ 3 │ bval4 ║ +╚═══╧═══════╝ +``` + +### Creating a Series and specifying index and dtypes + +You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. + +> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2, 3, 4, 5]; +let index = ["a", "b", "c", "d", "e"]; +let dtypes = ["int32",] + +let df = new Series(data1, { index, dtypes }); +df.print() +``` +{% endtab %} +{% endtabs %} + +```text +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╚═══╧═══╝ +``` + +### Creating a Series and specifying memory mode + +To use less space on Series creation, you can set the low memory mode as demonstrated below: + +```javascript +import { Series } from "danfojs" + +let data1 = [1, 2.3, 3, 4, 5, "girl"]; + +let df = new Series(data1, { + config: { lowMemoryMode: true } +}); +df.print() +``` + +{% hint style="info" %} +**Note**: In low memory mode, less space is used by the Series. +{% endhint %} + diff --git a/api-reference copy/series/danfo.series.add.md b/api-reference copy/series/danfo.series.add.md new file mode 100644 index 0000000..7cd6150 --- /dev/null +++ b/api-reference copy/series/danfo.series.add.md @@ -0,0 +1,22 @@ +--- +description: 'Return Addition of series and other, element-wise (binary operator add).' +--- + +# danfo.Series.add + +Return Addition of series and other, element-wise \(binary operator add\). + + **parameter:** {other} Series or Number to add + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 6] +let data2 = [30, 40, 39, 1, 2, 1] +let sf = new Series(data) +let sf2 = new Series(data2) +sf.add(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.apply.md b/api-reference copy/series/danfo.series.apply.md new file mode 100644 index 0000000..d59a99c --- /dev/null +++ b/api-reference copy/series/danfo.series.apply.md @@ -0,0 +1,63 @@ +--- +description: invoke a function on Series Value +--- + +# danfo.Series.apply + +> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function | Function \(can be anonymous\) to apply | | + +**Returns:** + + ****return **Series** + +\*\*\*\* + +**Example** + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +let apply_func = (x) => { + return x + x +} +sf.apply(apply_func).print() +``` + +**OUTPUT:** + +![](../../.gitbook/assets/series_apply.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +sf.apply(Math.log).print() +``` + +**OUTPUT:** + +![](../../.gitbook/assets/series_apply1.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) + +sf.apply((x)=>{ + return x.toLocaleLowerCase() +}).print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_apply2.png) + + + diff --git a/api-reference copy/series/danfo.series.copy.md b/api-reference copy/series/danfo.series.copy.md new file mode 100644 index 0000000..c610c04 --- /dev/null +++ b/api-reference copy/series/danfo.series.copy.md @@ -0,0 +1,22 @@ +# danfo.Series.copy + +Make a new copy of Series + + + +**parameter:** + + **return:** {Series} + +**Example** + +```javascript +let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) +sf_copy = sf.copy() + + +let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) +sf = sf.set_index({ "index": ["a", "b", "c", "d"] }) +sf_copy = sf.copy() +``` + diff --git a/api-reference copy/series/danfo.series.count.md b/api-reference copy/series/danfo.series.count.md new file mode 100644 index 0000000..50a5789 --- /dev/null +++ b/api-reference copy/series/danfo.series.count.md @@ -0,0 +1,24 @@ +--- +description: Return the sum of the values in a series. +--- + +# danfo.Series.count + +Return number of non-NA/null observations in the Series. + +This is equivalent to the method numpy.sum + + **parameter:** + + **return:** {Number}, sum of values in Series + +**Example** + +```javascript +let data = ["boy", "gitl", "woman", NaN] +let sf = new Series(data) +sf.count() +``` + + + diff --git a/api-reference copy/series/danfo.series.describe.md b/api-reference copy/series/danfo.series.describe.md new file mode 100644 index 0000000..184dbe9 --- /dev/null +++ b/api-reference copy/series/danfo.series.describe.md @@ -0,0 +1,26 @@ +# danfo.Series.describe + + + +Generate descriptive statistics. Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding NaN values + + + +**parameter:** + + **return:** {frame} + +**Example** + +```javascript +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three"] }) + + +let data = [1,2,3,4,5,6] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +df.reset_index() +``` + diff --git a/api-reference copy/series/danfo.series.div.md b/api-reference copy/series/danfo.series.div.md new file mode 100644 index 0000000..ae2731b --- /dev/null +++ b/api-reference copy/series/danfo.series.div.md @@ -0,0 +1,26 @@ +--- +description: >- + Return Floating division of series and other, element-wise (binary operator + truediv). +--- + +# danfo.Series.div + +Return division of series and other, element-wise \(binary operator div\). + +Equivalent to series / other + + **parameter:** {other} Series, Number to divide with. + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.div(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.head.md b/api-reference copy/series/danfo.series.head.md new file mode 100644 index 0000000..1bc9d5e --- /dev/null +++ b/api-reference copy/series/danfo.series.head.md @@ -0,0 +1,25 @@ +--- +description: This function returns the first n rows for the object based on position. +--- + +# danfo.Series.head + + + +Prints the first n values in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let cols = ["A"] +let sf = new Series(data, { columns: cols }) +sf.head() +``` + + + diff --git a/api-reference copy/series/danfo.series.map.md b/api-reference copy/series/danfo.series.map.md new file mode 100644 index 0000000..9d7cad4 --- /dev/null +++ b/api-reference copy/series/danfo.series.map.md @@ -0,0 +1,42 @@ +--- +description: Map the value of a series to it representation +--- + +# danfo.Series.map + +> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] + +| Parameter | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| callable | Function or Object | callable can either be a function or an object\({}\) | | + +**Example** + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1,2,3,4]) +let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } +sf.map(map) + +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_map.png) + +```javascript +const dfd = require("danfojs") + +let sf = new dfd.Series([1,2,3,4]) + +sf.map((x)=>{ + return `I have ${x} cat(s)` +}).print() + +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_map1.png) + diff --git a/api-reference copy/series/danfo.series.max.md b/api-reference copy/series/danfo.series.max.md new file mode 100644 index 0000000..cac4ba1 --- /dev/null +++ b/api-reference copy/series/danfo.series.max.md @@ -0,0 +1,2 @@ +# danfo.Series.max + diff --git a/api-reference copy/series/danfo.series.maximum.md b/api-reference copy/series/danfo.series.maximum.md new file mode 100644 index 0000000..9082120 --- /dev/null +++ b/api-reference copy/series/danfo.series.maximum.md @@ -0,0 +1,22 @@ +# danfo.Series.maximum + +Return maximum of series and other, element-wise \(binary operator div\). + + + + **parameter:** {other} Series, Numbers to check maximum against + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.maximum(sf2) +``` + + + diff --git a/api-reference copy/series/danfo.series.mean.md b/api-reference copy/series/danfo.series.mean.md new file mode 100644 index 0000000..6ace487 --- /dev/null +++ b/api-reference copy/series/danfo.series.mean.md @@ -0,0 +1,2 @@ +# danfo.Series.mean + diff --git a/api-reference copy/series/danfo.series.median.md b/api-reference copy/series/danfo.series.median.md new file mode 100644 index 0000000..077c0ec --- /dev/null +++ b/api-reference copy/series/danfo.series.median.md @@ -0,0 +1,2 @@ +# danfo.Series.median + diff --git a/api-reference copy/series/danfo.series.min.md b/api-reference copy/series/danfo.series.min.md new file mode 100644 index 0000000..22f3589 --- /dev/null +++ b/api-reference copy/series/danfo.series.min.md @@ -0,0 +1,2 @@ +# danfo.Series.min + diff --git a/api-reference copy/series/danfo.series.minimum.md b/api-reference copy/series/danfo.series.minimum.md new file mode 100644 index 0000000..2a9d9c6 --- /dev/null +++ b/api-reference copy/series/danfo.series.minimum.md @@ -0,0 +1,22 @@ +# danfo.Series.minimum + + + +Return minimum of series and other, element-wise \(binary operator div\). + + + + **parameter:** {other} Series, Numbers to check minimum against + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.minimum(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.mod.md b/api-reference copy/series/danfo.series.mod.md new file mode 100644 index 0000000..577014d --- /dev/null +++ b/api-reference copy/series/danfo.series.mod.md @@ -0,0 +1,24 @@ +--- +description: 'Return Modulo of series and other, element-wise (binary operator mod).' +--- + +# danfo.Series.mod + +Return Modulo of series and other, element-wise \(binary operator mod\). + +Equivalent to series % other + + **parameter:** {other} Series, Number + + **return:** Series + +**Example** + +```javascript +let data1 = [2, 30, 4, 5] +let data2 = [1.1, 2.2, 3.3, 2.4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.mod(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.mode.md b/api-reference copy/series/danfo.series.mode.md new file mode 100644 index 0000000..8d86e6e --- /dev/null +++ b/api-reference copy/series/danfo.series.mode.md @@ -0,0 +1,2 @@ +# danfo.Series.mode + diff --git a/api-reference copy/series/danfo.series.mul.md b/api-reference copy/series/danfo.series.mul.md new file mode 100644 index 0000000..6cdac92 --- /dev/null +++ b/api-reference copy/series/danfo.series.mul.md @@ -0,0 +1,26 @@ +--- +description: 'Return Multiplication of series and other, element-wise (binary operator mul).' +--- + +# danfo.Series.mul + +Return Multiplication of series and other, element-wise \(binary operator mul\). + +Equivalent to series \* other, but with support to substitute a fill\_value for missing data in one of the inputs. + + **parameter:** {Series, Number to multiply with. + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.mul(sf2) +``` + + + diff --git a/api-reference copy/series/danfo.series.pow.md b/api-reference copy/series/danfo.series.pow.md new file mode 100644 index 0000000..291a993 --- /dev/null +++ b/api-reference copy/series/danfo.series.pow.md @@ -0,0 +1,26 @@ +--- +description: >- + Return Exponential power of series and other, element-wise (binary operator + pow). +--- + +# danfo.Series.pow + +Return Exponential power of series and other, element-wise \(binary operator pow\). + +Equivalent to series \*\* other + + **parameter:** {other} Series, Number to multiply with. + + **return:** Series + +**Example** + +```javascript +let data1 = [2, 3, 4, 5] +let data2 = [1, 2, 3, 0] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.pow(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.reset_index.md b/api-reference copy/series/danfo.series.reset_index.md new file mode 100644 index 0000000..7a908a9 --- /dev/null +++ b/api-reference copy/series/danfo.series.reset_index.md @@ -0,0 +1,31 @@ +# danfo.Series.reset\_index + + + +Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. + + + +**parameter:** {kwargs} {inplace: Modify the Series in place \(do not create a new object, drop: Just reset the index, without inserting it as a column in the new DataFrame.} + + **return:** {Series} + +**Example** + +```javascript +const dfd = require("danfojs") + +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["one", "two", "three"] }) +let df_reset = df_new.reset_index() +df_reset.print() + + +let data = [1,2,3,4,5,6] +let df = new Series(data) +df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) +let df_new = df.reset_index() +df_new +``` + diff --git a/api-reference copy/series/danfo.series.round.md b/api-reference copy/series/danfo.series.round.md new file mode 100644 index 0000000..2bbacbb --- /dev/null +++ b/api-reference copy/series/danfo.series.round.md @@ -0,0 +1,20 @@ +# danfo.Series.round + +Round each value in a Series to the given number of decimals. + + + + **parameter:** {dp} Number, Numbers of Decimal places to round to + + **return:** {Series} + +**Example** + +```javascript +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf = new Series(data1) +sf.round(1) +``` + + + diff --git a/api-reference copy/series/danfo.series.sample.md b/api-reference copy/series/danfo.series.sample.md new file mode 100644 index 0000000..fa8f326 --- /dev/null +++ b/api-reference copy/series/danfo.series.sample.md @@ -0,0 +1,22 @@ +--- +description: Return a random sample of items from an axis of object. +--- + +# danfo.Series.sample + +Gets \[num\] number of random rows in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf = new Series(data) +sf.sample(2) +``` + + + diff --git a/api-reference copy/series/danfo.series.set_index.md b/api-reference copy/series/danfo.series.set_index.md new file mode 100644 index 0000000..5cb3d28 --- /dev/null +++ b/api-reference copy/series/danfo.series.set_index.md @@ -0,0 +1,40 @@ +--- +description: Assign new Index to Series +--- + +# danfo.Series.set\_index + +> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| kwargs | Object {} | The object contains the key **index** and assigned an array value of equal length to the Series. format {"index": \[Array\] } | | + +**Example** + +```javascript +const dfd = require("danfojs") + +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["one", "two", "three"] }) +df_new.print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series.reset_index.png) + +```javascript +const dfd = require("danfojs") + +let data = ["Humans","Life","Meaning","Fact","Truth"] +let df = new dfd.Series(data) +let df_new = df.set_index({ "index": ["H", "L", "M","F","T"] }) +df_new.print() +``` + +**OUTPUT** + +![](../../.gitbook/assets/series_reset_index2.png) + diff --git a/api-reference copy/series/danfo.series.sort_values.md b/api-reference copy/series/danfo.series.sort_values.md new file mode 100644 index 0000000..0a0c4e7 --- /dev/null +++ b/api-reference copy/series/danfo.series.sort_values.md @@ -0,0 +1,27 @@ +# danfo.Series.sort\_values + + + +Sort a Series in ascending or descending order by some criterion. + + + + **parameter:** {kwargs} Object, {ascending \(Bool\): Whether to return sorted values in ascending order or not, inplace \(Bool\): Whether to perform sorting on the original Series or not} + + **return:** {Number} + +**Example** + +```javascript +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values() + + +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values({ "inplace": true }) + + +let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) +sf.sort_values({ "ascending": false, "inplace": true }) +``` + diff --git a/api-reference copy/series/danfo.series.std.md b/api-reference copy/series/danfo.series.std.md new file mode 100644 index 0000000..8f48ef2 --- /dev/null +++ b/api-reference copy/series/danfo.series.std.md @@ -0,0 +1,20 @@ +# danfo.Series.std + +Return sample standard deviation over requested axis. + + + + **parameter:** + + **return:** {Number} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.std() +``` + + + diff --git a/api-reference copy/series/danfo.series.sub.md b/api-reference copy/series/danfo.series.sub.md new file mode 100644 index 0000000..8867c14 --- /dev/null +++ b/api-reference copy/series/danfo.series.sub.md @@ -0,0 +1,24 @@ +--- +description: 'Return Subtraction of series and other, element-wise (binary operator sub).' +--- + +# danfo.Series.sub + +Returns the subtraction between a series and other, element-wise \(binary operator subtraction\). + +Equivalent to series - other + + **parameter:** {other} Series, Number to subtract + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 39, 1, 2, 1] +let data2 = [1, 2, 3, 4, 5, 6] +let sf1 = new Series(data1) +let sf2 = new Series(data2) +sf1.sub(sf2) +``` + diff --git a/api-reference copy/series/danfo.series.sum-1.md b/api-reference copy/series/danfo.series.sum-1.md new file mode 100644 index 0000000..6ec14cb --- /dev/null +++ b/api-reference copy/series/danfo.series.sum-1.md @@ -0,0 +1,22 @@ +--- +description: Return the sum of the values in a series. +--- + +# danfo.Series.sum + +Return the sum of the values for the requested axis. + +This is equivalent to the method numpy.sum. + + **parameter:** + + **return:** Series + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.sum() +``` + diff --git a/api-reference copy/series/danfo.series.tail.md b/api-reference copy/series/danfo.series.tail.md new file mode 100644 index 0000000..e83307d --- /dev/null +++ b/api-reference copy/series/danfo.series.tail.md @@ -0,0 +1,22 @@ +--- +description: Prints the last n values in a Series +--- + +# danfo.Series.tail + +Prints the first n values in a Series + + **parameter:** {rows} Number of rows to return + + **return:** Series + +**Example** + +```javascript +let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf = new Series(data) +sf.tail() +``` + + + diff --git a/api-reference copy/series/danfo.series.tostring.md b/api-reference copy/series/danfo.series.tostring.md new file mode 100644 index 0000000..5807850 --- /dev/null +++ b/api-reference copy/series/danfo.series.tostring.md @@ -0,0 +1,18 @@ +# danfo.Series.toString + + + +Prints the data in a Series as a grid of row and columns + + + +**parameter:** + + **return:** {frame} + +**Example** + +```javascript + +``` + diff --git a/api-reference copy/series/danfo.series.var.md b/api-reference copy/series/danfo.series.var.md new file mode 100644 index 0000000..822edc7 --- /dev/null +++ b/api-reference copy/series/danfo.series.var.md @@ -0,0 +1,20 @@ +# danfo.Series.var + + + +Return unbiased variance of Series. + + + + **parameter:** + + **return:** {Number} + +**Example** + +```javascript +let data1 = [30, 40, 3, 5] +let sf = new Series(data1) +sf.var() +``` + diff --git a/api-reference copy/series/series.abs.md b/api-reference copy/series/series.abs.md new file mode 100644 index 0000000..843dd5e --- /dev/null +++ b/api-reference copy/series/series.abs.md @@ -0,0 +1,52 @@ +--- +description: Returns the absolute value in a Series +--- + +# Series.abs + +> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| + +**Returns:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [-10, 45, 56, -25, 23, -20, 10] +let sf = new dfd.Series(data1) + +sf.abs().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 25 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 6 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.add.md b/api-reference copy/series/series.add.md new file mode 100644 index 0000000..e55b1b8 --- /dev/null +++ b/api-reference copy/series/series.add.md @@ -0,0 +1,86 @@ +--- +description: Return Addition of series and other, element-wise (binary operator add). +--- + +# Series.add + +> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +subtract from values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.add(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 31 ║ +╟───┼──────────────────────╢ +║ 1 │ 42 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 9 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +subtract from a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.add(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 3 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 5 ║ +╟───┼──────────────────────╢ +║ 3 │ 6 ║ +╟───┼──────────────────────╢ +║ 4 │ 7 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.and.md b/api-reference copy/series/series.and.md new file mode 100644 index 0000000..85c22cb --- /dev/null +++ b/api-reference copy/series/series.and.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical AND between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.and + +> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical AND between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.and(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical AND between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.and(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.append.md b/api-reference copy/series/series.append.md new file mode 100644 index 0000000..53e8f03 --- /dev/null +++ b/api-reference copy/series/series.append.md @@ -0,0 +1,135 @@ +--- +description: Add a new value or values to the end of a Series. +--- + +# Series.append + +danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | +| newValue | Array, Series | Object to append | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | +| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | + +**Returns:** + + **** return **Series** + +**** + +### **Append new Series to the end of a Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) + +new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) +new_sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ +``` +{% endtab %} +{% endtabs %} + +### **Append new Series to the end of a Series in-place** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sf2 = new dfd.Series(["a", "b", "c"]) +let newIndex = ["f5", "f6", "f7"] + +sf1.append(sf2, newIndex, { inplace: true }) +sf1.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ +``` + +### **Append an array to the end of Series** + +{% tabs %} +{% tab title="Node" %} +```javascript +let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) +let sfArr = ["a", "b", "c"] + +new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) +new_sf.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤═══╗ +║ f1 │ 1 ║ +╟────┼───╢ +║ f2 │ 2 ║ +╟────┼───╢ +║ f3 │ 3 ║ +╟────┼───╢ +║ f4 │ 4 ║ +╟────┼───╢ +║ f5 │ a ║ +╟────┼───╢ +║ f6 │ b ║ +╟────┼───╢ +║ f7 │ c ║ +╚════╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.apply.md b/api-reference copy/series/series.apply.md new file mode 100644 index 0000000..7f7050e --- /dev/null +++ b/api-reference copy/series/series.apply.md @@ -0,0 +1,149 @@ +--- +description: Invoke a function on each value in a Series. +--- + +# Series.apply + +> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] + +| Parameters | Type | Description | Default | +| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function | Function (can be anonymous) to apply | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns:** + + **** return **Series** + +**** + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +let apply_func = (x) => { + return x + x +} +sf.apply(apply_func).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 8 ║ +╟───┼──────────────────────╢ +║ 4 │ 10 ║ +╟───┼──────────────────────╢ +║ 5 │ 12 ║ +╟───┼──────────────────────╢ +║ 6 │ 14 ║ +╟───┼──────────────────────╢ +║ 7 │ 16 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) + +sf.apply(Math.log).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 0.6931471805599453 ║ +╟───┼──────────────────────╢ +║ 2 │ 1.0986122886681096 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.3862943611198906 ║ +╟───┼──────────────────────╢ +║ 4 │ 1.6094379124341003 ║ +╟───┼──────────────────────╢ +║ 5 │ 1.791759469228055 ║ +╟───┼──────────────────────╢ +║ 6 │ 1.9459101490553132 ║ +╟───┼──────────────────────╢ +║ 7 │ 2.0794415416798357 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) + +sf.apply((x)=>{ + return x.toLocaleLowerCase() +}).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ rice ║ +╟───┼──────────────────────╢ +║ 1 │ beans ║ +╟───┼──────────────────────╢ +║ 2 │ yam ║ +╟───┼──────────────────────╢ +║ 3 │ banana ║ +╟───┼──────────────────────╢ +║ 4 │ wheat ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.argmax.md b/api-reference copy/series/series.argmax.md new file mode 100644 index 0000000..d7927d2 --- /dev/null +++ b/api-reference copy/series/series.argmax.md @@ -0,0 +1,35 @@ +--- +description: Returns the int position of the largest value in the series +--- + +# Series.argmax + +> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] + +**Parameters**: None + +**Returns**: int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,30,20,40,50,70,90,200,10,20,12] +let sf = new dfd.Series(data) + +sf.argmax() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +7 +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.argmin.md b/api-reference copy/series/series.argmin.md new file mode 100644 index 0000000..dfc661f --- /dev/null +++ b/api-reference copy/series/series.argmin.md @@ -0,0 +1,35 @@ +--- +description: Returns the int position of the smallest value in the series +--- + +# Series.argmin + +> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] + +**Parameters**: None + +**Returns**: int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,30,20,40,50,70,90,200,10,20,12] +let sf = new dfd.Series(data) + +sf.argmin() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +0 +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.argsort.md b/api-reference copy/series/series.argsort.md new file mode 100644 index 0000000..b4608a4 --- /dev/null +++ b/api-reference copy/series/series.argsort.md @@ -0,0 +1,75 @@ +--- +description: Return the integer indices that would sort the Series values +--- + +# Series.argsort + +> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | +| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| + +**Returns:** Series (int element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [10, 45, 20, 10, 23, 20, 30, 11] +let sf = new dfd.Series(data) + +sf.argsort().print() //defaults to ascending order +sf.argsort({ ascending: false }).print() + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 3 ║ +╟───┼──────────────────────╢ +║ 2 │ 7 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 4 ║ +╟───┼──────────────────────╢ +║ 6 │ 6 ║ +╟───┼──────────────────────╢ +║ 7 │ 1 ║ +╚═══╧══════════════════════╝ + +//sorted in descending order +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 6 ║ +╟───┼───╢ +║ 2 │ 4 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 3 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.astype.md b/api-reference copy/series/series.astype.md new file mode 100644 index 0000000..15a61ae --- /dev/null +++ b/api-reference copy/series/series.astype.md @@ -0,0 +1,2 @@ +# Series.astype + diff --git a/api-reference copy/series/series.copy.md b/api-reference copy/series/series.copy.md new file mode 100644 index 0000000..9bbdb47 --- /dev/null +++ b/api-reference copy/series/series.copy.md @@ -0,0 +1,45 @@ +--- +description: Makes a deep copy of a Series +--- + +# Series.copy + +> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] + +**parameter:** + +**Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) +let sf2 = sf1.copy() + +sf2.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30.21091 ║ +╟───┼──────────────────────╢ +║ 1 │ 40.190901 ║ +╟───┼──────────────────────╢ +║ 2 │ 3.564 ║ +╟───┼──────────────────────╢ +║ 3 │ 5.0212 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.corr.md b/api-reference copy/series/series.corr.md new file mode 100644 index 0000000..ee3263f --- /dev/null +++ b/api-reference copy/series/series.corr.md @@ -0,0 +1,2 @@ +# Series.corr + diff --git a/api-reference copy/series/series.count.md b/api-reference copy/series/series.count.md new file mode 100644 index 0000000..832c794 --- /dev/null +++ b/api-reference copy/series/series.count.md @@ -0,0 +1,36 @@ +--- +description: Obtain the total number of values in a series +--- + +# Series.count + +> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.count()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +9 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.cummax.md b/api-reference copy/series/series.cummax.md new file mode 100644 index 0000000..8aded1a --- /dev/null +++ b/api-reference copy/series/series.cummax.md @@ -0,0 +1,51 @@ +--- +description: Returns cumulative maximum over a series +--- + +# Series.cummax + +> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cummax().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 3 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 56 ║ +╟───┼──────────────────────╢ +║ 5 │ 56 ║ +╟───┼──────────────────────╢ +║ 6 │ 56 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.cummin.md b/api-reference copy/series/series.cummin.md new file mode 100644 index 0000000..736cee5 --- /dev/null +++ b/api-reference copy/series/series.cummin.md @@ -0,0 +1,51 @@ +--- +description: Returns the cumulative min of a Series +--- + +# Series.cummin + +> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 5, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cummin().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 10 ║ +╟───┼──────────────────────╢ +║ 2 │ 10 ║ +╟───┼──────────────────────╢ +║ 3 │ 5 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 5 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.cumprod.md b/api-reference copy/series/series.cumprod.md new file mode 100644 index 0000000..84ec0e7 --- /dev/null +++ b/api-reference copy/series/series.cumprod.md @@ -0,0 +1,51 @@ +--- +description: Return the cumulative product of a series +--- + +# Series.cumprod + +> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cumprod().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 450 ║ +╟───┼──────────────────────╢ +║ 2 │ 25200 ║ +╟───┼──────────────────────╢ +║ 3 │ 630000 ║ +╟───┼──────────────────────╢ +║ 4 │ 14490000 ║ +╟───┼──────────────────────╢ +║ 5 │ 289800000 ║ +╟───┼──────────────────────╢ +║ 6 │ 2898000000 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.cumsum.md b/api-reference copy/series/series.cumsum.md new file mode 100644 index 0000000..7b7a19a --- /dev/null +++ b/api-reference copy/series/series.cumsum.md @@ -0,0 +1,74 @@ +--- +description: Return a cumulative sum of a series +--- + +# Series.cumsum + +> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.cumsum().print() +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + Document + + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 55 ║ +╟───┼──────────────────────╢ +║ 2 │ 111 ║ +╟───┼──────────────────────╢ +║ 3 │ 136 ║ +╟───┼──────────────────────╢ +║ 4 │ 159 ║ +╟───┼──────────────────────╢ +║ 5 │ 179 ║ +╟───┼──────────────────────╢ +║ 6 │ 189 ║ +╚═══╧══════════════════════╝ +``` diff --git a/api-reference copy/series/series.describe.md b/api-reference copy/series/series.describe.md new file mode 100644 index 0000000..ce52246 --- /dev/null +++ b/api-reference copy/series/series.describe.md @@ -0,0 +1,57 @@ +--- +description: >- + Generate descriptive statistics. Descriptive statistics include those that + summarize the central tendency, dispersion and shape of a dataset’s + distribution, excluding NaN values +--- + +# Series.describe + +> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] + +**Parameters:** No parameter + +**return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = [1,2,3,4,5,6] +let sf = new dfd.Series(data) +sf.describe().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔══════════╤══════════════════════╗ +║ │ 0 ║ +╟──────────┼──────────────────────╢ +║ count │ 6 ║ +╟──────────┼──────────────────────╢ +║ mean │ 3.5 ║ +╟──────────┼──────────────────────╢ +║ std │ 1.8708286933869707 ║ +╟──────────┼──────────────────────╢ +║ min │ 1 ║ +╟──────────┼──────────────────────╢ +║ median │ 3.5 ║ +╟──────────┼──────────────────────╢ +║ max │ 6 ║ +╟──────────┼──────────────────────╢ +║ variance │ 3.5 ║ +╚══════════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.div.md b/api-reference copy/series/series.div.md new file mode 100644 index 0000000..656a796 --- /dev/null +++ b/api-reference copy/series/series.div.md @@ -0,0 +1,87 @@ +--- +description: >- + Return Floating division of series and other, element-wise (binary operator + truediv). +--- + +# Series.div + +> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +divide with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.div(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 20 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 1.25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### divide with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.div(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0.5 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 1.5 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 2.5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dot.md b/api-reference copy/series/series.dot.md new file mode 100644 index 0000000..61a8bc2 --- /dev/null +++ b/api-reference copy/series/series.dot.md @@ -0,0 +1,2 @@ +# Series.dot + diff --git a/api-reference copy/series/series.drop_duplicates.md b/api-reference copy/series/series.drop_duplicates.md new file mode 100644 index 0000000..08edf09 --- /dev/null +++ b/api-reference copy/series/series.drop_duplicates.md @@ -0,0 +1,121 @@ +--- +description: Remove duplicate rows +--- + +# Series.drop\_duplicates + +> danfo.Series.**drop\_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | +| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| + +**Returns:** Series + +**Examples** + +### Drop duplicate by keeping the first occurrence of the duplicate value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 10, 23, 20, 10, 10] +let sf = new dfd.Series(data1) +let sf_drop = sf.drop_duplicates() + +sf_drop.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop duplicate and keep only the last duplicated value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 10, 23, 20, 10, 10] +let sf = new dfd.Series(data1) +let sf_drop = sf.drop_duplicates({keep:"last"}) + +sf_drop.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 2 │ 56 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Remove duplicate value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] +let sf = new dfd.Series(data1) +sf.drop_duplicates({inplace:true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ A ║ +╟───┼──────────────────────╢ +║ 3 │ B ║ +╟───┼──────────────────────╢ +║ 5 │ C ║ +╟───┼──────────────────────╢ +║ 7 │ D ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dropna.md b/api-reference copy/series/series.dropna.md new file mode 100644 index 0000000..2fab716 --- /dev/null +++ b/api-reference copy/series/series.dropna.md @@ -0,0 +1,91 @@ +--- +description: Remove missing values from Series +--- + +# Series.dropna + +> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| + +**Returns**: Series + +**Examples** + +### Drop all nan value and then return New Series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] +let sf = new dfd.Series(data1) +let sf_rep = sf.dropna() + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 3 │ 10 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Drop nan values in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] +let sf = new dfd.Series(data1) +sf.dropna({inplace:true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 45 ║ +╟───┼──────────────────────╢ +║ 3 │ 10 ║ +╟───┼──────────────────────╢ +║ 4 │ 23 ║ +╟───┼──────────────────────╢ +║ 5 │ 20 ║ +╟───┼──────────────────────╢ +║ 7 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.day.md b/api-reference copy/series/series.dt.day.md new file mode 100644 index 0000000..6461fa5 --- /dev/null +++ b/api-reference copy/series/series.dt.day.md @@ -0,0 +1,55 @@ +--- +description: Obtain the numerical representation of the week day. +--- + +# Series.dt.day + +> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] + +**Parameters**: None + +**Returns:** Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) +let sf = new dfd.Series(data) + +sf.dt.day().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ +``` diff --git a/api-reference copy/series/series.dt.hour.md b/api-reference copy/series/series.dt.hour.md new file mode 100644 index 0000000..16369bb --- /dev/null +++ b/api-reference copy/series/series.dt.hour.md @@ -0,0 +1,52 @@ +--- +description: Obtain the hours in a time series +--- + +# Series.dt.hour + +> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] + +**Parameters:** None + +**Returns:** Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) +let sf = new dfd.Series(data) +// print series +sf.print() +// print hour series +sf.dt.hours().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 2:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.minute.md b/api-reference copy/series/series.dt.minute.md new file mode 100644 index 0000000..ea8bfee --- /dev/null +++ b/api-reference copy/series/series.dt.minute.md @@ -0,0 +1,60 @@ +--- +description: Obtain the minutes in a Time Series +--- + +# Series.dt.minutes + +> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] + +**Parameters**: None + +**Returns:** Series (int Elements) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) +let sf = new dfd.Series(data) +//print the series +sf.print() +//print the minutes series +sf.dt.minutes().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 1:01:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2000, 1:02:00 AM ║ +╚═══╧══════════════════════╝ + +//print the minutes series +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.month.md b/api-reference copy/series/series.dt.month.md new file mode 100644 index 0000000..e21eeda --- /dev/null +++ b/api-reference copy/series/series.dt.month.md @@ -0,0 +1,47 @@ +--- +description: Obtain the month in a date time series +--- + +# Series.dt.month + +> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] + +**Parameters**: None + +**Returns:** Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) +let sf = new dfd.Series(data) + +sf.dt.month().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 0 │ 6 ║ +╟───┼────╢ +║ 1 │ 7 ║ +╟───┼────╢ +║ 2 │ 9 ║ +╟───┼────╢ +║ 3 │ 9 ║ +╟───┼────╢ +║ 4 │ 11 ║ +╟───┼────╢ +║ 5 │ 11 ║ +╚═══╧════╝ +``` diff --git a/api-reference copy/series/series.dt.month_name.md b/api-reference copy/series/series.dt.month_name.md new file mode 100644 index 0000000..4e83618 --- /dev/null +++ b/api-reference copy/series/series.dt.month_name.md @@ -0,0 +1,55 @@ +--- +description: obtain the month name in a Time Series +--- + +# Series.dt.month\_name + +> danfo.Series.dt.month\_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] + +**Parameters**: None + +**Returns:** Series (String elements) + +**Examples** + +{% tabs %} +{% tab title="Output" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print month names +sf.dt.month_name().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2018, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 2/1/2018, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 3/1/2018, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═════╗ +║ 0 │ Jan ║ +╟───┼─────╢ +║ 1 │ Feb ║ +╟───┼─────╢ +║ 2 │ Mar ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.monthday.md b/api-reference copy/series/series.dt.monthday.md new file mode 100644 index 0000000..b385f17 --- /dev/null +++ b/api-reference copy/series/series.dt.monthday.md @@ -0,0 +1,55 @@ +--- +description: Obtain the day of the month +--- + +# Series.dt.monthday + +> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] + +**Parameters:** None + +**Returns**: Series (Int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print monthdays +sf.dt.monthday().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/2/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/3/2000, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.second.md b/api-reference copy/series/series.dt.second.md new file mode 100644 index 0000000..43330be --- /dev/null +++ b/api-reference copy/series/series.dt.second.md @@ -0,0 +1,60 @@ +--- +description: Obtain the seconds in Date series +--- + +# Series.dt.seconds + +> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] + +**Parameters**: None + +**Returns:** Series (Int elements) + +**Example** + +Obtain the seconds of the datetime + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) +let sf = new dfd.Series(data) +//print the series frame +sf.print() + +//print the seconds obtained +sf.dt.seconds().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` + +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2000, 1:00:01 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2000, 1:00:02 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╚═══╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.dt.weekdays.md b/api-reference copy/series/series.dt.weekdays.md new file mode 100644 index 0000000..04dbe18 --- /dev/null +++ b/api-reference copy/series/series.dt.weekdays.md @@ -0,0 +1,79 @@ +--- +description: Obtain the days of the weeks +--- + +# Series.dt.weekdays + +> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] + +**Parameters**: None + +**Returns:** Series (String elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let sf = new dfd.Series(data) +//print series +sf.print() +//print days of the week +sf.dt.weekdays().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ + +╔═══╤══════╗ +║ 0 │ Sat ║ +╟───┼──────╢ +║ 1 │ Sun ║ +╟───┼──────╢ +║ 2 │ Mon ║ +╟───┼──────╢ +║ 3 │ Tue ║ +╟───┼──────╢ +║ 4 │ Wed ║ +╟───┼──────╢ +║ 5 │ Thur ║ +╟───┼──────╢ +║ 6 │ Fri ║ +╟───┼──────╢ +║ 7 │ Sat ║ +╟───┼──────╢ +║ 8 │ Sun ║ +╟───┼──────╢ +║ 9 │ Mon ║ +╚═══╧══════╝ +``` diff --git a/api-reference copy/series/series.dt.year.md b/api-reference copy/series/series.dt.year.md new file mode 100644 index 0000000..ed1117f --- /dev/null +++ b/api-reference copy/series/series.dt.year.md @@ -0,0 +1,45 @@ +--- +description: Obtain the year in a date time series +--- + +# Series.dt.year + +> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] + +**Parameters**: None + +**Returns:** Series (int elements) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) +let sf = new dfd.Series(data) +sf.print() +sf.dt.year().print() +``` +{% endtab %} +{% endtabs %} + +``` +//print date time series +╔═══╤══════════════════════╗ +║ 0 │ 1/1/2000, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 1 │ 1/1/2001, 1:00:00 AM ║ +╟───┼──────────────────────╢ +║ 2 │ 1/1/2002, 1:00:00 AM ║ +╚═══╧══════════════════════╝ + +╔═══╤══════╗ +║ 0 │ 2000 ║ +╟───┼──────╢ +║ 1 │ 2001 ║ +╟───┼──────╢ +║ 2 │ 2002 ║ +╚═══╧══════╝ +``` diff --git a/api-reference copy/series/series.dtype.md b/api-reference copy/series/series.dtype.md new file mode 100644 index 0000000..75b4614 --- /dev/null +++ b/api-reference copy/series/series.dtype.md @@ -0,0 +1,34 @@ +--- +description: Obtain the dtype of a series +--- + +# Series.dtype + +> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] + +**Parameters**: None + +**Returns:** String + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.dtype) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +float32 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.eq.md b/api-reference copy/series/series.eq.md new file mode 100644 index 0000000..43a3ece --- /dev/null +++ b/api-reference copy/series/series.eq.md @@ -0,0 +1,95 @@ +--- +description: Check all the values in a series is equal to another value +--- + +# Series.eq + +> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | + +**Returns**: Series (Boolean element) + +**Examples** + +Compare all the values in a series to another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.eq(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Check it all the values are equal to a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.eq(10).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.fillna.md b/api-reference copy/series/series.fillna.md new file mode 100644 index 0000000..a1db3a8 --- /dev/null +++ b/api-reference copy/series/series.fillna.md @@ -0,0 +1,106 @@ +--- +description: Replace all NaN value with specified value +--- + +# Series.fillna + +> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| + +**Examples** + +### Fill nan value and then return new series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] +let sf = new dfd.Series(data1) + +let sf_rep = sf.fillna({ value: -999}) + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -999 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 33 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 5 │ -999 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 7 ║ +╟───┼──────────────────────╢ +║ 9 │ 8 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Fill nan value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] +let sf = new dfd.Series(data1) +sf.fillna({ value: -999, inplace: true }) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -999 ║ +╟───┼──────────────────────╢ +║ 1 │ 1 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 33 ║ +╟───┼──────────────────────╢ +║ 4 │ 4 ║ +╟───┼──────────────────────╢ +║ 5 │ -999 ║ +╟───┼──────────────────────╢ +║ 6 │ 5 ║ +╟───┼──────────────────────╢ +║ 7 │ 6 ║ +╟───┼──────────────────────╢ +║ 8 │ 7 ║ +╟───┼──────────────────────╢ +║ 9 │ 8 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.ge.md b/api-reference copy/series/series.ge.md new file mode 100644 index 0000000..0fb1aeb --- /dev/null +++ b/api-reference copy/series/series.ge.md @@ -0,0 +1,95 @@ +--- +description: Check if all the values in a series is greater than or equal a value +--- + +# Series.ge + +> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns:** Series (Boolean element) + +**Example** + +Compare all the value in a Series to the values in another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.ge(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Check if all the value in a Series is greater than or equal a value. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.ge(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.gt.md b/api-reference copy/series/series.gt.md new file mode 100644 index 0000000..184ca28 --- /dev/null +++ b/api-reference copy/series/series.gt.md @@ -0,0 +1,95 @@ +--- +description: Check if all the value in a series is greater than a value +--- + +# Series.gt + +> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns**: Series (boolean element) + +**Example** + +Check if all the values in a series are greater than a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.gt(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are greater than values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.gt(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.head.md b/api-reference copy/series/series.head.md new file mode 100644 index 0000000..2892263 --- /dev/null +++ b/api-reference copy/series/series.head.md @@ -0,0 +1,51 @@ +--- +description: Obtain the first n rows for the object based on position. +--- + +# Series.head + +> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| rows | Int | number of first n values | 5 | + + **Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf1 = new dfd.Series(data1) + +sf1.head().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference copy/series/series.iloc.md b/api-reference copy/series/series.iloc.md new file mode 100644 index 0000000..ab7d1f3 --- /dev/null +++ b/api-reference copy/series/series.iloc.md @@ -0,0 +1,158 @@ +# Series.iloc + +danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | + +**Returns:** + + **** return **Series** + +## **Examples** + +`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). + +Allowed inputs are: + +* An integer, e.g. `5`. +* A list or array of integers, e.g. `[4, 3, 0]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `"1:7"` + +_**Note:** only **** the start label is included, and the end label is ignored._ + +`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. + +### **Indexing specific rows by index** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc([0,5]).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 5 │ 30 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row** + +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(["0:5"]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 12 ║ +╟───┼──────────────────────╢ +║ 1 │ 34 ║ +╟───┼──────────────────────╢ +║ 2 │ 2.2 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 30 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +By specifying a start index in a slice, all values after that index are returned. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(["5:"]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 5 │ 30 ║ +╟───┼──────────────────────╢ +║ 6 │ 2.1 ║ +╟───┼──────────────────────╢ +║ 7 │ 7 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.iloc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference copy/series/series.index.md b/api-reference copy/series/series.index.md new file mode 100644 index 0000000..1cc95da --- /dev/null +++ b/api-reference copy/series/series.index.md @@ -0,0 +1,33 @@ +--- +description: Obtain the index of a Series +--- + +# Series.index + +> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] + +**Returns**: Array + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.index) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 0, 1, 2, 3 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.isna.md b/api-reference copy/series/series.isna.md new file mode 100644 index 0000000..cdf6343 --- /dev/null +++ b/api-reference copy/series/series.isna.md @@ -0,0 +1,45 @@ +--- +description: Detect Missing values +--- + +# Series.isna + +> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] + +**Parameters**: None + +**Returns**: Series \(Boolean element\) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [NaN, undefined, "girl", "Man"] +let sf = new dfd.Series(data1) + +sf.isna().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.le.md b/api-reference copy/series/series.le.md new file mode 100644 index 0000000..44006e2 --- /dev/null +++ b/api-reference copy/series/series.le.md @@ -0,0 +1,96 @@ +--- +description: Check if all the values in a series is less than or equal to a value +--- + +# Series.le + +> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns:** Series (Boolean Element) + +**Example** + +Check if all the values in a series is less than or equal to a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.le(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ false ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are less than equal to values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.le(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ true ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.loc.md b/api-reference copy/series/series.loc.md new file mode 100644 index 0000000..13772ab --- /dev/null +++ b/api-reference copy/series/series.loc.md @@ -0,0 +1,198 @@ +--- +description: Access a group of rows by label(s) or a boolean array. +--- + +# Series.loc + +danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] + +| Parameters | Type | Description | Default | +| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | + +**Returns:** + + **** return **Series** + +## **Examples** + +`.loc()` is label position based (from `0` to `length-1` of the row axis). + +Allowed inputs are: + +* An integer, e.g. `"r1"`. +* A list or array of integers, e.g. `["a", "b", "d"]`. +* A boolean mask. E.g \[ true, false, false ] +* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` + +_**Note:** only **** the start label is included, and the end label is ignored._ + +`.loc` will raise a `ValueEror` if a requested label is not found. + +### **Indexing by specific row index** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc(["a", "g"]).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╟───┼─────╢ +║ e │ 30 ║ +╟───┼─────╢ +║ f │ 30 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╟───┼─────╢ +║ h │ 7 ║ +╚═══╧═════╝ + +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ g │ 2.1 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +### **Index by a slice of row** + +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +const index = ["a", "b", "c", "d", "e", "f", "g", "h"] +let s = new dfd.Series(data, { index }) +s.print() + +s.loc([`"a":"e"`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ a │ 12 ║ +╟───┼─────╢ +║ b │ 34 ║ +╟───┼─────╢ +║ c │ 2.2 ║ +╟───┼─────╢ +║ d │ 2 ║ +╚═══╧═════╝ +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ +`s.loc([a:e]).print()`\ +For the slice above to work, you must quote each slice, e.g:\ +`s.loc(["a":"e"]).print()`\ +\ +_**Inner quotes are not needed for numeric indices!**_ +{% endhint %} + +### By specifying a start index in a slice, all values after that index are returned. + +{% tabs %} +{% tab title="Node" %} +```javascript +const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] +let s = new dfd.Series(data) + +s.loc([`1:`]).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 1 │ 34 ║ +╟───┼─────╢ +║ 2 │ 2.2 ║ +╟───┼─────╢ +║ 3 │ 2 ║ +╟───┼─────╢ +║ 4 │ 30 ║ +╟───┼─────╢ +║ 5 │ 30 ║ +╟───┼─────╢ +║ 6 │ 2.1 ║ +╟───┼─────╢ +║ 7 │ 7 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} + +### Slice Series by boolean condition + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) +s.loc(s.gt(20)).print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤════╗ +║ 1 │ 34 ║ +╟───┼────╢ +║ 4 │ 30 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ +``` diff --git a/api-reference copy/series/series.lt.md b/api-reference copy/series/series.lt.md new file mode 100644 index 0000000..7af18bc --- /dev/null +++ b/api-reference copy/series/series.lt.md @@ -0,0 +1,96 @@ +--- +description: Check if all values in a Series are less than a value. +--- + +# Series.lt + +> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ------------------- | ------- | +| other | Series, Array or number | value(s) to compare | | + +**Returns**: Series (boolean element) + +**Example** + +Check if all the values in a series are less than a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.lt(20).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +check if all the values in a series are less than values in another series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.lt(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ false ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ false ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.map.md b/api-reference copy/series/series.map.md new file mode 100644 index 0000000..0e0850a --- /dev/null +++ b/api-reference copy/series/series.map.md @@ -0,0 +1,92 @@ +--- +description: Map the value of a series to a function or Object +--- + +# Series.map + +> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] + +| Parameter | Type | Description | Default | +| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| callable | Function or Object | A function or object({}) | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Example** + +Mapping the element in a Series words in an Object + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1, 2, 3, 4]) +let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } +sf.map(map).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ ok ║ +╟───┼──────────────────────╢ +║ 1 │ okie ║ +╟───┼──────────────────────╢ +║ 2 │ frit ║ +╟───┼──────────────────────╢ +║ 3 │ gop ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Mapping values in a Series to a representation using functions. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series([1,2,3,4]) + +sf.map((x)=>{ + return `I have ${x} cat(s)` +}).print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ I have 1 cat(s) ║ +╟───┼──────────────────────╢ +║ 1 │ I have 2 cat(s) ║ +╟───┼──────────────────────╢ +║ 2 │ I have 3 cat(s) ║ +╟───┼──────────────────────╢ +║ 3 │ I have 4 cat(s) ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.max.md b/api-reference copy/series/series.max.md new file mode 100644 index 0000000..4f7193a --- /dev/null +++ b/api-reference copy/series/series.max.md @@ -0,0 +1,36 @@ +--- +description: Obtain the maximum value in a Series +--- + +# Series.max + +> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.max()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +89 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.maximum.md b/api-reference copy/series/series.maximum.md new file mode 100644 index 0000000..afc5a48 --- /dev/null +++ b/api-reference copy/series/series.maximum.md @@ -0,0 +1,50 @@ +--- +description: Obtain the maximum number between two series +--- + +# Series.maximum + +> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series | series to match | | + +**Return:** {Series} + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.maximum(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 41 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 5 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference copy/series/series.mean.md b/api-reference copy/series/series.mean.md new file mode 100644 index 0000000..17d97e6 --- /dev/null +++ b/api-reference copy/series/series.mean.md @@ -0,0 +1,36 @@ +--- +description: Obtain the mean of a series +--- + +# Series.mean + +> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.mean()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +23.000001907348633 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.median.md b/api-reference copy/series/series.median.md new file mode 100644 index 0000000..d1cde75 --- /dev/null +++ b/api-reference copy/series/series.median.md @@ -0,0 +1,36 @@ +--- +description: Obtain the median of a series +--- + +# Series.median + +> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.median()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +4 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.min.md b/api-reference copy/series/series.min.md new file mode 100644 index 0000000..6e11a67 --- /dev/null +++ b/api-reference copy/series/series.min.md @@ -0,0 +1,36 @@ +--- +description: Obtain the minimum value in a series +--- + +# Series.min + +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.min()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +0 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.minimum.md b/api-reference copy/series/series.minimum.md new file mode 100644 index 0000000..a06ba69 --- /dev/null +++ b/api-reference copy/series/series.minimum.md @@ -0,0 +1,48 @@ +--- +description: Obtain the minimum value between two series (element wise) +--- + +# Series.minimum + +> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series | series to match | | + +**Return:** {Series} + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [10, 41, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.minimum(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 10 ║ +╟───┼──────────────────────╢ +║ 1 │ 40 ║ +╟───┼──────────────────────╢ +║ 2 │ 2 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.mod.md b/api-reference copy/series/series.mod.md new file mode 100644 index 0000000..fdf0555 --- /dev/null +++ b/api-reference copy/series/series.mod.md @@ -0,0 +1,85 @@ +--- +description: Return Modulo of series and other, element-wise (binary operator mod). +--- + +# Series.mod + +> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] + +| Parameters | Type | Description | Default | +| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\|float | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +Modulus with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [2, 30, 4, 5] +let data2 = [1.1, 2.2, 3.3, 2.4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.mod(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 0.8999999761581421 ║ +╟───┼──────────────────────╢ +║ 1 │ 1.3999993801116943 ║ +╟───┼──────────────────────╢ +║ 2 │ 0.7000000476837158 ║ +╟───┼──────────────────────╢ +║ 3 │ 0.19999980926513672 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Modulo with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.mod(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 0 ║ +╟───┼──────────────────────╢ +║ 4 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.mode.md b/api-reference copy/series/series.mode.md new file mode 100644 index 0000000..6077686 --- /dev/null +++ b/api-reference copy/series/series.mode.md @@ -0,0 +1,36 @@ +--- +description: Obtain the center value in a series +--- + +# Series.mode + +> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.mode()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +[ 4 ] +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.mul.md b/api-reference copy/series/series.mul.md new file mode 100644 index 0000000..d5d33de --- /dev/null +++ b/api-reference copy/series/series.mul.md @@ -0,0 +1,86 @@ +--- +description: Return Multiplication of series and other, element-wise (binary operator mul). +--- + +# Series.mul + +> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +multiplication with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.mul(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30 ║ +╟───┼──────────────────────╢ +║ 1 │ 80 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 20 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +multiply with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.mul(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 6 ║ +╟───┼──────────────────────╢ +║ 3 │ 8 ║ +╟───┼──────────────────────╢ +║ 4 │ 10 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.ndim.md b/api-reference copy/series/series.ndim.md new file mode 100644 index 0000000..8623e80 --- /dev/null +++ b/api-reference copy/series/series.ndim.md @@ -0,0 +1,34 @@ +--- +description: Obtain the dimension of a series +--- + +# Series.ndim + +> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] + +**Parameters:** None + +**Returns:** int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.ndim) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +1 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.ne.md b/api-reference copy/series/series.ne.md new file mode 100644 index 0000000..16cf1dc --- /dev/null +++ b/api-reference copy/series/series.ne.md @@ -0,0 +1,95 @@ +--- +description: Check if all values in a series is not equal to a value(s) +--- + +# Series.ne + +> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] + +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ----------------- | ------- | +| other | Series, Array or number | value to compare | | + +**Returns**: Series (Boolean element) + +**Example** + +Compare all the values in a series to that in another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let data2 = [10, 450, 56, 5, 25, 2, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) + +sf1.ne(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Compare all the values in a Series to a value. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf1 = new dfd.Series(data1) + +sf1.ne(10).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╟───┼──────────────────────╢ +║ 4 │ true ║ +╟───┼──────────────────────╢ +║ 5 │ true ║ +╟───┼──────────────────────╢ +║ 6 │ false ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.nunique.md b/api-reference copy/series/series.nunique.md new file mode 100644 index 0000000..092a2eb --- /dev/null +++ b/api-reference copy/series/series.nunique.md @@ -0,0 +1,34 @@ +--- +description: Returns the number of unique values in a series +--- + +# Series.nunique + +> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] + +**Parameters**: None + +**Returns:** int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +console.log(sf.nunique()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Ouptut" %} +``` +9 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.or.md b/api-reference copy/series/series.or.md new file mode 100644 index 0000000..948c61d --- /dev/null +++ b/api-reference copy/series/series.or.md @@ -0,0 +1,132 @@ +--- +description: >- + Returns the logical OR between Series and other. Supports element wise + operations and broadcasting. +--- + +# Series.or + +> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | + + **Return:** Series + +### **Logical OR between two Series object** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let sf2 = new dfd.Series(data2); +let res = sf.or(sf2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between Series and Array of the same length** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [false, false, false, true, false, false, true]; +let data2 = [false, false, false, false, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(data2) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + +### **Logical OR between a Series and single value with broadcasting** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data1 = [false, false, false, true, false, false, true]; + +let sf = new dfd.Series(data1); +let res = sf.or(false) +res.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.pow.md b/api-reference copy/series/series.pow.md new file mode 100644 index 0000000..2fbe542 --- /dev/null +++ b/api-reference copy/series/series.pow.md @@ -0,0 +1,87 @@ +--- +description: >- + Return Exponential power of series and other, element-wise (binary operator + pow). +--- + +# Series.pow + +> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +Exponential power with values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [2, 3, 4, 5] +let data2 = [1, 2, 3, 0] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.pow(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 2 ║ +╟───┼──────────────────────╢ +║ 1 │ 9 ║ +╟───┼──────────────────────╢ +║ 2 │ 64 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Exponential value with a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.pow(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 4 ║ +╟───┼──────────────────────╢ +║ 2 │ 9 ║ +╟───┼──────────────────────╢ +║ 3 │ 16 ║ +╟───┼──────────────────────╢ +║ 4 │ 25 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.replace.md b/api-reference copy/series/series.replace.md new file mode 100644 index 0000000..8a1f48b --- /dev/null +++ b/api-reference copy/series/series.replace.md @@ -0,0 +1,89 @@ +--- +description: Replace values given in replace param with value +--- + +# Series.replace + +> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| + +**Returns**: Series + +**Examples** + +### Replace a value in a series and return a new series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf = new dfd.Series(data1) +let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) + +sf_rep.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + +``` +{% endtab %} +{% endtabs %} + +### Replace a value in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [10, 45, 56, 25, 23, 20, 10] +let sf = new dfd.Series(data1) +sf.replace({ oldValue: 10, newValue: -50, inplace: true}) + +sf.print() +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤═════╗ +║ 0 │ -50 ║ +╟───┼─────╢ +║ 1 │ 45 ║ +╟───┼─────╢ +║ 2 │ 56 ║ +╟───┼─────╢ +║ 3 │ 25 ║ +╟───┼─────╢ +║ 4 │ 23 ║ +╟───┼─────╢ +║ 5 │ 20 ║ +╟───┼─────╢ +║ 6 │ -50 ║ +╚═══╧═════╝ + +``` diff --git a/api-reference copy/series/series.reset_index.md b/api-reference copy/series/series.reset_index.md new file mode 100644 index 0000000..c51497a --- /dev/null +++ b/api-reference copy/series/series.reset_index.md @@ -0,0 +1,113 @@ +--- +description: Reset the index of a series. +--- + +# Series.reset\_index + +> danfo.series.reset\_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | + +**Returns :** Series + +`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. + +### **Reset index to default values** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [20, 30, 40] +let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) +sf.print() + +let sf_reset = sf.reset_index() +sf_reset.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ a │ 20 ║ +╟───┼────╢ +║ b │ 30 ║ +╟───┼────╢ +║ c │ 40 ║ +╚═══╧════╝ + +╔═══╤════╗ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 2 │ 40 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Reset index to new values in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) +sf.print() + +sf.reset_index({ inplace: true }) +sf.print() + +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ a │ 1 ║ +╟───┼───╢ +║ b │ 2 ║ +╟───┼───╢ +║ c │ 3 ║ +╟───┼───╢ +║ d │ 4 ║ +╟───┼───╢ +║ e │ 5 ║ +╟───┼───╢ +║ f │ 6 ║ +╚═══╧═══╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 2 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 4 ║ +╟───┼───╢ +║ 4 │ 5 ║ +╟───┼───╢ +║ 5 │ 6 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.round.md b/api-reference copy/series/series.round.md new file mode 100644 index 0000000..b6f0d82 --- /dev/null +++ b/api-reference copy/series/series.round.md @@ -0,0 +1,48 @@ +--- +description: round off floating values in series +--- + +# Series.round + +> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| dp | int | decimal place to round off to | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +sf1.round(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 30.21 ║ +╟───┼──────────────────────╢ +║ 1 │ 40.19 ║ +╟───┼──────────────────────╢ +║ 2 │ 3.56 ║ +╟───┼──────────────────────╢ +║ 3 │ 5.02 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.sample.md b/api-reference copy/series/series.sample.md new file mode 100644 index 0000000..a28298d --- /dev/null +++ b/api-reference copy/series/series.sample.md @@ -0,0 +1,65 @@ +--- +description: Return a random sample of items from an axis of object. +--- + +# Series.sample + +> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| num | Int | The number of rows to return. | | +| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| + +**Returns:** + + **** return **{Promies} resolves to Series** + +**Example** + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5) + sample.print() + +} +load_data() +``` + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤════╗ +║ 2 │ 3 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 0 │ 1 ║ +╟───┼────╢ +║ 7 │ 40 ║ +╟───┼────╢ +║ 6 │ 30 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Specify a seed when sampling + +```javascript +const dfd = require("danfojs-node") + +async function load_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5, { seed: 2 }) + sample.print() + +} +load_data() + +``` diff --git a/api-reference copy/series/series.set_index.md b/api-reference copy/series/series.set_index.md new file mode 100644 index 0000000..3de352f --- /dev/null +++ b/api-reference copy/series/series.set_index.md @@ -0,0 +1,136 @@ +--- +description: Assign new Index to Series +--- + +# Series.set\_index + +> danfo.series.**set\_index(**options**)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] + +| Parameter | Type | Description | Default | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| index | Array | new index values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Returns:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] +let sf = new dfd.Series(data) +sf.print() + +let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) +sf_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═════════════════════════╗ +║ 0 │ {"alpha":"A","count":1} ║ +╟───┼─────────────────────────╢ +║ 1 │ {"alpha":"B","count":2} ║ +╟───┼─────────────────────────╢ +║ 2 │ {"alpha":"C","count":3} ║ +╚═══╧═════════════════════════╝ + +╔═══════╤═════════════════════════╗ +║ one │ {"alpha":"A","count":1} ║ +╟───────┼─────────────────────────╢ +║ two │ {"alpha":"B","count":2} ║ +╟───────┼─────────────────────────╢ +║ three │ {"alpha":"C","count":3} ║ +╚═══════╧═════════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["Humans","Life","Meaning","Fact","Truth"] +let sf = new dfd.Series(data) +let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) +sf_new.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ H │ Humans ║ +╟───┼──────────────────────╢ +║ L │ Life ║ +╟───┼──────────────────────╢ +║ M │ Meaning ║ +╟───┼──────────────────────╢ +║ F │ Fact ║ +╟───┼──────────────────────╢ +║ T │ Truth ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +### Set index in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs") + +let data = [1, 2, 3, 4, 5, 6] +let sf = new dfd.Series(data) +sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) +sf.print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══════╤═══╗ +║ one │ 1 ║ +╟───────┼───╢ +║ two │ 2 ║ +╟───────┼───╢ +║ three │ 3 ║ +╟───────┼───╢ +║ four │ 4 ║ +╟───────┼───╢ +║ five │ 5 ║ +╟───────┼───╢ +║ six │ 6 ║ +╚═══════╧═══╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.shape.md b/api-reference copy/series/series.shape.md new file mode 100644 index 0000000..9eb5031 --- /dev/null +++ b/api-reference copy/series/series.shape.md @@ -0,0 +1,35 @@ +--- +description: Obtain the shape of a Series +--- + +# Series.shape + +> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] + +**Parameters**: None + +**Returns**: Array \[int, int\] + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.shape) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 4, 1 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.size.md b/api-reference copy/series/series.size.md new file mode 100644 index 0000000..9665b65 --- /dev/null +++ b/api-reference copy/series/series.size.md @@ -0,0 +1,37 @@ +--- +description: Obtain the size of a series +--- + +# Series.size + +> danfo.Series.size \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] + +**Parameters**: None + +**Returns:** int + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.size) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +4 +``` +{% endtab %} +{% endtabs %} + + + diff --git a/api-reference copy/series/series.sort_values.md b/api-reference copy/series/series.sort_values.md new file mode 100644 index 0000000..5c7e5fa --- /dev/null +++ b/api-reference copy/series/series.sort_values.md @@ -0,0 +1,140 @@ +--- +description: Sorts a Series in ascending or descending order +--- + +# Series.sort_values + +> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| + + **Return:** Series + +### Sort values in a Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +let sf2 = sf1.sort_values() + +sf2.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} + +### Sort Series in-place + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +sf1.sort_values({ inplace: true }) + +sf1.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 7 │ 0 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 6 │ 89 ║ +╚═══╧════╝ + +``` +{% endtab %} +{% endtabs %} + +Sort Series values in descending order + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) +sf1.sort_values({ "ascending": false, "inplace": true }) + +sf1.print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════╗ +║ 6 │ 89 ║ +╟───┼────╢ +║ 5 │ 57 ║ +╟───┼────╢ +║ 1 │ 30 ║ +╟───┼────╢ +║ 0 │ 20 ║ +╟───┼────╢ +║ 4 │ 4 ║ +╟───┼────╢ +║ 8 │ 4 ║ +╟───┼────╢ +║ 3 │ 2 ║ +╟───┼────╢ +║ 2 │ 1 ║ +╟───┼────╢ +║ 7 │ 0 ║ +╚═══╧════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.std.md b/api-reference copy/series/series.std.md new file mode 100644 index 0000000..aa05018 --- /dev/null +++ b/api-reference copy/series/series.std.md @@ -0,0 +1,37 @@ +--- +description: Obtain the standard deviation for a series +--- + +# Series.std + +> danfo.Series.std() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.std()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +31.11671576500322 +``` +{% endtab %} +{% endtabs %} + + **** + diff --git a/api-reference copy/series/series.str.capitalize.md b/api-reference copy/series/series.str.capitalize.md new file mode 100644 index 0000000..aea9e91 --- /dev/null +++ b/api-reference copy/series/series.str.capitalize.md @@ -0,0 +1,52 @@ +--- +description: Capitalize the first character of each string +--- + +# Series.str.capitalize + +> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (String element) + +**Example** + +Convert the first character of a string to capital letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'capitals', 'sentence', 'swApCaSe'] +let sf = new dfd.Series(data) +sf.str.capitalize().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ Lower boy ║ +╟───┼──────────────────────╢ +║ 1 │ Capitals ║ +╟───┼──────────────────────╢ +║ 2 │ Sentence ║ +╟───┼──────────────────────╢ +║ 3 │ Swapcase ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.charat.md b/api-reference copy/series/series.str.charat.md new file mode 100644 index 0000000..931bb48 --- /dev/null +++ b/api-reference copy/series/series.str.charat.md @@ -0,0 +1,53 @@ +--- +description: Obtain the character at the specified index (position) +--- + +# Series.str.charAt + +> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| index | int | the index at which to obtain the character | 0 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (Character element) + +**Example** + +Obtain the character at index 2 of all string elements in the series. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.charAt(2).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ w ║ +╟───┼──────────────────────╢ +║ 1 │ P ║ +╟───┼──────────────────────╢ +║ 2 │ n ║ +╟───┼──────────────────────╢ +║ 3 │ A ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.concat.md b/api-reference copy/series/series.str.concat.md new file mode 100644 index 0000000..e3abe54 --- /dev/null +++ b/api-reference copy/series/series.str.concat.md @@ -0,0 +1,165 @@ +--- +description: Joins two or more strings/arrays +--- + +# Series.str.concat + +> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] + +| Parameters | Type | Description | Default | +| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| other | string or Array | string or list of strings to add to each string element of the series | "" | +| position | Int | The position to add the **other** (string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** Series (String element) + +**Examples** + +Add the strings from an Array to the start of each of the String element in Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat(data2,0).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ XXlower boy ║ +╟───┼──────────────────────╢ +║ 1 │ YYCAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ BBsentence ║ +╟───┼──────────────────────╢ +║ 3 │ 01SwApCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add the strings from an Array to the end of each of the String element in Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat(data2,1).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boyXX ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALSYY ║ +╟───┼──────────────────────╢ +║ 2 │ sentenceBB ║ +╟───┼──────────────────────╢ +║ 3 │ SwApCaSe01 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add a string to the start of each string element in a Series + +{% tabs %} +{% tab title="Output" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat("pre",0).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ prelower boy ║ +╟───┼──────────────────────╢ +║ 1 │ preCAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ presentence ║ +╟───┼──────────────────────╢ +║ 3 │ preSwApCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Add a string to the end of each string element in a series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let data2 = ['XX', 'YY', 'BB', '01'] +let sf = new dfd.Series(data) +sf.str.concat("post",1).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boypost ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALSpost ║ +╟───┼──────────────────────╢ +║ 2 │ sentencepost ║ +╟───┼──────────────────────╢ +║ 3 │ SwApCaSepost ║ +╚═══╧══════════════════════╝ +``` diff --git a/api-reference copy/series/series.str.endswith.md b/api-reference copy/series/series.str.endswith.md new file mode 100644 index 0000000..2fb44cc --- /dev/null +++ b/api-reference copy/series/series.str.endswith.md @@ -0,0 +1,51 @@ +--- +description: Checks whether a string ends with specified characters +--- + +# Series.str.endsWith + +> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (Boolean element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.endsWith("e").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ true ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.includes.md b/api-reference copy/series/series.str.includes.md new file mode 100644 index 0000000..8918773 --- /dev/null +++ b/api-reference copy/series/series.str.includes.md @@ -0,0 +1,51 @@ +--- +description: Checks whether a string contains the specified string/characters +--- + +# Series.str.includes + +> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (boolean element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.includes("C").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ true ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.indexof.md b/api-reference copy/series/series.str.indexof.md new file mode 100644 index 0000000..1d9e64f --- /dev/null +++ b/api-reference copy/series/series.str.indexof.md @@ -0,0 +1,51 @@ +--- +description: the position of the first found occurrence of a specified value in a string +--- + +# Series.str.indexOf + +> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to obtain its index | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.indexOf("C").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.join.md b/api-reference copy/series/series.str.join.md new file mode 100644 index 0000000..5bb77fe --- /dev/null +++ b/api-reference copy/series/series.str.join.md @@ -0,0 +1,52 @@ +--- +description: Join a new string value to all string elements in a Series. +--- + +# Series.str.join + +> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| valToJoin | String | the string value you want to | "" | +| joinChar | String | The delimiter to specify the joining | " " | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + + **** return **Series** + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part', 'CAPITALS city', 'this is a sentence', 'SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.join("new", "_").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤════════════════════════╗ +║ 0 │ lower part_new ║ +╟───┼────────────────────────╢ +║ 1 │ CAPITALS city_new ║ +╟───┼────────────────────────╢ +║ 2 │ this is a sentence_new ║ +╟───┼────────────────────────╢ +║ 3 │ SwAp CaSe_new ║ +╚═══╧════════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.lastindexof.md b/api-reference copy/series/series.str.lastindexof.md new file mode 100644 index 0000000..889a1f4 --- /dev/null +++ b/api-reference copy/series/series.str.lastindexof.md @@ -0,0 +1,54 @@ +--- +description: >- + Obtain the position of the last found occurrence of a specified value in a + string +--- + +# Series.str.lastIndexOf + +danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.lastIndexOf("r").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 4 ║ +╟───┼──────────────────────╢ +║ 1 │ -1 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.str.len.md b/api-reference copy/series/series.str.len.md new file mode 100644 index 0000000..0ef06b2 --- /dev/null +++ b/api-reference copy/series/series.str.len.md @@ -0,0 +1,52 @@ +--- +description: Obtain the length of each string element in a Series +--- + +# Series.str.len + +> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Examples** + +Returns the length (number of character) of a string, and also return the length (number of elements) of Array + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["dog", 5,"cat","fog","mug","animals"] +let sf = new dfd.Series(data) +sf.str.len().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 3 ║ +╟───┼───╢ +║ 3 │ 3 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 7 ║ +╚═══╧═══╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.repeat.md b/api-reference copy/series/series.str.repeat.md new file mode 100644 index 0000000..703be26 --- /dev/null +++ b/api-reference copy/series/series.str.repeat.md @@ -0,0 +1,51 @@ +--- +description: Repeat the the character(s) in a string for a specified number of time +--- + +# Series.str.repeat + +> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] + +| Parameters | Type | Description | Default | +| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | +| num | integer | the string to search for | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['a', 'b', 'c', 'd'] +let sf = new dfd.Series(data) +sf.str.repeat(4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ aaaa ║ +╟───┼──────────────────────╢ +║ 1 │ bbbb ║ +╟───┼──────────────────────╢ +║ 2 │ cccc ║ +╟───┼──────────────────────╢ +║ 3 │ dddd ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.replace.md b/api-reference copy/series/series.str.replace.md new file mode 100644 index 0000000..2b06b1f --- /dev/null +++ b/api-reference copy/series/series.str.replace.md @@ -0,0 +1,50 @@ +--- +description: Replace a word or character(s) in a String element +--- + +# Series.str.replace + +> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] + +| Parameters | Type | Description | Default | +| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| searchValue | string | String \| Character value to replace. Supports regex. | "" | +| replaceValue | String | string to replace the searched string | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.replace("A", "XXX").print() +``` +{% endtab %} + +{% tab title="Browse" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower ║ +╟───┼──────────────────────╢ +║ 1 │ CXXXPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentence ║ +╟───┼──────────────────────╢ +║ 3 │ SwXXXpCaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.search.md b/api-reference copy/series/series.str.search.md new file mode 100644 index 0000000..99fc428 --- /dev/null +++ b/api-reference copy/series/series.str.search.md @@ -0,0 +1,94 @@ +--- +description: Obtain the index position of a searched character in a String +--- + +# Series.str.search + +> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] + + + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | String | the string to search for | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + + **** return Series: Series of index position + +**Example** + +obtain the index position for a character + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.search("S").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 8 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +Obtain the index position for a searched word + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower city ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.search("city").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 6 ║ +╟───┼──────────────────────╢ +║ 1 │ 10 ║ +╟───┼──────────────────────╢ +║ 2 │ -1 ║ +╟───┼──────────────────────╢ +║ 3 │ -1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.slice.md b/api-reference copy/series/series.str.slice.md new file mode 100644 index 0000000..cef7a86 --- /dev/null +++ b/api-reference copy/series/series.str.slice.md @@ -0,0 +1,54 @@ +--- +description: Obtain the substring of each element in a series +--- + +# Series.str.slice + +> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + + **** return Series. + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.slice(2, 4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ we ║ +╟───┼──────────────────────╢ +║ 1 │ AP ║ +╟───┼──────────────────────╢ +║ 2 │ hi ║ +╟───┼──────────────────────╢ +║ 3 │ Sw ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.split.md b/api-reference copy/series/series.str.split.md new file mode 100644 index 0000000..006795d --- /dev/null +++ b/api-reference copy/series/series.str.split.md @@ -0,0 +1,74 @@ +--- +description: >- + Split string around a given separator/delimiter. The array of strings are then + converted to a string. +--- + +# Series.str.split + +> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | +| splitVal | String | separator or delimiter used to split the string | " " | +| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| + +**Returns** + + return **Series** + +**Examples** + +Split the string value in the Series by space and obtain the Series values + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["king of the music","the lamba queen","I love the hat"] +let sf = new dfd.Series(data) +console.log(sf.str.split().values) +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` + +{% tabs %} +{% tab title="JavaScript" %} +```javascript +const dfd = require("danfojs-node") + +let data = ["king_of_the_music","the_lamba_queen","I_love_the_hat"] +let sf = new dfd.Series(data) +sf.str.split("_").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ king,of,the,music ║ +╟───┼──────────────────────╢ +║ 1 │ the,lamba,queen ║ +╟───┼──────────────────────╢ +║ 2 │ I,love,the,hat ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.startswith.md b/api-reference copy/series/series.str.startswith.md new file mode 100644 index 0000000..835809e --- /dev/null +++ b/api-reference copy/series/series.str.startswith.md @@ -0,0 +1,51 @@ +--- +description: Test whether a string begins with specified characters +--- + +# Series.str.startsWith + +> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| str | string | the character(s) to check | "" | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** Series (Boolean element) + +**Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.startsWith("S").print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ false ║ +╟───┼──────────────────────╢ +║ 1 │ false ║ +╟───┼──────────────────────╢ +║ 2 │ false ║ +╟───┼──────────────────────╢ +║ 3 │ true ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.substr.md b/api-reference copy/series/series.str.substr.md new file mode 100644 index 0000000..0a391bb --- /dev/null +++ b/api-reference copy/series/series.str.substr.md @@ -0,0 +1,50 @@ +--- +description: >- + Obtain the substring from a String element in a Series, by specifying the + number of string to obtain starting from a specific index. +--- + +# Series.str.substr + +> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| num | Number | The number of character to obtain starting from the startIndex | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + + **** return Series + +**Example** + +Obtain substring( containing 4 characters) starting from the third character (2nd index). + +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.substr(2, 4).print() +``` + +{% tabs %} +{% tab title="Output" %} +```javascript +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ wer ║ +╟───┼──────────────────────╢ +║ 1 │ APIT ║ +╟───┼──────────────────────╢ +║ 2 │ his ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp ║ +╚═══╧══════════════════════╝ + +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.substring.md b/api-reference copy/series/series.str.substring.md new file mode 100644 index 0000000..b54702e --- /dev/null +++ b/api-reference copy/series/series.str.substring.md @@ -0,0 +1,56 @@ +--- +description: Obtain the substring of each element in a series +--- + +# Series.str.substring + +> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| startIndex | Number | specify the index to start obtaining the substring | 0 | +| endIndex | Number | specify the index to end the substring | 1 | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns** + + **** return **Series** + +**Example** + +Obtain the substring from index 2 to index 4 of the string elements in a Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.substring(2, 4).print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ we ║ +╟───┼──────────────────────╢ +║ 1 │ AP ║ +╟───┼──────────────────────╢ +║ 2 │ hi ║ +╟───┼──────────────────────╢ +║ 3 │ Sw ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.tolowercase.md b/api-reference copy/series/series.str.tolowercase.md new file mode 100644 index 0000000..9abe0f5 --- /dev/null +++ b/api-reference copy/series/series.str.tolowercase.md @@ -0,0 +1,50 @@ +--- +description: Converts all characters to lower case. +--- + +# Series.str.toLowerCase + +> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Example** + +Convert all characters in each string element to small letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['LOWER BOY', 'CAPITALS', 'SENTENCE', 'SWAPCASE'] +let sf = new dfd.Series(data) +sf.str.toLowerCase().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower boy ║ +╟───┼──────────────────────╢ +║ 1 │ capitals ║ +╟───┼──────────────────────╢ +║ 2 │ sentence ║ +╟───┼──────────────────────╢ +║ 3 │ swapcase ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.touppercase.md b/api-reference copy/series/series.str.touppercase.md new file mode 100644 index 0000000..f484390 --- /dev/null +++ b/api-reference copy/series/series.str.touppercase.md @@ -0,0 +1,52 @@ +--- +description: Converts all characters to uppercase. +--- + +# Series.str.toUpperCase + +> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns**: Series (String element) + +**Example** + +Convert all characters in each string element to capital letter + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] +let sf = new dfd.Series(data) +sf.str.toUpperCase().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ LOWER BOY ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS ║ +╟───┼──────────────────────╢ +║ 2 │ SENTENCE ║ +╟───┼──────────────────────╢ +║ 3 │ SWAPCASE ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.str.trim.md b/api-reference copy/series/series.str.trim.md new file mode 100644 index 0000000..58b7b16 --- /dev/null +++ b/api-reference copy/series/series.str.trim.md @@ -0,0 +1,50 @@ +--- +description: Remove leading and trailing Whitespace from a String element +--- + +# Series.str.trim + +> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| + +**Returns:** + + **** return Series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] +let sf = new dfd.Series(data) +sf.str.trim().print() +``` +{% endtab %} + +{% tab title="Browser" %} +``` +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ lower part ║ +╟───┼──────────────────────╢ +║ 1 │ CAPITALS city ║ +╟───┼──────────────────────╢ +║ 2 │ this is a sentence ║ +╟───┼──────────────────────╢ +║ 3 │ SwAp CaSe ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.sub.md b/api-reference copy/series/series.sub.md new file mode 100644 index 0000000..e281d06 --- /dev/null +++ b/api-reference copy/series/series.sub.md @@ -0,0 +1,86 @@ +--- +description: Return Subtraction of series and other, element-wise (binary operator sub). +--- + +# Series.sub + +> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] + +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | +| other | Series\|int\| | values | | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| + +**Return:** Series + +**Example** + +subtract from values of another series + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30, 40, 3, 5] +let data2 = [1, 2, 3, 4] +let sf1 = new dfd.Series(data1) +let sf2 = new dfd.Series(data2) +sf1.sub(sf2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 29 ║ +╟───┼──────────────────────╢ +║ 1 │ 38 ║ +╟───┼──────────────────────╢ +║ 2 │ 0 ║ +╟───┼──────────────────────╢ +║ 3 │ 1 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + +subtract from a value + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5] +let sf1 = new dfd.Series(data1) + +sf1.sub(2).print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ -1 ║ +╟───┼──────────────────────╢ +║ 1 │ 0 ║ +╟───┼──────────────────────╢ +║ 2 │ 1 ║ +╟───┼──────────────────────╢ +║ 3 │ 2 ║ +╟───┼──────────────────────╢ +║ 4 │ 3 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.sum.md b/api-reference copy/series/series.sum.md new file mode 100644 index 0000000..fabcba7 --- /dev/null +++ b/api-reference copy/series/series.sum.md @@ -0,0 +1,36 @@ +--- +description: Return the sum of the values in a series. +--- + +# Series.sum + +> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.sum()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +207 +``` +{% endtab %} +{% endtabs %} + +**** diff --git a/api-reference copy/series/series.tail.md b/api-reference copy/series/series.tail.md new file mode 100644 index 0000000..7f986a1 --- /dev/null +++ b/api-reference copy/series/series.tail.md @@ -0,0 +1,49 @@ +--- +description: Prints the last n values in a Series +--- + +# Series.tail + +> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] + +| Parameters | Type | Description | Default | +| :--- | :--- | :--- | :--- | +| rows | Int | number of last n values | 5 | + + **Return:** Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] +let sf1 = new dfd.Series(data1) + +sf1.tail().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔════╤══════════════════════╗ +║ │ 0 ║ +╟────┼──────────────────────╢ +║ 6 │ 30 ║ +╟────┼──────────────────────╢ +║ 7 │ 40 ║ +╟────┼──────────────────────╢ +║ 8 │ 39 ║ +╟────┼──────────────────────╢ +║ 9 │ 89 ║ +╟────┼──────────────────────╢ +║ 10 │ 78 ║ +╚════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.tensor.md b/api-reference copy/series/series.tensor.md new file mode 100644 index 0000000..a5c112c --- /dev/null +++ b/api-reference copy/series/series.tensor.md @@ -0,0 +1,46 @@ +--- +description: Obtain the tensor representation of the values in a Series +--- + +# Series.tensor + +> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] + +**Parameters**: None + +**Returns**: Tensorflow tensor + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.tensor) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 4 ], + dtype: 'float32', + size: 4, + strides: [], + dataId: {}, + id: 2, + rankType: '1', + scopeId: 0 +} +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.unique.md b/api-reference copy/series/series.unique.md new file mode 100644 index 0000000..c89d187 --- /dev/null +++ b/api-reference copy/series/series.unique.md @@ -0,0 +1,55 @@ +--- +description: Obtain the unique value in a Series +--- + +# Series.unique + +> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] + +**Parameters**: None + +**Returns**: Series + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +sf.unique().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +╔═══╤══════════════════════╗ +║ │ 0 ║ +╟───┼──────────────────────╢ +║ 0 │ 1 ║ +╟───┼──────────────────────╢ +║ 1 │ 2 ║ +╟───┼──────────────────────╢ +║ 2 │ 3 ║ +╟───┼──────────────────────╢ +║ 3 │ 4 ║ +╟───┼──────────────────────╢ +║ 4 │ 5 ║ +╟───┼──────────────────────╢ +║ 5 │ 6 ║ +╟───┼──────────────────────╢ +║ 6 │ 7 ║ +╟───┼──────────────────────╢ +║ 7 │ 8 ║ +╟───┼──────────────────────╢ +║ 8 │ 22 ║ +╚═══╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.value_counts.md b/api-reference copy/series/series.value_counts.md new file mode 100644 index 0000000..338064f --- /dev/null +++ b/api-reference copy/series/series.value_counts.md @@ -0,0 +1,54 @@ +--- +description: Count the number of occurrence for each element in a Series +--- + +# Series.value\_counts + +> danfo.Series.value\_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] + +**Parameters:** None + +**Returns:** Series (int element) + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] +let sf = new dfd.Series(data1) + +sf.value_counts().print() +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +╔════╤══════════════════════╗ +║ │ 0 ║ +╟────┼──────────────────────╢ +║ 1 │ 3 ║ +╟────┼──────────────────────╢ +║ 2 │ 1 ║ +╟────┼──────────────────────╢ +║ 3 │ 1 ║ +╟────┼──────────────────────╢ +║ 4 │ 1 ║ +╟────┼──────────────────────╢ +║ 5 │ 4 ║ +╟────┼──────────────────────╢ +║ 6 │ 1 ║ +╟────┼──────────────────────╢ +║ 7 │ 1 ║ +╟────┼──────────────────────╢ +║ 8 │ 2 ║ +╟────┼──────────────────────╢ +║ 22 │ 1 ║ +╚════╧══════════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference copy/series/series.values.md b/api-reference copy/series/series.values.md new file mode 100644 index 0000000..4857487 --- /dev/null +++ b/api-reference copy/series/series.values.md @@ -0,0 +1,35 @@ +--- +description: Obtain the values in a series +--- + +# Series.values + +> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] + +**Parameters:** None + +**Returns**: Array + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [30.21091, 40.190901, 3.564, 5.0212] +let sf1 = new dfd.Series(data1) + +console.log(sf1.values) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +[ 30.21091, 40.190901, 3.564, 5.0212 ] +``` +{% endtab %} +{% endtabs %} + diff --git a/api-reference copy/series/series.var.md b/api-reference copy/series/series.var.md new file mode 100644 index 0000000..4fdcbc2 --- /dev/null +++ b/api-reference copy/series/series.var.md @@ -0,0 +1,35 @@ +--- +description: Calculate the variance of a Series +--- + +# Series.var + +> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] + +**Parameter:** None + +**Return:** Number + +**Example** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] +let sf1 = new dfd.Series(data1) + +console.log(sf1.var()) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +```text +968.25 +``` +{% endtab %} +{% endtabs %} + From f31f4f02fdf8ffcb52689ded68dc1fe87a1618d6 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 2 Jan 2022 22:07:44 +0100 Subject: [PATCH 158/202] Update ts doc folder --- {api-reference copy => api-reference-v1-stable}/README.md | 0 .../configuration-options.md | 0 .../dataframe/README.md | 0 .../dataframe/creating-a-dataframe.md | 0 .../dataframe/danfo.dataframe.abs.md | 0 .../dataframe/danfo.dataframe.add.md | 0 .../dataframe/danfo.dataframe.addcolumn.md | 0 .../dataframe/danfo.dataframe.apply.md | 0 .../dataframe/danfo.dataframe.column.md | 0 .../dataframe/danfo.dataframe.copy.md | 0 .../dataframe/danfo.dataframe.count.md | 0 .../dataframe/danfo.dataframe.cummax.md | 0 .../dataframe/danfo.dataframe.cummin.md | 0 .../dataframe/danfo.dataframe.cumprod.md | 0 .../dataframe/danfo.dataframe.cumsum.md | 0 .../dataframe/danfo.dataframe.describe.md | 0 .../dataframe/danfo.dataframe.div.md | 0 .../dataframe/danfo.dataframe.dropna.md | 0 .../dataframe/danfo.dataframe.eq.md | 0 .../dataframe/danfo.dataframe.fillna.md | 0 .../dataframe/danfo.dataframe.ge.md | 0 .../dataframe/danfo.dataframe.groupby.md | 0 .../dataframe/danfo.dataframe.gt.md | 0 .../dataframe/danfo.dataframe.head.md | 0 .../dataframe/danfo.dataframe.iloc.md | 0 .../dataframe/danfo.dataframe.isna.md | 0 .../dataframe/danfo.dataframe.it.md | 0 .../dataframe/danfo.dataframe.le.md | 0 .../dataframe/danfo.dataframe.loc.md | 0 .../dataframe/danfo.dataframe.max.md | 0 .../dataframe/danfo.dataframe.mean.md | 0 .../dataframe/danfo.dataframe.median.md | 0 .../dataframe/danfo.dataframe.min.md | 0 .../dataframe/danfo.dataframe.mod.md | 0 .../dataframe/danfo.dataframe.mul.md | 0 .../dataframe/danfo.dataframe.ne.md | 0 .../dataframe/danfo.dataframe.pow.md | 0 .../dataframe/danfo.dataframe.query.md | 0 .../dataframe/danfo.dataframe.replace.md | 0 .../dataframe/danfo.dataframe.round.md | 0 .../dataframe/danfo.dataframe.sample.md | 0 .../dataframe/danfo.dataframe.std.md | 0 .../dataframe/danfo.dataframe.sub.md | 0 .../dataframe/danfo.dataframe.sum.md | 0 .../dataframe/danfo.dataframe.tail.md | 0 .../dataframe/danfo.dataframe.var.md | 0 .../dataframe/dataframe.append.md | 0 .../dataframe/dataframe.apply_map.md | 0 .../dataframe/dataframe.astype.md | 0 .../dataframe/dataframe.axes.md | 0 .../dataframe/dataframe.drop.md | 0 .../dataframe/dataframe.dtypes.md | 0 .../dataframe/dataframe.index.md | 0 .../dataframe/dataframe.ndim.md | 0 .../dataframe/dataframe.nunique-1.md | 0 .../dataframe/dataframe.print.md | 0 .../dataframe/dataframe.rename.md | 0 .../dataframe/dataframe.reset_index.md | 0 .../dataframe/dataframe.select_dtypes.md | 0 .../dataframe/dataframe.set_index.md | 0 .../dataframe/dataframe.shape.md | 0 .../dataframe/dataframe.sort_index.md | 0 .../dataframe/dataframe.sort_values.md | 0 .../dataframe/dataframe.tensor.md | 0 .../dataframe/dataframe.to_csv.md | 0 .../dataframe/dataframe.to_excel.md | 0 .../dataframe/dataframe.to_json.md | 0 .../dataframe/dataframe.values.md | 0 .../general-functions/README.md | 0 .../general-functions/danfo.concat.md | 0 .../general-functions/danfo.date_range.md | 0 .../general-functions/danfo.get_dummies.md | 0 .../general-functions/danfo.labelencoder.md | 0 .../general-functions/danfo.merge.md | 0 .../general-functions/danfo.minmaxscaler.md | 0 .../general-functions/danfo.onehotencoder.md | 0 .../general-functions/danfo.standardscaler.md | 0 .../general-functions/danfo.to_datetime.md | 0 {api-reference copy => api-reference-v1-stable}/groupby.md | 0 {api-reference copy => api-reference-v1-stable}/groupby/README.md | 0 .../groupby/groupby.agg.md | 0 .../groupby/groupby.apply.md | 0 .../groupby/groupby.col.md | 0 .../groupby/groupby.count.md | 0 .../groupby/groupby.cummax.md | 0 .../groupby/groupby.cummin.md | 0 .../groupby/groupby.cumprod.md | 0 .../groupby/groupby.cumsum.md | 0 .../groupby/groupby.get_groups.md | 0 .../groupby/groupby.max.md | 0 .../groupby/groupby.mean.md | 0 .../groupby/groupby.min.md | 0 .../groupby/groupby.std.md | 0 .../groupby/groupby.sum.md | 0 .../groupby/groupby.var.md | 0 .../input-output/README.md | 0 .../input-output/danfo.read_csv.md | 0 .../input-output/danfo.read_excel.md | 0 .../input-output/danfo.read_json.md | 0 .../input-output/danfo.to_csv.md | 0 .../input-output/danfo.to_excel.md | 0 .../input-output/danfo.to_json.md | 0 .../input-output/read.md | 0 .../plotting/README.md | 0 .../plotting/bar-charts.md | 0 .../plotting/box-plots.md | 0 .../plotting/configuring-your-plots.md | 0 .../plotting/histograms.md | 0 .../plotting/line-charts.md | 0 .../plotting/pie-charts.md | 0 .../plotting/scatter-plots.md | 0 .../plotting/tables.md | 0 .../plotting/timeseries-plots.md | 0 .../plotting/violin-plots.md | 0 {api-reference copy => api-reference-v1-stable}/series/README.md | 0 .../series/creating-a-series.md | 0 .../series/danfo.series.add.md | 0 .../series/danfo.series.apply.md | 0 .../series/danfo.series.copy.md | 0 .../series/danfo.series.count.md | 0 .../series/danfo.series.describe.md | 0 .../series/danfo.series.div.md | 0 .../series/danfo.series.head.md | 0 .../series/danfo.series.map.md | 0 .../series/danfo.series.max.md | 0 .../series/danfo.series.maximum.md | 0 .../series/danfo.series.mean.md | 0 .../series/danfo.series.median.md | 0 .../series/danfo.series.min.md | 0 .../series/danfo.series.minimum.md | 0 .../series/danfo.series.mod.md | 0 .../series/danfo.series.mode.md | 0 .../series/danfo.series.mul.md | 0 .../series/danfo.series.pow.md | 0 .../series/danfo.series.reset_index.md | 0 .../series/danfo.series.round.md | 0 .../series/danfo.series.sample.md | 0 .../series/danfo.series.set_index.md | 0 .../series/danfo.series.sort_values.md | 0 .../series/danfo.series.std.md | 0 .../series/danfo.series.sub.md | 0 .../series/danfo.series.sum-1.md | 0 .../series/danfo.series.tail.md | 0 .../series/danfo.series.tostring.md | 0 .../series/danfo.series.var.md | 0 .../series/series.abs.md | 0 .../series/series.add.md | 0 .../series/series.and.md | 0 .../series/series.append.md | 0 .../series/series.apply.md | 0 .../series/series.argmax.md | 0 .../series/series.argmin.md | 0 .../series/series.argsort.md | 0 .../series/series.astype.md | 0 .../series/series.copy.md | 0 .../series/series.corr.md | 0 .../series/series.count.md | 0 .../series/series.cummax.md | 0 .../series/series.cummin.md | 0 .../series/series.cumprod.md | 0 .../series/series.cumsum.md | 0 .../series/series.describe.md | 0 .../series/series.div.md | 0 .../series/series.dot.md | 0 .../series/series.drop_duplicates.md | 0 .../series/series.dropna.md | 0 .../series/series.dt.day.md | 0 .../series/series.dt.hour.md | 0 .../series/series.dt.minute.md | 0 .../series/series.dt.month.md | 0 .../series/series.dt.month_name.md | 0 .../series/series.dt.monthday.md | 0 .../series/series.dt.second.md | 0 .../series/series.dt.weekdays.md | 0 .../series/series.dt.year.md | 0 .../series/series.dtype.md | 0 .../series/series.eq.md | 0 .../series/series.fillna.md | 0 .../series/series.ge.md | 0 .../series/series.gt.md | 0 .../series/series.head.md | 0 .../series/series.iloc.md | 0 .../series/series.index.md | 0 .../series/series.isna.md | 0 .../series/series.le.md | 0 .../series/series.loc.md | 0 .../series/series.lt.md | 0 .../series/series.map.md | 0 .../series/series.max.md | 0 .../series/series.maximum.md | 0 .../series/series.mean.md | 0 .../series/series.median.md | 0 .../series/series.min.md | 0 .../series/series.minimum.md | 0 .../series/series.mod.md | 0 .../series/series.mode.md | 0 .../series/series.mul.md | 0 .../series/series.ndim.md | 0 .../series/series.ne.md | 0 .../series/series.nunique.md | 0 .../series/series.or.md | 0 .../series/series.pow.md | 0 .../series/series.replace.md | 0 .../series/series.reset_index.md | 0 .../series/series.round.md | 0 .../series/series.sample.md | 0 .../series/series.set_index.md | 0 .../series/series.shape.md | 0 .../series/series.size.md | 0 .../series/series.sort_values.md | 0 .../series/series.std.md | 0 .../series/series.str.capitalize.md | 0 .../series/series.str.charat.md | 0 .../series/series.str.concat.md | 0 .../series/series.str.endswith.md | 0 .../series/series.str.includes.md | 0 .../series/series.str.indexof.md | 0 .../series/series.str.join.md | 0 .../series/series.str.lastindexof.md | 0 .../series/series.str.len.md | 0 .../series/series.str.repeat.md | 0 .../series/series.str.replace.md | 0 .../series/series.str.search.md | 0 .../series/series.str.slice.md | 0 .../series/series.str.split.md | 0 .../series/series.str.startswith.md | 0 .../series/series.str.substr.md | 0 .../series/series.str.substring.md | 0 .../series/series.str.tolowercase.md | 0 .../series/series.str.touppercase.md | 0 .../series/series.str.trim.md | 0 .../series/series.sub.md | 0 .../series/series.sum.md | 0 .../series/series.tail.md | 0 .../series/series.tensor.md | 0 .../series/series.unique.md | 0 .../series/series.value_counts.md | 0 .../series/series.values.md | 0 .../series/series.var.md | 0 239 files changed, 0 insertions(+), 0 deletions(-) rename {api-reference copy => api-reference-v1-stable}/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/configuration-options.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/creating-a-dataframe.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.abs.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.add.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.addcolumn.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.apply.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.column.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.copy.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.count.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.cummax.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.cummin.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.cumprod.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.cumsum.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.describe.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.div.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.dropna.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.eq.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.fillna.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.ge.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.groupby.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.gt.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.head.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.iloc.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.isna.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.it.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.le.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.loc.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.max.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.mean.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.median.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.min.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.mod.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.mul.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.ne.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.pow.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.query.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.replace.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.round.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.sample.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.std.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.sub.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.sum.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.tail.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/danfo.dataframe.var.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.append.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.apply_map.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.astype.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.axes.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.drop.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.dtypes.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.index.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.ndim.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.nunique-1.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.print.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.rename.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.reset_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.select_dtypes.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.set_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.shape.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.sort_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.sort_values.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.tensor.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.to_csv.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.to_excel.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.to_json.md (100%) rename {api-reference copy => api-reference-v1-stable}/dataframe/dataframe.values.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.concat.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.date_range.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.get_dummies.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.labelencoder.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.merge.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.minmaxscaler.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.onehotencoder.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.standardscaler.md (100%) rename {api-reference copy => api-reference-v1-stable}/general-functions/danfo.to_datetime.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.agg.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.apply.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.col.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.count.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.cummax.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.cummin.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.cumprod.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.cumsum.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.get_groups.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.max.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.mean.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.min.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.std.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.sum.md (100%) rename {api-reference copy => api-reference-v1-stable}/groupby/groupby.var.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.read_csv.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.read_excel.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.read_json.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.to_csv.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.to_excel.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/danfo.to_json.md (100%) rename {api-reference copy => api-reference-v1-stable}/input-output/read.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/bar-charts.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/box-plots.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/configuring-your-plots.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/histograms.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/line-charts.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/pie-charts.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/scatter-plots.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/tables.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/timeseries-plots.md (100%) rename {api-reference copy => api-reference-v1-stable}/plotting/violin-plots.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/README.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/creating-a-series.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.add.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.apply.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.copy.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.count.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.describe.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.div.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.head.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.map.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.max.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.maximum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.mean.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.median.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.min.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.minimum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.mod.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.mode.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.mul.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.pow.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.reset_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.round.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.sample.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.set_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.sort_values.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.std.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.sub.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.sum-1.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.tail.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.tostring.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/danfo.series.var.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.abs.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.add.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.and.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.append.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.apply.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.argmax.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.argmin.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.argsort.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.astype.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.copy.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.corr.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.count.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.cummax.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.cummin.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.cumprod.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.cumsum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.describe.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.div.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dot.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.drop_duplicates.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dropna.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.day.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.hour.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.minute.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.month.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.month_name.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.monthday.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.second.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.weekdays.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dt.year.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.dtype.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.eq.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.fillna.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.ge.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.gt.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.head.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.iloc.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.index.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.isna.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.le.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.loc.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.lt.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.map.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.max.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.maximum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.mean.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.median.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.min.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.minimum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.mod.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.mode.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.mul.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.ndim.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.ne.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.nunique.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.or.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.pow.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.replace.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.reset_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.round.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.sample.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.set_index.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.shape.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.size.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.sort_values.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.std.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.capitalize.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.charat.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.concat.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.endswith.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.includes.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.indexof.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.join.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.lastindexof.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.len.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.repeat.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.replace.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.search.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.slice.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.split.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.startswith.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.substr.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.substring.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.tolowercase.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.touppercase.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.str.trim.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.sub.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.sum.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.tail.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.tensor.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.unique.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.value_counts.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.values.md (100%) rename {api-reference copy => api-reference-v1-stable}/series/series.var.md (100%) diff --git a/api-reference copy/README.md b/api-reference-v1-stable/README.md similarity index 100% rename from api-reference copy/README.md rename to api-reference-v1-stable/README.md diff --git a/api-reference copy/configuration-options.md b/api-reference-v1-stable/configuration-options.md similarity index 100% rename from api-reference copy/configuration-options.md rename to api-reference-v1-stable/configuration-options.md diff --git a/api-reference copy/dataframe/README.md b/api-reference-v1-stable/dataframe/README.md similarity index 100% rename from api-reference copy/dataframe/README.md rename to api-reference-v1-stable/dataframe/README.md diff --git a/api-reference copy/dataframe/creating-a-dataframe.md b/api-reference-v1-stable/dataframe/creating-a-dataframe.md similarity index 100% rename from api-reference copy/dataframe/creating-a-dataframe.md rename to api-reference-v1-stable/dataframe/creating-a-dataframe.md diff --git a/api-reference copy/dataframe/danfo.dataframe.abs.md b/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.abs.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.abs.md diff --git a/api-reference copy/dataframe/danfo.dataframe.add.md b/api-reference-v1-stable/dataframe/danfo.dataframe.add.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.add.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.add.md diff --git a/api-reference copy/dataframe/danfo.dataframe.addcolumn.md b/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.addcolumn.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md diff --git a/api-reference copy/dataframe/danfo.dataframe.apply.md b/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.apply.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.apply.md diff --git a/api-reference copy/dataframe/danfo.dataframe.column.md b/api-reference-v1-stable/dataframe/danfo.dataframe.column.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.column.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.column.md diff --git a/api-reference copy/dataframe/danfo.dataframe.copy.md b/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.copy.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.copy.md diff --git a/api-reference copy/dataframe/danfo.dataframe.count.md b/api-reference-v1-stable/dataframe/danfo.dataframe.count.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.count.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.count.md diff --git a/api-reference copy/dataframe/danfo.dataframe.cummax.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.cummax.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md diff --git a/api-reference copy/dataframe/danfo.dataframe.cummin.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.cummin.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md diff --git a/api-reference copy/dataframe/danfo.dataframe.cumprod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.cumprod.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md diff --git a/api-reference copy/dataframe/danfo.dataframe.cumsum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.cumsum.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md diff --git a/api-reference copy/dataframe/danfo.dataframe.describe.md b/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.describe.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.describe.md diff --git a/api-reference copy/dataframe/danfo.dataframe.div.md b/api-reference-v1-stable/dataframe/danfo.dataframe.div.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.div.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.div.md diff --git a/api-reference copy/dataframe/danfo.dataframe.dropna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.dropna.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md diff --git a/api-reference copy/dataframe/danfo.dataframe.eq.md b/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.eq.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.eq.md diff --git a/api-reference copy/dataframe/danfo.dataframe.fillna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.fillna.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md diff --git a/api-reference copy/dataframe/danfo.dataframe.ge.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.ge.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.ge.md diff --git a/api-reference copy/dataframe/danfo.dataframe.groupby.md b/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.groupby.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md diff --git a/api-reference copy/dataframe/danfo.dataframe.gt.md b/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.gt.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.gt.md diff --git a/api-reference copy/dataframe/danfo.dataframe.head.md b/api-reference-v1-stable/dataframe/danfo.dataframe.head.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.head.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.head.md diff --git a/api-reference copy/dataframe/danfo.dataframe.iloc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.iloc.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md diff --git a/api-reference copy/dataframe/danfo.dataframe.isna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.isna.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.isna.md diff --git a/api-reference copy/dataframe/danfo.dataframe.it.md b/api-reference-v1-stable/dataframe/danfo.dataframe.it.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.it.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.it.md diff --git a/api-reference copy/dataframe/danfo.dataframe.le.md b/api-reference-v1-stable/dataframe/danfo.dataframe.le.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.le.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.le.md diff --git a/api-reference copy/dataframe/danfo.dataframe.loc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.loc.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.loc.md diff --git a/api-reference copy/dataframe/danfo.dataframe.max.md b/api-reference-v1-stable/dataframe/danfo.dataframe.max.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.max.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.max.md diff --git a/api-reference copy/dataframe/danfo.dataframe.mean.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.mean.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.mean.md diff --git a/api-reference copy/dataframe/danfo.dataframe.median.md b/api-reference-v1-stable/dataframe/danfo.dataframe.median.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.median.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.median.md diff --git a/api-reference copy/dataframe/danfo.dataframe.min.md b/api-reference-v1-stable/dataframe/danfo.dataframe.min.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.min.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.min.md diff --git a/api-reference copy/dataframe/danfo.dataframe.mod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.mod.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.mod.md diff --git a/api-reference copy/dataframe/danfo.dataframe.mul.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.mul.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.mul.md diff --git a/api-reference copy/dataframe/danfo.dataframe.ne.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.ne.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.ne.md diff --git a/api-reference copy/dataframe/danfo.dataframe.pow.md b/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.pow.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.pow.md diff --git a/api-reference copy/dataframe/danfo.dataframe.query.md b/api-reference-v1-stable/dataframe/danfo.dataframe.query.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.query.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.query.md diff --git a/api-reference copy/dataframe/danfo.dataframe.replace.md b/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.replace.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.replace.md diff --git a/api-reference copy/dataframe/danfo.dataframe.round.md b/api-reference-v1-stable/dataframe/danfo.dataframe.round.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.round.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.round.md diff --git a/api-reference copy/dataframe/danfo.dataframe.sample.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.sample.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.sample.md diff --git a/api-reference copy/dataframe/danfo.dataframe.std.md b/api-reference-v1-stable/dataframe/danfo.dataframe.std.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.std.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.std.md diff --git a/api-reference copy/dataframe/danfo.dataframe.sub.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.sub.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.sub.md diff --git a/api-reference copy/dataframe/danfo.dataframe.sum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.sum.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.sum.md diff --git a/api-reference copy/dataframe/danfo.dataframe.tail.md b/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.tail.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.tail.md diff --git a/api-reference copy/dataframe/danfo.dataframe.var.md b/api-reference-v1-stable/dataframe/danfo.dataframe.var.md similarity index 100% rename from api-reference copy/dataframe/danfo.dataframe.var.md rename to api-reference-v1-stable/dataframe/danfo.dataframe.var.md diff --git a/api-reference copy/dataframe/dataframe.append.md b/api-reference-v1-stable/dataframe/dataframe.append.md similarity index 100% rename from api-reference copy/dataframe/dataframe.append.md rename to api-reference-v1-stable/dataframe/dataframe.append.md diff --git a/api-reference copy/dataframe/dataframe.apply_map.md b/api-reference-v1-stable/dataframe/dataframe.apply_map.md similarity index 100% rename from api-reference copy/dataframe/dataframe.apply_map.md rename to api-reference-v1-stable/dataframe/dataframe.apply_map.md diff --git a/api-reference copy/dataframe/dataframe.astype.md b/api-reference-v1-stable/dataframe/dataframe.astype.md similarity index 100% rename from api-reference copy/dataframe/dataframe.astype.md rename to api-reference-v1-stable/dataframe/dataframe.astype.md diff --git a/api-reference copy/dataframe/dataframe.axes.md b/api-reference-v1-stable/dataframe/dataframe.axes.md similarity index 100% rename from api-reference copy/dataframe/dataframe.axes.md rename to api-reference-v1-stable/dataframe/dataframe.axes.md diff --git a/api-reference copy/dataframe/dataframe.drop.md b/api-reference-v1-stable/dataframe/dataframe.drop.md similarity index 100% rename from api-reference copy/dataframe/dataframe.drop.md rename to api-reference-v1-stable/dataframe/dataframe.drop.md diff --git a/api-reference copy/dataframe/dataframe.dtypes.md b/api-reference-v1-stable/dataframe/dataframe.dtypes.md similarity index 100% rename from api-reference copy/dataframe/dataframe.dtypes.md rename to api-reference-v1-stable/dataframe/dataframe.dtypes.md diff --git a/api-reference copy/dataframe/dataframe.index.md b/api-reference-v1-stable/dataframe/dataframe.index.md similarity index 100% rename from api-reference copy/dataframe/dataframe.index.md rename to api-reference-v1-stable/dataframe/dataframe.index.md diff --git a/api-reference copy/dataframe/dataframe.ndim.md b/api-reference-v1-stable/dataframe/dataframe.ndim.md similarity index 100% rename from api-reference copy/dataframe/dataframe.ndim.md rename to api-reference-v1-stable/dataframe/dataframe.ndim.md diff --git a/api-reference copy/dataframe/dataframe.nunique-1.md b/api-reference-v1-stable/dataframe/dataframe.nunique-1.md similarity index 100% rename from api-reference copy/dataframe/dataframe.nunique-1.md rename to api-reference-v1-stable/dataframe/dataframe.nunique-1.md diff --git a/api-reference copy/dataframe/dataframe.print.md b/api-reference-v1-stable/dataframe/dataframe.print.md similarity index 100% rename from api-reference copy/dataframe/dataframe.print.md rename to api-reference-v1-stable/dataframe/dataframe.print.md diff --git a/api-reference copy/dataframe/dataframe.rename.md b/api-reference-v1-stable/dataframe/dataframe.rename.md similarity index 100% rename from api-reference copy/dataframe/dataframe.rename.md rename to api-reference-v1-stable/dataframe/dataframe.rename.md diff --git a/api-reference copy/dataframe/dataframe.reset_index.md b/api-reference-v1-stable/dataframe/dataframe.reset_index.md similarity index 100% rename from api-reference copy/dataframe/dataframe.reset_index.md rename to api-reference-v1-stable/dataframe/dataframe.reset_index.md diff --git a/api-reference copy/dataframe/dataframe.select_dtypes.md b/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md similarity index 100% rename from api-reference copy/dataframe/dataframe.select_dtypes.md rename to api-reference-v1-stable/dataframe/dataframe.select_dtypes.md diff --git a/api-reference copy/dataframe/dataframe.set_index.md b/api-reference-v1-stable/dataframe/dataframe.set_index.md similarity index 100% rename from api-reference copy/dataframe/dataframe.set_index.md rename to api-reference-v1-stable/dataframe/dataframe.set_index.md diff --git a/api-reference copy/dataframe/dataframe.shape.md b/api-reference-v1-stable/dataframe/dataframe.shape.md similarity index 100% rename from api-reference copy/dataframe/dataframe.shape.md rename to api-reference-v1-stable/dataframe/dataframe.shape.md diff --git a/api-reference copy/dataframe/dataframe.sort_index.md b/api-reference-v1-stable/dataframe/dataframe.sort_index.md similarity index 100% rename from api-reference copy/dataframe/dataframe.sort_index.md rename to api-reference-v1-stable/dataframe/dataframe.sort_index.md diff --git a/api-reference copy/dataframe/dataframe.sort_values.md b/api-reference-v1-stable/dataframe/dataframe.sort_values.md similarity index 100% rename from api-reference copy/dataframe/dataframe.sort_values.md rename to api-reference-v1-stable/dataframe/dataframe.sort_values.md diff --git a/api-reference copy/dataframe/dataframe.tensor.md b/api-reference-v1-stable/dataframe/dataframe.tensor.md similarity index 100% rename from api-reference copy/dataframe/dataframe.tensor.md rename to api-reference-v1-stable/dataframe/dataframe.tensor.md diff --git a/api-reference copy/dataframe/dataframe.to_csv.md b/api-reference-v1-stable/dataframe/dataframe.to_csv.md similarity index 100% rename from api-reference copy/dataframe/dataframe.to_csv.md rename to api-reference-v1-stable/dataframe/dataframe.to_csv.md diff --git a/api-reference copy/dataframe/dataframe.to_excel.md b/api-reference-v1-stable/dataframe/dataframe.to_excel.md similarity index 100% rename from api-reference copy/dataframe/dataframe.to_excel.md rename to api-reference-v1-stable/dataframe/dataframe.to_excel.md diff --git a/api-reference copy/dataframe/dataframe.to_json.md b/api-reference-v1-stable/dataframe/dataframe.to_json.md similarity index 100% rename from api-reference copy/dataframe/dataframe.to_json.md rename to api-reference-v1-stable/dataframe/dataframe.to_json.md diff --git a/api-reference copy/dataframe/dataframe.values.md b/api-reference-v1-stable/dataframe/dataframe.values.md similarity index 100% rename from api-reference copy/dataframe/dataframe.values.md rename to api-reference-v1-stable/dataframe/dataframe.values.md diff --git a/api-reference copy/general-functions/README.md b/api-reference-v1-stable/general-functions/README.md similarity index 100% rename from api-reference copy/general-functions/README.md rename to api-reference-v1-stable/general-functions/README.md diff --git a/api-reference copy/general-functions/danfo.concat.md b/api-reference-v1-stable/general-functions/danfo.concat.md similarity index 100% rename from api-reference copy/general-functions/danfo.concat.md rename to api-reference-v1-stable/general-functions/danfo.concat.md diff --git a/api-reference copy/general-functions/danfo.date_range.md b/api-reference-v1-stable/general-functions/danfo.date_range.md similarity index 100% rename from api-reference copy/general-functions/danfo.date_range.md rename to api-reference-v1-stable/general-functions/danfo.date_range.md diff --git a/api-reference copy/general-functions/danfo.get_dummies.md b/api-reference-v1-stable/general-functions/danfo.get_dummies.md similarity index 100% rename from api-reference copy/general-functions/danfo.get_dummies.md rename to api-reference-v1-stable/general-functions/danfo.get_dummies.md diff --git a/api-reference copy/general-functions/danfo.labelencoder.md b/api-reference-v1-stable/general-functions/danfo.labelencoder.md similarity index 100% rename from api-reference copy/general-functions/danfo.labelencoder.md rename to api-reference-v1-stable/general-functions/danfo.labelencoder.md diff --git a/api-reference copy/general-functions/danfo.merge.md b/api-reference-v1-stable/general-functions/danfo.merge.md similarity index 100% rename from api-reference copy/general-functions/danfo.merge.md rename to api-reference-v1-stable/general-functions/danfo.merge.md diff --git a/api-reference copy/general-functions/danfo.minmaxscaler.md b/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md similarity index 100% rename from api-reference copy/general-functions/danfo.minmaxscaler.md rename to api-reference-v1-stable/general-functions/danfo.minmaxscaler.md diff --git a/api-reference copy/general-functions/danfo.onehotencoder.md b/api-reference-v1-stable/general-functions/danfo.onehotencoder.md similarity index 100% rename from api-reference copy/general-functions/danfo.onehotencoder.md rename to api-reference-v1-stable/general-functions/danfo.onehotencoder.md diff --git a/api-reference copy/general-functions/danfo.standardscaler.md b/api-reference-v1-stable/general-functions/danfo.standardscaler.md similarity index 100% rename from api-reference copy/general-functions/danfo.standardscaler.md rename to api-reference-v1-stable/general-functions/danfo.standardscaler.md diff --git a/api-reference copy/general-functions/danfo.to_datetime.md b/api-reference-v1-stable/general-functions/danfo.to_datetime.md similarity index 100% rename from api-reference copy/general-functions/danfo.to_datetime.md rename to api-reference-v1-stable/general-functions/danfo.to_datetime.md diff --git a/api-reference copy/groupby.md b/api-reference-v1-stable/groupby.md similarity index 100% rename from api-reference copy/groupby.md rename to api-reference-v1-stable/groupby.md diff --git a/api-reference copy/groupby/README.md b/api-reference-v1-stable/groupby/README.md similarity index 100% rename from api-reference copy/groupby/README.md rename to api-reference-v1-stable/groupby/README.md diff --git a/api-reference copy/groupby/groupby.agg.md b/api-reference-v1-stable/groupby/groupby.agg.md similarity index 100% rename from api-reference copy/groupby/groupby.agg.md rename to api-reference-v1-stable/groupby/groupby.agg.md diff --git a/api-reference copy/groupby/groupby.apply.md b/api-reference-v1-stable/groupby/groupby.apply.md similarity index 100% rename from api-reference copy/groupby/groupby.apply.md rename to api-reference-v1-stable/groupby/groupby.apply.md diff --git a/api-reference copy/groupby/groupby.col.md b/api-reference-v1-stable/groupby/groupby.col.md similarity index 100% rename from api-reference copy/groupby/groupby.col.md rename to api-reference-v1-stable/groupby/groupby.col.md diff --git a/api-reference copy/groupby/groupby.count.md b/api-reference-v1-stable/groupby/groupby.count.md similarity index 100% rename from api-reference copy/groupby/groupby.count.md rename to api-reference-v1-stable/groupby/groupby.count.md diff --git a/api-reference copy/groupby/groupby.cummax.md b/api-reference-v1-stable/groupby/groupby.cummax.md similarity index 100% rename from api-reference copy/groupby/groupby.cummax.md rename to api-reference-v1-stable/groupby/groupby.cummax.md diff --git a/api-reference copy/groupby/groupby.cummin.md b/api-reference-v1-stable/groupby/groupby.cummin.md similarity index 100% rename from api-reference copy/groupby/groupby.cummin.md rename to api-reference-v1-stable/groupby/groupby.cummin.md diff --git a/api-reference copy/groupby/groupby.cumprod.md b/api-reference-v1-stable/groupby/groupby.cumprod.md similarity index 100% rename from api-reference copy/groupby/groupby.cumprod.md rename to api-reference-v1-stable/groupby/groupby.cumprod.md diff --git a/api-reference copy/groupby/groupby.cumsum.md b/api-reference-v1-stable/groupby/groupby.cumsum.md similarity index 100% rename from api-reference copy/groupby/groupby.cumsum.md rename to api-reference-v1-stable/groupby/groupby.cumsum.md diff --git a/api-reference copy/groupby/groupby.get_groups.md b/api-reference-v1-stable/groupby/groupby.get_groups.md similarity index 100% rename from api-reference copy/groupby/groupby.get_groups.md rename to api-reference-v1-stable/groupby/groupby.get_groups.md diff --git a/api-reference copy/groupby/groupby.max.md b/api-reference-v1-stable/groupby/groupby.max.md similarity index 100% rename from api-reference copy/groupby/groupby.max.md rename to api-reference-v1-stable/groupby/groupby.max.md diff --git a/api-reference copy/groupby/groupby.mean.md b/api-reference-v1-stable/groupby/groupby.mean.md similarity index 100% rename from api-reference copy/groupby/groupby.mean.md rename to api-reference-v1-stable/groupby/groupby.mean.md diff --git a/api-reference copy/groupby/groupby.min.md b/api-reference-v1-stable/groupby/groupby.min.md similarity index 100% rename from api-reference copy/groupby/groupby.min.md rename to api-reference-v1-stable/groupby/groupby.min.md diff --git a/api-reference copy/groupby/groupby.std.md b/api-reference-v1-stable/groupby/groupby.std.md similarity index 100% rename from api-reference copy/groupby/groupby.std.md rename to api-reference-v1-stable/groupby/groupby.std.md diff --git a/api-reference copy/groupby/groupby.sum.md b/api-reference-v1-stable/groupby/groupby.sum.md similarity index 100% rename from api-reference copy/groupby/groupby.sum.md rename to api-reference-v1-stable/groupby/groupby.sum.md diff --git a/api-reference copy/groupby/groupby.var.md b/api-reference-v1-stable/groupby/groupby.var.md similarity index 100% rename from api-reference copy/groupby/groupby.var.md rename to api-reference-v1-stable/groupby/groupby.var.md diff --git a/api-reference copy/input-output/README.md b/api-reference-v1-stable/input-output/README.md similarity index 100% rename from api-reference copy/input-output/README.md rename to api-reference-v1-stable/input-output/README.md diff --git a/api-reference copy/input-output/danfo.read_csv.md b/api-reference-v1-stable/input-output/danfo.read_csv.md similarity index 100% rename from api-reference copy/input-output/danfo.read_csv.md rename to api-reference-v1-stable/input-output/danfo.read_csv.md diff --git a/api-reference copy/input-output/danfo.read_excel.md b/api-reference-v1-stable/input-output/danfo.read_excel.md similarity index 100% rename from api-reference copy/input-output/danfo.read_excel.md rename to api-reference-v1-stable/input-output/danfo.read_excel.md diff --git a/api-reference copy/input-output/danfo.read_json.md b/api-reference-v1-stable/input-output/danfo.read_json.md similarity index 100% rename from api-reference copy/input-output/danfo.read_json.md rename to api-reference-v1-stable/input-output/danfo.read_json.md diff --git a/api-reference copy/input-output/danfo.to_csv.md b/api-reference-v1-stable/input-output/danfo.to_csv.md similarity index 100% rename from api-reference copy/input-output/danfo.to_csv.md rename to api-reference-v1-stable/input-output/danfo.to_csv.md diff --git a/api-reference copy/input-output/danfo.to_excel.md b/api-reference-v1-stable/input-output/danfo.to_excel.md similarity index 100% rename from api-reference copy/input-output/danfo.to_excel.md rename to api-reference-v1-stable/input-output/danfo.to_excel.md diff --git a/api-reference copy/input-output/danfo.to_json.md b/api-reference-v1-stable/input-output/danfo.to_json.md similarity index 100% rename from api-reference copy/input-output/danfo.to_json.md rename to api-reference-v1-stable/input-output/danfo.to_json.md diff --git a/api-reference copy/input-output/read.md b/api-reference-v1-stable/input-output/read.md similarity index 100% rename from api-reference copy/input-output/read.md rename to api-reference-v1-stable/input-output/read.md diff --git a/api-reference copy/plotting/README.md b/api-reference-v1-stable/plotting/README.md similarity index 100% rename from api-reference copy/plotting/README.md rename to api-reference-v1-stable/plotting/README.md diff --git a/api-reference copy/plotting/bar-charts.md b/api-reference-v1-stable/plotting/bar-charts.md similarity index 100% rename from api-reference copy/plotting/bar-charts.md rename to api-reference-v1-stable/plotting/bar-charts.md diff --git a/api-reference copy/plotting/box-plots.md b/api-reference-v1-stable/plotting/box-plots.md similarity index 100% rename from api-reference copy/plotting/box-plots.md rename to api-reference-v1-stable/plotting/box-plots.md diff --git a/api-reference copy/plotting/configuring-your-plots.md b/api-reference-v1-stable/plotting/configuring-your-plots.md similarity index 100% rename from api-reference copy/plotting/configuring-your-plots.md rename to api-reference-v1-stable/plotting/configuring-your-plots.md diff --git a/api-reference copy/plotting/histograms.md b/api-reference-v1-stable/plotting/histograms.md similarity index 100% rename from api-reference copy/plotting/histograms.md rename to api-reference-v1-stable/plotting/histograms.md diff --git a/api-reference copy/plotting/line-charts.md b/api-reference-v1-stable/plotting/line-charts.md similarity index 100% rename from api-reference copy/plotting/line-charts.md rename to api-reference-v1-stable/plotting/line-charts.md diff --git a/api-reference copy/plotting/pie-charts.md b/api-reference-v1-stable/plotting/pie-charts.md similarity index 100% rename from api-reference copy/plotting/pie-charts.md rename to api-reference-v1-stable/plotting/pie-charts.md diff --git a/api-reference copy/plotting/scatter-plots.md b/api-reference-v1-stable/plotting/scatter-plots.md similarity index 100% rename from api-reference copy/plotting/scatter-plots.md rename to api-reference-v1-stable/plotting/scatter-plots.md diff --git a/api-reference copy/plotting/tables.md b/api-reference-v1-stable/plotting/tables.md similarity index 100% rename from api-reference copy/plotting/tables.md rename to api-reference-v1-stable/plotting/tables.md diff --git a/api-reference copy/plotting/timeseries-plots.md b/api-reference-v1-stable/plotting/timeseries-plots.md similarity index 100% rename from api-reference copy/plotting/timeseries-plots.md rename to api-reference-v1-stable/plotting/timeseries-plots.md diff --git a/api-reference copy/plotting/violin-plots.md b/api-reference-v1-stable/plotting/violin-plots.md similarity index 100% rename from api-reference copy/plotting/violin-plots.md rename to api-reference-v1-stable/plotting/violin-plots.md diff --git a/api-reference copy/series/README.md b/api-reference-v1-stable/series/README.md similarity index 100% rename from api-reference copy/series/README.md rename to api-reference-v1-stable/series/README.md diff --git a/api-reference copy/series/creating-a-series.md b/api-reference-v1-stable/series/creating-a-series.md similarity index 100% rename from api-reference copy/series/creating-a-series.md rename to api-reference-v1-stable/series/creating-a-series.md diff --git a/api-reference copy/series/danfo.series.add.md b/api-reference-v1-stable/series/danfo.series.add.md similarity index 100% rename from api-reference copy/series/danfo.series.add.md rename to api-reference-v1-stable/series/danfo.series.add.md diff --git a/api-reference copy/series/danfo.series.apply.md b/api-reference-v1-stable/series/danfo.series.apply.md similarity index 100% rename from api-reference copy/series/danfo.series.apply.md rename to api-reference-v1-stable/series/danfo.series.apply.md diff --git a/api-reference copy/series/danfo.series.copy.md b/api-reference-v1-stable/series/danfo.series.copy.md similarity index 100% rename from api-reference copy/series/danfo.series.copy.md rename to api-reference-v1-stable/series/danfo.series.copy.md diff --git a/api-reference copy/series/danfo.series.count.md b/api-reference-v1-stable/series/danfo.series.count.md similarity index 100% rename from api-reference copy/series/danfo.series.count.md rename to api-reference-v1-stable/series/danfo.series.count.md diff --git a/api-reference copy/series/danfo.series.describe.md b/api-reference-v1-stable/series/danfo.series.describe.md similarity index 100% rename from api-reference copy/series/danfo.series.describe.md rename to api-reference-v1-stable/series/danfo.series.describe.md diff --git a/api-reference copy/series/danfo.series.div.md b/api-reference-v1-stable/series/danfo.series.div.md similarity index 100% rename from api-reference copy/series/danfo.series.div.md rename to api-reference-v1-stable/series/danfo.series.div.md diff --git a/api-reference copy/series/danfo.series.head.md b/api-reference-v1-stable/series/danfo.series.head.md similarity index 100% rename from api-reference copy/series/danfo.series.head.md rename to api-reference-v1-stable/series/danfo.series.head.md diff --git a/api-reference copy/series/danfo.series.map.md b/api-reference-v1-stable/series/danfo.series.map.md similarity index 100% rename from api-reference copy/series/danfo.series.map.md rename to api-reference-v1-stable/series/danfo.series.map.md diff --git a/api-reference copy/series/danfo.series.max.md b/api-reference-v1-stable/series/danfo.series.max.md similarity index 100% rename from api-reference copy/series/danfo.series.max.md rename to api-reference-v1-stable/series/danfo.series.max.md diff --git a/api-reference copy/series/danfo.series.maximum.md b/api-reference-v1-stable/series/danfo.series.maximum.md similarity index 100% rename from api-reference copy/series/danfo.series.maximum.md rename to api-reference-v1-stable/series/danfo.series.maximum.md diff --git a/api-reference copy/series/danfo.series.mean.md b/api-reference-v1-stable/series/danfo.series.mean.md similarity index 100% rename from api-reference copy/series/danfo.series.mean.md rename to api-reference-v1-stable/series/danfo.series.mean.md diff --git a/api-reference copy/series/danfo.series.median.md b/api-reference-v1-stable/series/danfo.series.median.md similarity index 100% rename from api-reference copy/series/danfo.series.median.md rename to api-reference-v1-stable/series/danfo.series.median.md diff --git a/api-reference copy/series/danfo.series.min.md b/api-reference-v1-stable/series/danfo.series.min.md similarity index 100% rename from api-reference copy/series/danfo.series.min.md rename to api-reference-v1-stable/series/danfo.series.min.md diff --git a/api-reference copy/series/danfo.series.minimum.md b/api-reference-v1-stable/series/danfo.series.minimum.md similarity index 100% rename from api-reference copy/series/danfo.series.minimum.md rename to api-reference-v1-stable/series/danfo.series.minimum.md diff --git a/api-reference copy/series/danfo.series.mod.md b/api-reference-v1-stable/series/danfo.series.mod.md similarity index 100% rename from api-reference copy/series/danfo.series.mod.md rename to api-reference-v1-stable/series/danfo.series.mod.md diff --git a/api-reference copy/series/danfo.series.mode.md b/api-reference-v1-stable/series/danfo.series.mode.md similarity index 100% rename from api-reference copy/series/danfo.series.mode.md rename to api-reference-v1-stable/series/danfo.series.mode.md diff --git a/api-reference copy/series/danfo.series.mul.md b/api-reference-v1-stable/series/danfo.series.mul.md similarity index 100% rename from api-reference copy/series/danfo.series.mul.md rename to api-reference-v1-stable/series/danfo.series.mul.md diff --git a/api-reference copy/series/danfo.series.pow.md b/api-reference-v1-stable/series/danfo.series.pow.md similarity index 100% rename from api-reference copy/series/danfo.series.pow.md rename to api-reference-v1-stable/series/danfo.series.pow.md diff --git a/api-reference copy/series/danfo.series.reset_index.md b/api-reference-v1-stable/series/danfo.series.reset_index.md similarity index 100% rename from api-reference copy/series/danfo.series.reset_index.md rename to api-reference-v1-stable/series/danfo.series.reset_index.md diff --git a/api-reference copy/series/danfo.series.round.md b/api-reference-v1-stable/series/danfo.series.round.md similarity index 100% rename from api-reference copy/series/danfo.series.round.md rename to api-reference-v1-stable/series/danfo.series.round.md diff --git a/api-reference copy/series/danfo.series.sample.md b/api-reference-v1-stable/series/danfo.series.sample.md similarity index 100% rename from api-reference copy/series/danfo.series.sample.md rename to api-reference-v1-stable/series/danfo.series.sample.md diff --git a/api-reference copy/series/danfo.series.set_index.md b/api-reference-v1-stable/series/danfo.series.set_index.md similarity index 100% rename from api-reference copy/series/danfo.series.set_index.md rename to api-reference-v1-stable/series/danfo.series.set_index.md diff --git a/api-reference copy/series/danfo.series.sort_values.md b/api-reference-v1-stable/series/danfo.series.sort_values.md similarity index 100% rename from api-reference copy/series/danfo.series.sort_values.md rename to api-reference-v1-stable/series/danfo.series.sort_values.md diff --git a/api-reference copy/series/danfo.series.std.md b/api-reference-v1-stable/series/danfo.series.std.md similarity index 100% rename from api-reference copy/series/danfo.series.std.md rename to api-reference-v1-stable/series/danfo.series.std.md diff --git a/api-reference copy/series/danfo.series.sub.md b/api-reference-v1-stable/series/danfo.series.sub.md similarity index 100% rename from api-reference copy/series/danfo.series.sub.md rename to api-reference-v1-stable/series/danfo.series.sub.md diff --git a/api-reference copy/series/danfo.series.sum-1.md b/api-reference-v1-stable/series/danfo.series.sum-1.md similarity index 100% rename from api-reference copy/series/danfo.series.sum-1.md rename to api-reference-v1-stable/series/danfo.series.sum-1.md diff --git a/api-reference copy/series/danfo.series.tail.md b/api-reference-v1-stable/series/danfo.series.tail.md similarity index 100% rename from api-reference copy/series/danfo.series.tail.md rename to api-reference-v1-stable/series/danfo.series.tail.md diff --git a/api-reference copy/series/danfo.series.tostring.md b/api-reference-v1-stable/series/danfo.series.tostring.md similarity index 100% rename from api-reference copy/series/danfo.series.tostring.md rename to api-reference-v1-stable/series/danfo.series.tostring.md diff --git a/api-reference copy/series/danfo.series.var.md b/api-reference-v1-stable/series/danfo.series.var.md similarity index 100% rename from api-reference copy/series/danfo.series.var.md rename to api-reference-v1-stable/series/danfo.series.var.md diff --git a/api-reference copy/series/series.abs.md b/api-reference-v1-stable/series/series.abs.md similarity index 100% rename from api-reference copy/series/series.abs.md rename to api-reference-v1-stable/series/series.abs.md diff --git a/api-reference copy/series/series.add.md b/api-reference-v1-stable/series/series.add.md similarity index 100% rename from api-reference copy/series/series.add.md rename to api-reference-v1-stable/series/series.add.md diff --git a/api-reference copy/series/series.and.md b/api-reference-v1-stable/series/series.and.md similarity index 100% rename from api-reference copy/series/series.and.md rename to api-reference-v1-stable/series/series.and.md diff --git a/api-reference copy/series/series.append.md b/api-reference-v1-stable/series/series.append.md similarity index 100% rename from api-reference copy/series/series.append.md rename to api-reference-v1-stable/series/series.append.md diff --git a/api-reference copy/series/series.apply.md b/api-reference-v1-stable/series/series.apply.md similarity index 100% rename from api-reference copy/series/series.apply.md rename to api-reference-v1-stable/series/series.apply.md diff --git a/api-reference copy/series/series.argmax.md b/api-reference-v1-stable/series/series.argmax.md similarity index 100% rename from api-reference copy/series/series.argmax.md rename to api-reference-v1-stable/series/series.argmax.md diff --git a/api-reference copy/series/series.argmin.md b/api-reference-v1-stable/series/series.argmin.md similarity index 100% rename from api-reference copy/series/series.argmin.md rename to api-reference-v1-stable/series/series.argmin.md diff --git a/api-reference copy/series/series.argsort.md b/api-reference-v1-stable/series/series.argsort.md similarity index 100% rename from api-reference copy/series/series.argsort.md rename to api-reference-v1-stable/series/series.argsort.md diff --git a/api-reference copy/series/series.astype.md b/api-reference-v1-stable/series/series.astype.md similarity index 100% rename from api-reference copy/series/series.astype.md rename to api-reference-v1-stable/series/series.astype.md diff --git a/api-reference copy/series/series.copy.md b/api-reference-v1-stable/series/series.copy.md similarity index 100% rename from api-reference copy/series/series.copy.md rename to api-reference-v1-stable/series/series.copy.md diff --git a/api-reference copy/series/series.corr.md b/api-reference-v1-stable/series/series.corr.md similarity index 100% rename from api-reference copy/series/series.corr.md rename to api-reference-v1-stable/series/series.corr.md diff --git a/api-reference copy/series/series.count.md b/api-reference-v1-stable/series/series.count.md similarity index 100% rename from api-reference copy/series/series.count.md rename to api-reference-v1-stable/series/series.count.md diff --git a/api-reference copy/series/series.cummax.md b/api-reference-v1-stable/series/series.cummax.md similarity index 100% rename from api-reference copy/series/series.cummax.md rename to api-reference-v1-stable/series/series.cummax.md diff --git a/api-reference copy/series/series.cummin.md b/api-reference-v1-stable/series/series.cummin.md similarity index 100% rename from api-reference copy/series/series.cummin.md rename to api-reference-v1-stable/series/series.cummin.md diff --git a/api-reference copy/series/series.cumprod.md b/api-reference-v1-stable/series/series.cumprod.md similarity index 100% rename from api-reference copy/series/series.cumprod.md rename to api-reference-v1-stable/series/series.cumprod.md diff --git a/api-reference copy/series/series.cumsum.md b/api-reference-v1-stable/series/series.cumsum.md similarity index 100% rename from api-reference copy/series/series.cumsum.md rename to api-reference-v1-stable/series/series.cumsum.md diff --git a/api-reference copy/series/series.describe.md b/api-reference-v1-stable/series/series.describe.md similarity index 100% rename from api-reference copy/series/series.describe.md rename to api-reference-v1-stable/series/series.describe.md diff --git a/api-reference copy/series/series.div.md b/api-reference-v1-stable/series/series.div.md similarity index 100% rename from api-reference copy/series/series.div.md rename to api-reference-v1-stable/series/series.div.md diff --git a/api-reference copy/series/series.dot.md b/api-reference-v1-stable/series/series.dot.md similarity index 100% rename from api-reference copy/series/series.dot.md rename to api-reference-v1-stable/series/series.dot.md diff --git a/api-reference copy/series/series.drop_duplicates.md b/api-reference-v1-stable/series/series.drop_duplicates.md similarity index 100% rename from api-reference copy/series/series.drop_duplicates.md rename to api-reference-v1-stable/series/series.drop_duplicates.md diff --git a/api-reference copy/series/series.dropna.md b/api-reference-v1-stable/series/series.dropna.md similarity index 100% rename from api-reference copy/series/series.dropna.md rename to api-reference-v1-stable/series/series.dropna.md diff --git a/api-reference copy/series/series.dt.day.md b/api-reference-v1-stable/series/series.dt.day.md similarity index 100% rename from api-reference copy/series/series.dt.day.md rename to api-reference-v1-stable/series/series.dt.day.md diff --git a/api-reference copy/series/series.dt.hour.md b/api-reference-v1-stable/series/series.dt.hour.md similarity index 100% rename from api-reference copy/series/series.dt.hour.md rename to api-reference-v1-stable/series/series.dt.hour.md diff --git a/api-reference copy/series/series.dt.minute.md b/api-reference-v1-stable/series/series.dt.minute.md similarity index 100% rename from api-reference copy/series/series.dt.minute.md rename to api-reference-v1-stable/series/series.dt.minute.md diff --git a/api-reference copy/series/series.dt.month.md b/api-reference-v1-stable/series/series.dt.month.md similarity index 100% rename from api-reference copy/series/series.dt.month.md rename to api-reference-v1-stable/series/series.dt.month.md diff --git a/api-reference copy/series/series.dt.month_name.md b/api-reference-v1-stable/series/series.dt.month_name.md similarity index 100% rename from api-reference copy/series/series.dt.month_name.md rename to api-reference-v1-stable/series/series.dt.month_name.md diff --git a/api-reference copy/series/series.dt.monthday.md b/api-reference-v1-stable/series/series.dt.monthday.md similarity index 100% rename from api-reference copy/series/series.dt.monthday.md rename to api-reference-v1-stable/series/series.dt.monthday.md diff --git a/api-reference copy/series/series.dt.second.md b/api-reference-v1-stable/series/series.dt.second.md similarity index 100% rename from api-reference copy/series/series.dt.second.md rename to api-reference-v1-stable/series/series.dt.second.md diff --git a/api-reference copy/series/series.dt.weekdays.md b/api-reference-v1-stable/series/series.dt.weekdays.md similarity index 100% rename from api-reference copy/series/series.dt.weekdays.md rename to api-reference-v1-stable/series/series.dt.weekdays.md diff --git a/api-reference copy/series/series.dt.year.md b/api-reference-v1-stable/series/series.dt.year.md similarity index 100% rename from api-reference copy/series/series.dt.year.md rename to api-reference-v1-stable/series/series.dt.year.md diff --git a/api-reference copy/series/series.dtype.md b/api-reference-v1-stable/series/series.dtype.md similarity index 100% rename from api-reference copy/series/series.dtype.md rename to api-reference-v1-stable/series/series.dtype.md diff --git a/api-reference copy/series/series.eq.md b/api-reference-v1-stable/series/series.eq.md similarity index 100% rename from api-reference copy/series/series.eq.md rename to api-reference-v1-stable/series/series.eq.md diff --git a/api-reference copy/series/series.fillna.md b/api-reference-v1-stable/series/series.fillna.md similarity index 100% rename from api-reference copy/series/series.fillna.md rename to api-reference-v1-stable/series/series.fillna.md diff --git a/api-reference copy/series/series.ge.md b/api-reference-v1-stable/series/series.ge.md similarity index 100% rename from api-reference copy/series/series.ge.md rename to api-reference-v1-stable/series/series.ge.md diff --git a/api-reference copy/series/series.gt.md b/api-reference-v1-stable/series/series.gt.md similarity index 100% rename from api-reference copy/series/series.gt.md rename to api-reference-v1-stable/series/series.gt.md diff --git a/api-reference copy/series/series.head.md b/api-reference-v1-stable/series/series.head.md similarity index 100% rename from api-reference copy/series/series.head.md rename to api-reference-v1-stable/series/series.head.md diff --git a/api-reference copy/series/series.iloc.md b/api-reference-v1-stable/series/series.iloc.md similarity index 100% rename from api-reference copy/series/series.iloc.md rename to api-reference-v1-stable/series/series.iloc.md diff --git a/api-reference copy/series/series.index.md b/api-reference-v1-stable/series/series.index.md similarity index 100% rename from api-reference copy/series/series.index.md rename to api-reference-v1-stable/series/series.index.md diff --git a/api-reference copy/series/series.isna.md b/api-reference-v1-stable/series/series.isna.md similarity index 100% rename from api-reference copy/series/series.isna.md rename to api-reference-v1-stable/series/series.isna.md diff --git a/api-reference copy/series/series.le.md b/api-reference-v1-stable/series/series.le.md similarity index 100% rename from api-reference copy/series/series.le.md rename to api-reference-v1-stable/series/series.le.md diff --git a/api-reference copy/series/series.loc.md b/api-reference-v1-stable/series/series.loc.md similarity index 100% rename from api-reference copy/series/series.loc.md rename to api-reference-v1-stable/series/series.loc.md diff --git a/api-reference copy/series/series.lt.md b/api-reference-v1-stable/series/series.lt.md similarity index 100% rename from api-reference copy/series/series.lt.md rename to api-reference-v1-stable/series/series.lt.md diff --git a/api-reference copy/series/series.map.md b/api-reference-v1-stable/series/series.map.md similarity index 100% rename from api-reference copy/series/series.map.md rename to api-reference-v1-stable/series/series.map.md diff --git a/api-reference copy/series/series.max.md b/api-reference-v1-stable/series/series.max.md similarity index 100% rename from api-reference copy/series/series.max.md rename to api-reference-v1-stable/series/series.max.md diff --git a/api-reference copy/series/series.maximum.md b/api-reference-v1-stable/series/series.maximum.md similarity index 100% rename from api-reference copy/series/series.maximum.md rename to api-reference-v1-stable/series/series.maximum.md diff --git a/api-reference copy/series/series.mean.md b/api-reference-v1-stable/series/series.mean.md similarity index 100% rename from api-reference copy/series/series.mean.md rename to api-reference-v1-stable/series/series.mean.md diff --git a/api-reference copy/series/series.median.md b/api-reference-v1-stable/series/series.median.md similarity index 100% rename from api-reference copy/series/series.median.md rename to api-reference-v1-stable/series/series.median.md diff --git a/api-reference copy/series/series.min.md b/api-reference-v1-stable/series/series.min.md similarity index 100% rename from api-reference copy/series/series.min.md rename to api-reference-v1-stable/series/series.min.md diff --git a/api-reference copy/series/series.minimum.md b/api-reference-v1-stable/series/series.minimum.md similarity index 100% rename from api-reference copy/series/series.minimum.md rename to api-reference-v1-stable/series/series.minimum.md diff --git a/api-reference copy/series/series.mod.md b/api-reference-v1-stable/series/series.mod.md similarity index 100% rename from api-reference copy/series/series.mod.md rename to api-reference-v1-stable/series/series.mod.md diff --git a/api-reference copy/series/series.mode.md b/api-reference-v1-stable/series/series.mode.md similarity index 100% rename from api-reference copy/series/series.mode.md rename to api-reference-v1-stable/series/series.mode.md diff --git a/api-reference copy/series/series.mul.md b/api-reference-v1-stable/series/series.mul.md similarity index 100% rename from api-reference copy/series/series.mul.md rename to api-reference-v1-stable/series/series.mul.md diff --git a/api-reference copy/series/series.ndim.md b/api-reference-v1-stable/series/series.ndim.md similarity index 100% rename from api-reference copy/series/series.ndim.md rename to api-reference-v1-stable/series/series.ndim.md diff --git a/api-reference copy/series/series.ne.md b/api-reference-v1-stable/series/series.ne.md similarity index 100% rename from api-reference copy/series/series.ne.md rename to api-reference-v1-stable/series/series.ne.md diff --git a/api-reference copy/series/series.nunique.md b/api-reference-v1-stable/series/series.nunique.md similarity index 100% rename from api-reference copy/series/series.nunique.md rename to api-reference-v1-stable/series/series.nunique.md diff --git a/api-reference copy/series/series.or.md b/api-reference-v1-stable/series/series.or.md similarity index 100% rename from api-reference copy/series/series.or.md rename to api-reference-v1-stable/series/series.or.md diff --git a/api-reference copy/series/series.pow.md b/api-reference-v1-stable/series/series.pow.md similarity index 100% rename from api-reference copy/series/series.pow.md rename to api-reference-v1-stable/series/series.pow.md diff --git a/api-reference copy/series/series.replace.md b/api-reference-v1-stable/series/series.replace.md similarity index 100% rename from api-reference copy/series/series.replace.md rename to api-reference-v1-stable/series/series.replace.md diff --git a/api-reference copy/series/series.reset_index.md b/api-reference-v1-stable/series/series.reset_index.md similarity index 100% rename from api-reference copy/series/series.reset_index.md rename to api-reference-v1-stable/series/series.reset_index.md diff --git a/api-reference copy/series/series.round.md b/api-reference-v1-stable/series/series.round.md similarity index 100% rename from api-reference copy/series/series.round.md rename to api-reference-v1-stable/series/series.round.md diff --git a/api-reference copy/series/series.sample.md b/api-reference-v1-stable/series/series.sample.md similarity index 100% rename from api-reference copy/series/series.sample.md rename to api-reference-v1-stable/series/series.sample.md diff --git a/api-reference copy/series/series.set_index.md b/api-reference-v1-stable/series/series.set_index.md similarity index 100% rename from api-reference copy/series/series.set_index.md rename to api-reference-v1-stable/series/series.set_index.md diff --git a/api-reference copy/series/series.shape.md b/api-reference-v1-stable/series/series.shape.md similarity index 100% rename from api-reference copy/series/series.shape.md rename to api-reference-v1-stable/series/series.shape.md diff --git a/api-reference copy/series/series.size.md b/api-reference-v1-stable/series/series.size.md similarity index 100% rename from api-reference copy/series/series.size.md rename to api-reference-v1-stable/series/series.size.md diff --git a/api-reference copy/series/series.sort_values.md b/api-reference-v1-stable/series/series.sort_values.md similarity index 100% rename from api-reference copy/series/series.sort_values.md rename to api-reference-v1-stable/series/series.sort_values.md diff --git a/api-reference copy/series/series.std.md b/api-reference-v1-stable/series/series.std.md similarity index 100% rename from api-reference copy/series/series.std.md rename to api-reference-v1-stable/series/series.std.md diff --git a/api-reference copy/series/series.str.capitalize.md b/api-reference-v1-stable/series/series.str.capitalize.md similarity index 100% rename from api-reference copy/series/series.str.capitalize.md rename to api-reference-v1-stable/series/series.str.capitalize.md diff --git a/api-reference copy/series/series.str.charat.md b/api-reference-v1-stable/series/series.str.charat.md similarity index 100% rename from api-reference copy/series/series.str.charat.md rename to api-reference-v1-stable/series/series.str.charat.md diff --git a/api-reference copy/series/series.str.concat.md b/api-reference-v1-stable/series/series.str.concat.md similarity index 100% rename from api-reference copy/series/series.str.concat.md rename to api-reference-v1-stable/series/series.str.concat.md diff --git a/api-reference copy/series/series.str.endswith.md b/api-reference-v1-stable/series/series.str.endswith.md similarity index 100% rename from api-reference copy/series/series.str.endswith.md rename to api-reference-v1-stable/series/series.str.endswith.md diff --git a/api-reference copy/series/series.str.includes.md b/api-reference-v1-stable/series/series.str.includes.md similarity index 100% rename from api-reference copy/series/series.str.includes.md rename to api-reference-v1-stable/series/series.str.includes.md diff --git a/api-reference copy/series/series.str.indexof.md b/api-reference-v1-stable/series/series.str.indexof.md similarity index 100% rename from api-reference copy/series/series.str.indexof.md rename to api-reference-v1-stable/series/series.str.indexof.md diff --git a/api-reference copy/series/series.str.join.md b/api-reference-v1-stable/series/series.str.join.md similarity index 100% rename from api-reference copy/series/series.str.join.md rename to api-reference-v1-stable/series/series.str.join.md diff --git a/api-reference copy/series/series.str.lastindexof.md b/api-reference-v1-stable/series/series.str.lastindexof.md similarity index 100% rename from api-reference copy/series/series.str.lastindexof.md rename to api-reference-v1-stable/series/series.str.lastindexof.md diff --git a/api-reference copy/series/series.str.len.md b/api-reference-v1-stable/series/series.str.len.md similarity index 100% rename from api-reference copy/series/series.str.len.md rename to api-reference-v1-stable/series/series.str.len.md diff --git a/api-reference copy/series/series.str.repeat.md b/api-reference-v1-stable/series/series.str.repeat.md similarity index 100% rename from api-reference copy/series/series.str.repeat.md rename to api-reference-v1-stable/series/series.str.repeat.md diff --git a/api-reference copy/series/series.str.replace.md b/api-reference-v1-stable/series/series.str.replace.md similarity index 100% rename from api-reference copy/series/series.str.replace.md rename to api-reference-v1-stable/series/series.str.replace.md diff --git a/api-reference copy/series/series.str.search.md b/api-reference-v1-stable/series/series.str.search.md similarity index 100% rename from api-reference copy/series/series.str.search.md rename to api-reference-v1-stable/series/series.str.search.md diff --git a/api-reference copy/series/series.str.slice.md b/api-reference-v1-stable/series/series.str.slice.md similarity index 100% rename from api-reference copy/series/series.str.slice.md rename to api-reference-v1-stable/series/series.str.slice.md diff --git a/api-reference copy/series/series.str.split.md b/api-reference-v1-stable/series/series.str.split.md similarity index 100% rename from api-reference copy/series/series.str.split.md rename to api-reference-v1-stable/series/series.str.split.md diff --git a/api-reference copy/series/series.str.startswith.md b/api-reference-v1-stable/series/series.str.startswith.md similarity index 100% rename from api-reference copy/series/series.str.startswith.md rename to api-reference-v1-stable/series/series.str.startswith.md diff --git a/api-reference copy/series/series.str.substr.md b/api-reference-v1-stable/series/series.str.substr.md similarity index 100% rename from api-reference copy/series/series.str.substr.md rename to api-reference-v1-stable/series/series.str.substr.md diff --git a/api-reference copy/series/series.str.substring.md b/api-reference-v1-stable/series/series.str.substring.md similarity index 100% rename from api-reference copy/series/series.str.substring.md rename to api-reference-v1-stable/series/series.str.substring.md diff --git a/api-reference copy/series/series.str.tolowercase.md b/api-reference-v1-stable/series/series.str.tolowercase.md similarity index 100% rename from api-reference copy/series/series.str.tolowercase.md rename to api-reference-v1-stable/series/series.str.tolowercase.md diff --git a/api-reference copy/series/series.str.touppercase.md b/api-reference-v1-stable/series/series.str.touppercase.md similarity index 100% rename from api-reference copy/series/series.str.touppercase.md rename to api-reference-v1-stable/series/series.str.touppercase.md diff --git a/api-reference copy/series/series.str.trim.md b/api-reference-v1-stable/series/series.str.trim.md similarity index 100% rename from api-reference copy/series/series.str.trim.md rename to api-reference-v1-stable/series/series.str.trim.md diff --git a/api-reference copy/series/series.sub.md b/api-reference-v1-stable/series/series.sub.md similarity index 100% rename from api-reference copy/series/series.sub.md rename to api-reference-v1-stable/series/series.sub.md diff --git a/api-reference copy/series/series.sum.md b/api-reference-v1-stable/series/series.sum.md similarity index 100% rename from api-reference copy/series/series.sum.md rename to api-reference-v1-stable/series/series.sum.md diff --git a/api-reference copy/series/series.tail.md b/api-reference-v1-stable/series/series.tail.md similarity index 100% rename from api-reference copy/series/series.tail.md rename to api-reference-v1-stable/series/series.tail.md diff --git a/api-reference copy/series/series.tensor.md b/api-reference-v1-stable/series/series.tensor.md similarity index 100% rename from api-reference copy/series/series.tensor.md rename to api-reference-v1-stable/series/series.tensor.md diff --git a/api-reference copy/series/series.unique.md b/api-reference-v1-stable/series/series.unique.md similarity index 100% rename from api-reference copy/series/series.unique.md rename to api-reference-v1-stable/series/series.unique.md diff --git a/api-reference copy/series/series.value_counts.md b/api-reference-v1-stable/series/series.value_counts.md similarity index 100% rename from api-reference copy/series/series.value_counts.md rename to api-reference-v1-stable/series/series.value_counts.md diff --git a/api-reference copy/series/series.values.md b/api-reference-v1-stable/series/series.values.md similarity index 100% rename from api-reference copy/series/series.values.md rename to api-reference-v1-stable/series/series.values.md diff --git a/api-reference copy/series/series.var.md b/api-reference-v1-stable/series/series.var.md similarity index 100% rename from api-reference copy/series/series.var.md rename to api-reference-v1-stable/series/series.var.md From 27dccd21ba025bd4abe868f04dc604ce388b70ea Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Jan 2022 16:18:11 +0100 Subject: [PATCH 159/202] clean up repo --- api-reference copy/README.md | 54 --- api-reference copy/configuration-options.md | 128 ----- api-reference copy/dataframe/README.md | 145 ------ .../dataframe/creating-a-dataframe.md | 355 -------------- .../dataframe/danfo.dataframe.abs.md | 74 --- .../dataframe/danfo.dataframe.add.md | 246 ---------- .../dataframe/danfo.dataframe.addcolumn.md | 118 ----- .../dataframe/danfo.dataframe.apply.md | 106 ---- .../dataframe/danfo.dataframe.column.md | 72 --- .../dataframe/danfo.dataframe.copy.md | 53 -- .../dataframe/danfo.dataframe.count.md | 100 ---- .../dataframe/danfo.dataframe.cummax.md | 99 ---- .../dataframe/danfo.dataframe.cummin.md | 99 ---- .../dataframe/danfo.dataframe.cumprod.md | 99 ---- .../dataframe/danfo.dataframe.cumsum.md | 99 ---- .../dataframe/danfo.dataframe.describe.md | 61 --- .../dataframe/danfo.dataframe.div.md | 254 ---------- .../dataframe/danfo.dataframe.dropna.md | 96 ---- .../dataframe/danfo.dataframe.eq.md | 190 -------- .../dataframe/danfo.dataframe.fillna.md | 178 ------- .../dataframe/danfo.dataframe.ge.md | 195 -------- .../dataframe/danfo.dataframe.groupby.md | 148 ------ .../dataframe/danfo.dataframe.gt.md | 191 -------- .../dataframe/danfo.dataframe.head.md | 53 -- .../dataframe/danfo.dataframe.iloc.md | 331 ------------- .../dataframe/danfo.dataframe.isna.md | 54 --- .../dataframe/danfo.dataframe.it.md | 194 -------- .../dataframe/danfo.dataframe.le.md | 194 -------- .../dataframe/danfo.dataframe.loc.md | 367 -------------- .../dataframe/danfo.dataframe.max.md | 118 ----- .../dataframe/danfo.dataframe.mean.md | 120 ----- .../dataframe/danfo.dataframe.median.md | 120 ----- .../dataframe/danfo.dataframe.min.md | 120 ----- .../dataframe/danfo.dataframe.mod.md | 258 ---------- .../dataframe/danfo.dataframe.mul.md | 252 ---------- .../dataframe/danfo.dataframe.ne.md | 187 -------- .../dataframe/danfo.dataframe.pow.md | 260 ---------- .../dataframe/danfo.dataframe.query.md | 278 ----------- .../dataframe/danfo.dataframe.replace.md | 102 ---- .../dataframe/danfo.dataframe.round.md | 128 ----- .../dataframe/danfo.dataframe.sample.md | 112 ----- .../dataframe/danfo.dataframe.std.md | 94 ---- .../dataframe/danfo.dataframe.sub.md | 250 ---------- .../dataframe/danfo.dataframe.sum.md | 121 ----- .../dataframe/danfo.dataframe.tail.md | 53 -- .../dataframe/danfo.dataframe.var.md | 94 ---- .../dataframe/dataframe.append.md | 76 --- .../dataframe/dataframe.apply_map.md | 68 --- .../dataframe/dataframe.astype.md | 222 --------- .../dataframe/dataframe.axes.md | 47 -- .../dataframe/dataframe.drop.md | 143 ------ .../dataframe/dataframe.dtypes.md | 100 ---- .../dataframe/dataframe.index.md | 69 --- .../dataframe/dataframe.ndim.md | 46 -- .../dataframe/dataframe.nunique-1.md | 98 ---- .../dataframe/dataframe.print.md | 105 ---- .../dataframe/dataframe.rename.md | 148 ------ .../dataframe/dataframe.reset_index.md | 73 --- .../dataframe/dataframe.select_dtypes.md | 94 ---- .../dataframe/dataframe.set_index.md | 176 ------- .../dataframe/dataframe.shape.md | 43 -- .../dataframe/dataframe.sort_index.md | 74 --- .../dataframe/dataframe.sort_values.md | 99 ---- .../dataframe/dataframe.tensor.md | 110 ----- .../dataframe/dataframe.to_csv.md | 114 ----- .../dataframe/dataframe.to_excel.md | 53 -- .../dataframe/dataframe.to_json.md | 127 ----- .../dataframe/dataframe.values.md | 50 -- .../general-functions/README.md | 27 -- .../general-functions/danfo.concat.md | 187 -------- .../general-functions/danfo.date_range.md | 111 ----- .../general-functions/danfo.get_dummies.md | 188 -------- .../general-functions/danfo.labelencoder.md | 140 ------ .../general-functions/danfo.merge.md | 453 ------------------ .../general-functions/danfo.minmaxscaler.md | 125 ----- .../general-functions/danfo.onehotencoder.md | 148 ------ .../general-functions/danfo.standardscaler.md | 132 ----- .../general-functions/danfo.to_datetime.md | 141 ------ api-reference copy/groupby.md | 122 ----- api-reference copy/groupby/README.md | 34 -- api-reference copy/groupby/groupby.agg.md | 93 ---- api-reference copy/groupby/groupby.apply.md | 84 ---- api-reference copy/groupby/groupby.col.md | 105 ---- api-reference copy/groupby/groupby.count.md | 175 ------- api-reference copy/groupby/groupby.cummax.md | 258 ---------- api-reference copy/groupby/groupby.cummin.md | 258 ---------- api-reference copy/groupby/groupby.cumprod.md | 258 ---------- api-reference copy/groupby/groupby.cumsum.md | 259 ---------- .../groupby/groupby.get_groups.md | 129 ----- api-reference copy/groupby/groupby.max.md | 170 ------- api-reference copy/groupby/groupby.mean.md | 173 ------- api-reference copy/groupby/groupby.min.md | 171 ------- api-reference copy/groupby/groupby.std.md | 175 ------- api-reference copy/groupby/groupby.sum.md | 172 ------- api-reference copy/groupby/groupby.var.md | 175 ------- api-reference copy/input-output/README.md | 18 - .../input-output/danfo.read_csv.md | 134 ------ .../input-output/danfo.read_excel.md | 68 --- .../input-output/danfo.read_json.md | 127 ----- .../input-output/danfo.to_csv.md | 115 ----- .../input-output/danfo.to_excel.md | 54 --- .../input-output/danfo.to_json.md | 124 ----- api-reference copy/input-output/read.md | 138 ------ api-reference copy/plotting/README.md | 19 - api-reference copy/plotting/bar-charts.md | 75 --- api-reference copy/plotting/box-plots.md | 116 ----- .../plotting/configuring-your-plots.md | 68 --- api-reference copy/plotting/histograms.md | 117 ----- api-reference copy/plotting/line-charts.md | 109 ----- api-reference copy/plotting/pie-charts.md | 123 ----- api-reference copy/plotting/scatter-plots.md | 88 ---- api-reference copy/plotting/tables.md | 95 ---- .../plotting/timeseries-plots.md | 58 --- api-reference copy/plotting/violin-plots.md | 112 ----- api-reference copy/series/README.md | 182 ------- .../series/creating-a-series.md | 210 -------- api-reference copy/series/danfo.series.add.md | 22 - .../series/danfo.series.apply.md | 63 --- .../series/danfo.series.copy.md | 22 - .../series/danfo.series.count.md | 24 - .../series/danfo.series.describe.md | 26 - api-reference copy/series/danfo.series.div.md | 26 - .../series/danfo.series.head.md | 25 - api-reference copy/series/danfo.series.map.md | 42 -- api-reference copy/series/danfo.series.max.md | 2 - .../series/danfo.series.maximum.md | 22 - .../series/danfo.series.mean.md | 2 - .../series/danfo.series.median.md | 2 - api-reference copy/series/danfo.series.min.md | 2 - .../series/danfo.series.minimum.md | 22 - api-reference copy/series/danfo.series.mod.md | 24 - .../series/danfo.series.mode.md | 2 - api-reference copy/series/danfo.series.mul.md | 26 - api-reference copy/series/danfo.series.pow.md | 26 - .../series/danfo.series.reset_index.md | 31 -- .../series/danfo.series.round.md | 20 - .../series/danfo.series.sample.md | 22 - .../series/danfo.series.set_index.md | 40 -- .../series/danfo.series.sort_values.md | 27 -- api-reference copy/series/danfo.series.std.md | 20 - api-reference copy/series/danfo.series.sub.md | 24 - .../series/danfo.series.sum-1.md | 22 - .../series/danfo.series.tail.md | 22 - .../series/danfo.series.tostring.md | 18 - api-reference copy/series/danfo.series.var.md | 20 - api-reference copy/series/series.abs.md | 52 -- api-reference copy/series/series.add.md | 86 ---- api-reference copy/series/series.and.md | 132 ----- api-reference copy/series/series.append.md | 135 ------ api-reference copy/series/series.apply.md | 149 ------ api-reference copy/series/series.argmax.md | 35 -- api-reference copy/series/series.argmin.md | 35 -- api-reference copy/series/series.argsort.md | 75 --- api-reference copy/series/series.astype.md | 2 - api-reference copy/series/series.copy.md | 45 -- api-reference copy/series/series.corr.md | 2 - api-reference copy/series/series.count.md | 36 -- api-reference copy/series/series.cummax.md | 51 -- api-reference copy/series/series.cummin.md | 51 -- api-reference copy/series/series.cumprod.md | 51 -- api-reference copy/series/series.cumsum.md | 74 --- api-reference copy/series/series.describe.md | 57 --- api-reference copy/series/series.div.md | 87 ---- api-reference copy/series/series.dot.md | 2 - .../series/series.drop_duplicates.md | 121 ----- api-reference copy/series/series.dropna.md | 91 ---- api-reference copy/series/series.dt.day.md | 55 --- api-reference copy/series/series.dt.hour.md | 52 -- api-reference copy/series/series.dt.minute.md | 60 --- api-reference copy/series/series.dt.month.md | 47 -- .../series/series.dt.month_name.md | 55 --- .../series/series.dt.monthday.md | 55 --- api-reference copy/series/series.dt.second.md | 60 --- .../series/series.dt.weekdays.md | 79 --- api-reference copy/series/series.dt.year.md | 45 -- api-reference copy/series/series.dtype.md | 34 -- api-reference copy/series/series.eq.md | 95 ---- api-reference copy/series/series.fillna.md | 106 ---- api-reference copy/series/series.ge.md | 95 ---- api-reference copy/series/series.gt.md | 95 ---- api-reference copy/series/series.head.md | 51 -- api-reference copy/series/series.iloc.md | 158 ------ api-reference copy/series/series.index.md | 33 -- api-reference copy/series/series.isna.md | 45 -- api-reference copy/series/series.le.md | 96 ---- api-reference copy/series/series.loc.md | 198 -------- api-reference copy/series/series.lt.md | 96 ---- api-reference copy/series/series.map.md | 92 ---- api-reference copy/series/series.max.md | 36 -- api-reference copy/series/series.maximum.md | 50 -- api-reference copy/series/series.mean.md | 36 -- api-reference copy/series/series.median.md | 36 -- api-reference copy/series/series.min.md | 36 -- api-reference copy/series/series.minimum.md | 48 -- api-reference copy/series/series.mod.md | 85 ---- api-reference copy/series/series.mode.md | 36 -- api-reference copy/series/series.mul.md | 86 ---- api-reference copy/series/series.ndim.md | 34 -- api-reference copy/series/series.ne.md | 95 ---- api-reference copy/series/series.nunique.md | 34 -- api-reference copy/series/series.or.md | 132 ----- api-reference copy/series/series.pow.md | 87 ---- api-reference copy/series/series.replace.md | 89 ---- .../series/series.reset_index.md | 113 ----- api-reference copy/series/series.round.md | 48 -- api-reference copy/series/series.sample.md | 65 --- api-reference copy/series/series.set_index.md | 136 ------ api-reference copy/series/series.shape.md | 35 -- api-reference copy/series/series.size.md | 37 -- .../series/series.sort_values.md | 140 ------ api-reference copy/series/series.std.md | 37 -- .../series/series.str.capitalize.md | 52 -- .../series/series.str.charat.md | 53 -- .../series/series.str.concat.md | 165 ------- .../series/series.str.endswith.md | 51 -- .../series/series.str.includes.md | 51 -- .../series/series.str.indexof.md | 51 -- api-reference copy/series/series.str.join.md | 52 -- .../series/series.str.lastindexof.md | 54 --- api-reference copy/series/series.str.len.md | 52 -- .../series/series.str.repeat.md | 51 -- .../series/series.str.replace.md | 50 -- .../series/series.str.search.md | 94 ---- api-reference copy/series/series.str.slice.md | 54 --- api-reference copy/series/series.str.split.md | 74 --- .../series/series.str.startswith.md | 51 -- .../series/series.str.substr.md | 50 -- .../series/series.str.substring.md | 56 --- .../series/series.str.tolowercase.md | 50 -- .../series/series.str.touppercase.md | 52 -- api-reference copy/series/series.str.trim.md | 50 -- api-reference copy/series/series.sub.md | 86 ---- api-reference copy/series/series.sum.md | 36 -- api-reference copy/series/series.tail.md | 49 -- api-reference copy/series/series.tensor.md | 46 -- api-reference copy/series/series.unique.md | 55 --- .../series/series.value_counts.md | 54 --- api-reference copy/series/series.values.md | 35 -- api-reference copy/series/series.var.md | 35 -- 239 files changed, 22625 deletions(-) delete mode 100644 api-reference copy/README.md delete mode 100644 api-reference copy/configuration-options.md delete mode 100644 api-reference copy/dataframe/README.md delete mode 100644 api-reference copy/dataframe/creating-a-dataframe.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.abs.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.add.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.addcolumn.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.apply.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.column.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.copy.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.count.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.cummax.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.cummin.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.cumprod.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.cumsum.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.describe.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.div.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.dropna.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.eq.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.fillna.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.ge.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.groupby.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.gt.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.head.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.iloc.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.isna.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.it.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.le.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.loc.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.max.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.mean.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.median.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.min.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.mod.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.mul.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.ne.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.pow.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.query.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.replace.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.round.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.sample.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.std.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.sub.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.sum.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.tail.md delete mode 100644 api-reference copy/dataframe/danfo.dataframe.var.md delete mode 100644 api-reference copy/dataframe/dataframe.append.md delete mode 100644 api-reference copy/dataframe/dataframe.apply_map.md delete mode 100644 api-reference copy/dataframe/dataframe.astype.md delete mode 100644 api-reference copy/dataframe/dataframe.axes.md delete mode 100644 api-reference copy/dataframe/dataframe.drop.md delete mode 100644 api-reference copy/dataframe/dataframe.dtypes.md delete mode 100644 api-reference copy/dataframe/dataframe.index.md delete mode 100644 api-reference copy/dataframe/dataframe.ndim.md delete mode 100644 api-reference copy/dataframe/dataframe.nunique-1.md delete mode 100644 api-reference copy/dataframe/dataframe.print.md delete mode 100644 api-reference copy/dataframe/dataframe.rename.md delete mode 100644 api-reference copy/dataframe/dataframe.reset_index.md delete mode 100644 api-reference copy/dataframe/dataframe.select_dtypes.md delete mode 100644 api-reference copy/dataframe/dataframe.set_index.md delete mode 100644 api-reference copy/dataframe/dataframe.shape.md delete mode 100644 api-reference copy/dataframe/dataframe.sort_index.md delete mode 100644 api-reference copy/dataframe/dataframe.sort_values.md delete mode 100644 api-reference copy/dataframe/dataframe.tensor.md delete mode 100644 api-reference copy/dataframe/dataframe.to_csv.md delete mode 100644 api-reference copy/dataframe/dataframe.to_excel.md delete mode 100644 api-reference copy/dataframe/dataframe.to_json.md delete mode 100644 api-reference copy/dataframe/dataframe.values.md delete mode 100644 api-reference copy/general-functions/README.md delete mode 100644 api-reference copy/general-functions/danfo.concat.md delete mode 100644 api-reference copy/general-functions/danfo.date_range.md delete mode 100644 api-reference copy/general-functions/danfo.get_dummies.md delete mode 100644 api-reference copy/general-functions/danfo.labelencoder.md delete mode 100644 api-reference copy/general-functions/danfo.merge.md delete mode 100644 api-reference copy/general-functions/danfo.minmaxscaler.md delete mode 100644 api-reference copy/general-functions/danfo.onehotencoder.md delete mode 100644 api-reference copy/general-functions/danfo.standardscaler.md delete mode 100644 api-reference copy/general-functions/danfo.to_datetime.md delete mode 100644 api-reference copy/groupby.md delete mode 100644 api-reference copy/groupby/README.md delete mode 100644 api-reference copy/groupby/groupby.agg.md delete mode 100644 api-reference copy/groupby/groupby.apply.md delete mode 100644 api-reference copy/groupby/groupby.col.md delete mode 100644 api-reference copy/groupby/groupby.count.md delete mode 100644 api-reference copy/groupby/groupby.cummax.md delete mode 100644 api-reference copy/groupby/groupby.cummin.md delete mode 100644 api-reference copy/groupby/groupby.cumprod.md delete mode 100644 api-reference copy/groupby/groupby.cumsum.md delete mode 100644 api-reference copy/groupby/groupby.get_groups.md delete mode 100644 api-reference copy/groupby/groupby.max.md delete mode 100644 api-reference copy/groupby/groupby.mean.md delete mode 100644 api-reference copy/groupby/groupby.min.md delete mode 100644 api-reference copy/groupby/groupby.std.md delete mode 100644 api-reference copy/groupby/groupby.sum.md delete mode 100644 api-reference copy/groupby/groupby.var.md delete mode 100644 api-reference copy/input-output/README.md delete mode 100644 api-reference copy/input-output/danfo.read_csv.md delete mode 100644 api-reference copy/input-output/danfo.read_excel.md delete mode 100644 api-reference copy/input-output/danfo.read_json.md delete mode 100644 api-reference copy/input-output/danfo.to_csv.md delete mode 100644 api-reference copy/input-output/danfo.to_excel.md delete mode 100644 api-reference copy/input-output/danfo.to_json.md delete mode 100644 api-reference copy/input-output/read.md delete mode 100644 api-reference copy/plotting/README.md delete mode 100644 api-reference copy/plotting/bar-charts.md delete mode 100644 api-reference copy/plotting/box-plots.md delete mode 100644 api-reference copy/plotting/configuring-your-plots.md delete mode 100644 api-reference copy/plotting/histograms.md delete mode 100644 api-reference copy/plotting/line-charts.md delete mode 100644 api-reference copy/plotting/pie-charts.md delete mode 100644 api-reference copy/plotting/scatter-plots.md delete mode 100644 api-reference copy/plotting/tables.md delete mode 100644 api-reference copy/plotting/timeseries-plots.md delete mode 100644 api-reference copy/plotting/violin-plots.md delete mode 100644 api-reference copy/series/README.md delete mode 100644 api-reference copy/series/creating-a-series.md delete mode 100644 api-reference copy/series/danfo.series.add.md delete mode 100644 api-reference copy/series/danfo.series.apply.md delete mode 100644 api-reference copy/series/danfo.series.copy.md delete mode 100644 api-reference copy/series/danfo.series.count.md delete mode 100644 api-reference copy/series/danfo.series.describe.md delete mode 100644 api-reference copy/series/danfo.series.div.md delete mode 100644 api-reference copy/series/danfo.series.head.md delete mode 100644 api-reference copy/series/danfo.series.map.md delete mode 100644 api-reference copy/series/danfo.series.max.md delete mode 100644 api-reference copy/series/danfo.series.maximum.md delete mode 100644 api-reference copy/series/danfo.series.mean.md delete mode 100644 api-reference copy/series/danfo.series.median.md delete mode 100644 api-reference copy/series/danfo.series.min.md delete mode 100644 api-reference copy/series/danfo.series.minimum.md delete mode 100644 api-reference copy/series/danfo.series.mod.md delete mode 100644 api-reference copy/series/danfo.series.mode.md delete mode 100644 api-reference copy/series/danfo.series.mul.md delete mode 100644 api-reference copy/series/danfo.series.pow.md delete mode 100644 api-reference copy/series/danfo.series.reset_index.md delete mode 100644 api-reference copy/series/danfo.series.round.md delete mode 100644 api-reference copy/series/danfo.series.sample.md delete mode 100644 api-reference copy/series/danfo.series.set_index.md delete mode 100644 api-reference copy/series/danfo.series.sort_values.md delete mode 100644 api-reference copy/series/danfo.series.std.md delete mode 100644 api-reference copy/series/danfo.series.sub.md delete mode 100644 api-reference copy/series/danfo.series.sum-1.md delete mode 100644 api-reference copy/series/danfo.series.tail.md delete mode 100644 api-reference copy/series/danfo.series.tostring.md delete mode 100644 api-reference copy/series/danfo.series.var.md delete mode 100644 api-reference copy/series/series.abs.md delete mode 100644 api-reference copy/series/series.add.md delete mode 100644 api-reference copy/series/series.and.md delete mode 100644 api-reference copy/series/series.append.md delete mode 100644 api-reference copy/series/series.apply.md delete mode 100644 api-reference copy/series/series.argmax.md delete mode 100644 api-reference copy/series/series.argmin.md delete mode 100644 api-reference copy/series/series.argsort.md delete mode 100644 api-reference copy/series/series.astype.md delete mode 100644 api-reference copy/series/series.copy.md delete mode 100644 api-reference copy/series/series.corr.md delete mode 100644 api-reference copy/series/series.count.md delete mode 100644 api-reference copy/series/series.cummax.md delete mode 100644 api-reference copy/series/series.cummin.md delete mode 100644 api-reference copy/series/series.cumprod.md delete mode 100644 api-reference copy/series/series.cumsum.md delete mode 100644 api-reference copy/series/series.describe.md delete mode 100644 api-reference copy/series/series.div.md delete mode 100644 api-reference copy/series/series.dot.md delete mode 100644 api-reference copy/series/series.drop_duplicates.md delete mode 100644 api-reference copy/series/series.dropna.md delete mode 100644 api-reference copy/series/series.dt.day.md delete mode 100644 api-reference copy/series/series.dt.hour.md delete mode 100644 api-reference copy/series/series.dt.minute.md delete mode 100644 api-reference copy/series/series.dt.month.md delete mode 100644 api-reference copy/series/series.dt.month_name.md delete mode 100644 api-reference copy/series/series.dt.monthday.md delete mode 100644 api-reference copy/series/series.dt.second.md delete mode 100644 api-reference copy/series/series.dt.weekdays.md delete mode 100644 api-reference copy/series/series.dt.year.md delete mode 100644 api-reference copy/series/series.dtype.md delete mode 100644 api-reference copy/series/series.eq.md delete mode 100644 api-reference copy/series/series.fillna.md delete mode 100644 api-reference copy/series/series.ge.md delete mode 100644 api-reference copy/series/series.gt.md delete mode 100644 api-reference copy/series/series.head.md delete mode 100644 api-reference copy/series/series.iloc.md delete mode 100644 api-reference copy/series/series.index.md delete mode 100644 api-reference copy/series/series.isna.md delete mode 100644 api-reference copy/series/series.le.md delete mode 100644 api-reference copy/series/series.loc.md delete mode 100644 api-reference copy/series/series.lt.md delete mode 100644 api-reference copy/series/series.map.md delete mode 100644 api-reference copy/series/series.max.md delete mode 100644 api-reference copy/series/series.maximum.md delete mode 100644 api-reference copy/series/series.mean.md delete mode 100644 api-reference copy/series/series.median.md delete mode 100644 api-reference copy/series/series.min.md delete mode 100644 api-reference copy/series/series.minimum.md delete mode 100644 api-reference copy/series/series.mod.md delete mode 100644 api-reference copy/series/series.mode.md delete mode 100644 api-reference copy/series/series.mul.md delete mode 100644 api-reference copy/series/series.ndim.md delete mode 100644 api-reference copy/series/series.ne.md delete mode 100644 api-reference copy/series/series.nunique.md delete mode 100644 api-reference copy/series/series.or.md delete mode 100644 api-reference copy/series/series.pow.md delete mode 100644 api-reference copy/series/series.replace.md delete mode 100644 api-reference copy/series/series.reset_index.md delete mode 100644 api-reference copy/series/series.round.md delete mode 100644 api-reference copy/series/series.sample.md delete mode 100644 api-reference copy/series/series.set_index.md delete mode 100644 api-reference copy/series/series.shape.md delete mode 100644 api-reference copy/series/series.size.md delete mode 100644 api-reference copy/series/series.sort_values.md delete mode 100644 api-reference copy/series/series.std.md delete mode 100644 api-reference copy/series/series.str.capitalize.md delete mode 100644 api-reference copy/series/series.str.charat.md delete mode 100644 api-reference copy/series/series.str.concat.md delete mode 100644 api-reference copy/series/series.str.endswith.md delete mode 100644 api-reference copy/series/series.str.includes.md delete mode 100644 api-reference copy/series/series.str.indexof.md delete mode 100644 api-reference copy/series/series.str.join.md delete mode 100644 api-reference copy/series/series.str.lastindexof.md delete mode 100644 api-reference copy/series/series.str.len.md delete mode 100644 api-reference copy/series/series.str.repeat.md delete mode 100644 api-reference copy/series/series.str.replace.md delete mode 100644 api-reference copy/series/series.str.search.md delete mode 100644 api-reference copy/series/series.str.slice.md delete mode 100644 api-reference copy/series/series.str.split.md delete mode 100644 api-reference copy/series/series.str.startswith.md delete mode 100644 api-reference copy/series/series.str.substr.md delete mode 100644 api-reference copy/series/series.str.substring.md delete mode 100644 api-reference copy/series/series.str.tolowercase.md delete mode 100644 api-reference copy/series/series.str.touppercase.md delete mode 100644 api-reference copy/series/series.str.trim.md delete mode 100644 api-reference copy/series/series.sub.md delete mode 100644 api-reference copy/series/series.sum.md delete mode 100644 api-reference copy/series/series.tail.md delete mode 100644 api-reference copy/series/series.tensor.md delete mode 100644 api-reference copy/series/series.unique.md delete mode 100644 api-reference copy/series/series.value_counts.md delete mode 100644 api-reference copy/series/series.values.md delete mode 100644 api-reference copy/series/series.var.md diff --git a/api-reference copy/README.md b/api-reference copy/README.md deleted file mode 100644 index b5d5d28..0000000 --- a/api-reference copy/README.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - This page gives an overview of all public danfo objects, functions and - methods. All classes and functions exposed in danfo.* namespace are public. ---- - -# API reference - -* [General Functions](general-functions/) - * [Data manipulations](general-functions/#data-manipulations) - * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) -* [Input/output](input-output/) - * [CSV](input-output/#csv) - * [JSON](input-output/#json) -* [Series](series/) - * [Attributes](series/#attributes) - * [Conversion](series/#conversion) - * [Indexing, iteration](series/#indexing-iteration) - * [Binary operator functions](series/#binary-operator-functions) - * [Function application, GroupBy & window](series/#function-application-and-groupby) - * [Computations / descriptive stats](series/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](series/#reindexing-selection-label-manipulation) - * [Missing data handling](series/#missing-data-handling) - * [Reshaping, sorting](series/#reshaping-sorting) - * [Accessors](series/#accessors) - * [Serialization / IO / conversion](series/#serialization-io-conversion) -* [DataFrame](dataframe/) - * [Attributes ](dataframe/#attributes) - * [Conversion](dataframe/#conversion) - * [Indexing, iteration](dataframe/#indexing-iteration) - * [Binary operator functions](dataframe/#binary-operator-functions) - * [Function application, GroupBy & window](dataframe/#function-application-and-groupby) - * [Computations / descriptive stats](dataframe/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](dataframe/#reindexing-selection-label-manipulation) - * [Missing data handling](dataframe/#missing-data-handling) - * [Reshaping, sorting, transposing](dataframe/#sorting-and-transposing) - * [Combining / comparing / joining / merging](dataframe/#combining-comparing-joining-merging) - * [Serialization / IO / conversion](dataframe/#serialization-io-conversion) -* [Plotting](plotting/) - * [Line Charts](plotting/line-charts.md) - * [Bar Charts](plotting/bar-charts.md) - * [Scatter Plots](plotting/scatter-plots.md) - * [Histograms](plotting/histograms.md) - * [Pie Charts](plotting/pie-charts.md) - * [Tables](plotting/tables.md) - * [Box Plots](plotting/box-plots.md) - * [Violin Plots](plotting/violin-plots.md) - * [Timeseries Plots](plotting/timeseries-plots.md) -* [GroupBy](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html) - * [Indexing, iteration](groupby/#indexing-iteration) - * [Function application](groupby/#function-application) - * [Computations / descriptive stats](groupby/#computations-descriptive-stats) - diff --git a/api-reference copy/configuration-options.md b/api-reference copy/configuration-options.md deleted file mode 100644 index f4c2136..0000000 --- a/api-reference copy/configuration-options.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: >- - This section describes all user configurable options available on - DataFrame/Series creation. ---- - -# Configuration Options - -On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. - -| Parameter | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | -| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | -| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | -| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| - -> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) - -## Examples of setting configs - -### Add a DataFrame header - -```javascript - const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] - }; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - }, - } -}); -df.print() -``` - -```javascript -╔════════════════════════════════════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟────────────┬───────────────────┬───────────────────┬───────────────────╢ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Configure column size and display format of DataFrame - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -}; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - columns: [ - { alignment: 'left' }, - { alignment: 'center', width: 20 }, - { alignment: 'right' }, - { alignment: 'justify' } - ], - }, - } -}); -df.print() -``` - -```javascript -╔══════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟───┬──────────────────────┬───────┬───────╢ -║ │ Name │ Count │ Price ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧══════════════════════╧═══════╧═══════╝ -``` - -### Configure the number of rows displayed when **print** is called - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250], - -}; -const df = new DataFrame(data, { - config: { - tableMaxColInConsole: 6, - tableMaxRow: 1 - } -}); -df.print() -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference copy/dataframe/README.md b/api-reference copy/dataframe/README.md deleted file mode 100644 index d48a28d..0000000 --- a/api-reference copy/dataframe/README.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. ---- - -# Dataframe - -> `DataFrame`(data, {\ -> **columns:** \[ Array ],\ -> **dtypes:** \[ Array ], **** \ -> **index:** \[Array], \ -> **options**: Object}) - -### Attributes - -| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | -| ------------------------------------------------ | ---------------------------------------- | -| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | - -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| -------------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.select_dtypes`](dataframe.select\_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | - -### Conversion - -| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | -| ------------------------------------------- | -------------------------------------------------- | -| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | -| --------------------------------------------- | ------------------------------------------------------------------ | -| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | -| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | -| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | - -### Binary operator functions - -| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | -| ----------------------------------------- | --------------------------------------------------------------------------------------- | -| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | -| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | -| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | -| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | -| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | -| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | -| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | -| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | -| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | -| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | -| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | - -### Function application & GroupBy - -| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | -| --------------------------------------------- | --------------------------------------------------------- | -| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | -| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | - -### Computations / descriptive stats - -| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | -| --------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | -| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | -| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | -| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | -| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | -| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | -| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | -| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | -| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | -| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | -| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | -| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | - -### Reindexing / selection / label manipulation - -| | | -| ---------------------------------------------------- | ------------------------------------------------------- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset\_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------------------- | ------------------------------------------- | -| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | -| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | -| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | -| [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | - -### Sorting & transposing - -| | | -| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| [`DataFrame.sort_values`](dataframe.sort\_values.md) | Sort by the values along either axis. | -| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | - -### Combining / comparing / joining / merging - -| | | -| ---------------------------------------------------------- | ------------------------------------------------------------------- | -| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | -| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | -| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| -------------------------------------------------------- | ------------------------------------------------------------- | -| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | -| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| -------------------------------------------- | ---------------------------------------------------- | -| [`DataFrame.to_csv`](dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`DataFrame.to_json`](dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference copy/dataframe/creating-a-dataframe.md b/api-reference copy/dataframe/creating-a-dataframe.md deleted file mode 100644 index 0228131..0000000 --- a/api-reference copy/dataframe/creating-a-dataframe.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -description: Creates a DataFrame object from flat structure ---- - -# Creating a DataFrame - -new danfo.**DataFrame**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

columns: Array of column names. If not specified, column names are - auto generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. - -### Creating a `DataFrame` from a JSON object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -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 }] - -df = new dfd.DataFrame(json_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Creating a `DataFrame` from an array of array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] -let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` from a 2D tensor - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -const tf = require("@tensorflow/tfjs-node") - - -let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) -let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) -df.print() -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` - -### Creating a `DataFrame` from an object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) - -console.log(dates); - -obj_data = {'A': dates, - 'B': ["bval1", "bval2", "bval3", "bval4"], - 'C': [10, 20, 30, 40], - 'D': [1.2, 3.45, 60.1, 45], - 'E': ["test", "train", "test", "train"] - } - -df = new dfd.DataFrame(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -//output in console -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D │ E ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying index, dtypes, columns - -You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. - -> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; -let index = ["a", "b"]; -let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] -let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] - -let df = new DataFrame(data1, { index, columns, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying memory mode - -To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: - -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; - -let df = new DataFrame(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. -{% endhint %} - -For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) - diff --git a/api-reference copy/dataframe/danfo.dataframe.abs.md b/api-reference copy/dataframe/danfo.dataframe.abs.md deleted file mode 100644 index 8504222..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.abs.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a DataFrame with the absolute numeric value of each element. ---- - -# DataFrame.abs - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - - **** return **Series** - -## **Examples** - -The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let df_abs = df.abs() -df_abs.abs().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after applying abs function - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.add.md b/api-reference copy/dataframe/danfo.dataframe.add.md deleted file mode 100644 index 925a3cd..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.add.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -description: Get Addition of DataFrame and other, element-wise (binary operator add). ---- - -# DataFrame.add - -danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Addition of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.add(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.add(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 8 │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 9 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.add(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 2 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 9 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 25 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.add(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Addition works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.add(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.addcolumn.md b/api-reference copy/dataframe/danfo.dataframe.addcolumn.md deleted file mode 100644 index ef0ecc9..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.addcolumn.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Add new column to a DataFrame ---- - -# DataFrame.addColumn - -danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | - -**Returns:** - -## **Examples** - -## **Add Array as a new column to DataFrame** - -New columns get added at the end of the DataFrame, and this happens so returns nothing, - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -df.print() - -let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Add Series as a new column to DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -let s = new dfd.Series([1, 2, 3, 4]) -df.addColumn({ "column": "D", "values": s, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.apply.md b/api-reference copy/dataframe/danfo.dataframe.apply.md deleted file mode 100644 index de42294..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.apply.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Apply a function to each element or along a specified axis of a DataFrame. ---- - -# DataFrame.apply - -danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Apply a function along default axis 1 (columns) - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 1 }) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### Apply a function along axis 0 (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 0 }) -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ 6 ║ -╟───┼─────╢ -║ 1 │ 15 ║ -╟───┼─────╢ -║ 2 │ 90 ║ -╟───┼─────╢ -║ 3 │ 206 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.column.md b/api-reference copy/dataframe/danfo.dataframe.column.md deleted file mode 100644 index 7d963a2..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.column.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -description: Return the elements of the specified column in the DataFrame ---- - -# DataFrame.column - -danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------- | ------- | -| column | String | The name of a column in the DataFrame | | - -**Returns:** - - **** return **Series** - -## **Examples** - -## **Select a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { "Name": ["Apples", "App", "Banana", undefined], - "Count": [NaN, 5, NaN, 10] , - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) - -df.column("Name").print() - -//Alternatively, you can retrieve columns by using the object property -df['Name'].print() //produces the same result as above - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -``` -{% endtab %} -{% endtabs %} - -To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) diff --git a/api-reference copy/dataframe/danfo.dataframe.copy.md b/api-reference copy/dataframe/danfo.dataframe.copy.md deleted file mode 100644 index 188179d..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.copy.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Makes a new copy of the DataFrame ---- - -# DataFrame.copy - -danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -**Returns:** - - **** return **new DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) -let new_df = df.copy() -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.count.md b/api-reference copy/dataframe/danfo.dataframe.count.md deleted file mode 100644 index 637cbf4..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.count.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Count non-NaN cells for each column or row. The values NaN and undefined are - considered NaN ---- - -# DataFrame.count - -danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Count Non-NaN values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ Name │ 3 ║ -╟───────┼──────────────────────╢ -║ Count │ 2 ║ -╟───────┼──────────────────────╢ -║ Price │ 4 ║ -╚═══════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Count Non-NaN values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference copy/dataframe/danfo.dataframe.cummax.md b/api-reference copy/dataframe/danfo.dataframe.cummax.md deleted file mode 100644 index fb69bb5..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.cummax.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative maximum over a DataFrame or Series axis. ---- - -# DataFrame.cummax - -danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative maximum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 11 │ 20 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 11 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 11 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative maximum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 15 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 89 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cummin.md b/api-reference copy/dataframe/danfo.dataframe.cummin.md deleted file mode 100644 index be026a6..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.cummin.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative minimum over a DataFrame or Series axis. ---- - -# DataFrame.cummin - -danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative minimum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 15 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative minimum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 11 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 2 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cumprod.md b/api-reference copy/dataframe/danfo.dataframe.cumprod.md deleted file mode 100644 index 06ad53a..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.cumprod.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative product over a DataFrame or Series axis. ---- - -# DataFrame.cumprod - -danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative product of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 10 │ 18 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 300 │ 720 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 26700 │ 56160 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative product of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod({axis: 1}) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 60 │ 2400 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 178 │ 13884 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.cumsum.md b/api-reference copy/dataframe/danfo.dataframe.cumsum.md deleted file mode 100644 index 07be896..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.cumsum.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative sum over a DataFrame or Series axis. ---- - -# DataFrame.cumsum - -danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative sum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 12 │ 35 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 14 │ 65 │ 49 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 16 │ 154 │ 127 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative sum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 31 │ 34 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 16 │ 22 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 32 │ 72 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 91 │ 169 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.describe.md b/api-reference copy/dataframe/danfo.dataframe.describe.md deleted file mode 100644 index 0540873..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.describe.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -description: >- - Generate descriptive statistics for each numeric column. Numeric columns are - of type Int and float. ---- - -# DataFrame.describe - -danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] -let col_names = ["col1", "col2", "col3", "col4"] -let df = new dfd.DataFrame(data, {columns: col_names}) - -df.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 3 │ 3 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0 │ 2 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 2 │ 4 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 360 │ 180 │ 360 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference copy/dataframe/danfo.dataframe.div.md b/api-reference copy/dataframe/danfo.dataframe.div.md deleted file mode 100644 index c98c66e..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.div.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -description: >- - Get Float division of DataFrame and other, element-wise (binary operator - truediv). ---- - -# DataFrame.div - -danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Division of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.div(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.div(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0.25 │ 0.6000000238418… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0.4000000059604… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1.25 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0.25 │ 0.8000000119209… ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of **** DataFrame **with** a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.div(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0.1000000014901… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.8000000119209… │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0.25 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of **** Array **with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.div(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.div(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.dropna.md b/api-reference copy/dataframe/danfo.dataframe.dropna.md deleted file mode 100644 index 429bcbe..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.dropna.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Remove missing values (NaNs, undefined, null) for DataFrame ---- - -# DataFrame.dropna - -danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | -| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace:** false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Drop rows (axis=0) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -let df_drop = df.dropna(0) -df_drop.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop columns (axis=1) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -df.dropna({axis: 1, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.eq.md b/api-reference copy/dataframe/danfo.dataframe.eq.md deleted file mode 100644 index 5f3cf2a..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.eq.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -description: Get Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.eq - -danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.eq(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.eq(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.eq(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.eq(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.fillna.md b/api-reference copy/dataframe/danfo.dataframe.fillna.md deleted file mode 100644 index 2ddb860..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.fillna.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -description: >- - Fill NaN/undefined values using the specified method. Detect missing values - for an array-like object. ---- - -# DataFrame.fillna - -danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| values | Array \| Scalar | The list of value(s) to use for replacement. | | -| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Fill missing values in specified columns with specified values - -Missing values are NaN, undefined or null values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -df.print() - -let values = ["Apples", df["Count"].mean()] -let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//Before filling -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ NaN │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ NaN │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After filling - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 7.5 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 7.5 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ -``` -{% endtab %} -{% endtabs %} - -### Fill all columns with NaNs with a specified value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") - -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill NaNs inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let values = ["Apples", df["Count"].mean()] -df.fillna(values, { - columns: ["Name", "Count"], - inplace: true -}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.ge.md b/api-reference copy/dataframe/danfo.dataframe.ge.md deleted file mode 100644 index 8e5401b..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.ge.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -description: >- - Get Greater or Equal to of DataFrame and other, element-wise (binary operator - eq). ---- - -# DataFrame.ge - -danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.ge(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ge(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ge(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.ge(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.groupby.md b/api-reference copy/dataframe/danfo.dataframe.groupby.md deleted file mode 100644 index e7d084f..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.groupby.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Group DataFrame using a mapper or by a Series of columns. ---- - -# DataFrame.groupby - -danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | ----------------------------------------------------- | ------- | -| columns | Array | The names of a column(s) in the DataFrame to group by | | - -**Returns:** - - **** return **DataFrame.groups** - -## **Examples** - -## **Groupby a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]) -console.log(group_df) - -//GroupBy Object -GroupBy { - key_col: [ 'A' ], - col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, - data: [ - [ 'Pear', 2, 3 ], - [ 'Pear', 5, 6 ], - [ 'Apple', 30, 40 ], - [ 'Apple', 89, 78 ] - ], - column_name: [ 'A', 'B', 'C' ], - data_tensors: { - Pear: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - '$index': [Array], - '$dtypes': [Array], - '$columns': [Array] - }, - Apple: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - ... - '$columns': [Array] - } - }, - col_dtype: [ 'string' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: - -1. [count](danfo.dataframe.count.md) -2. [sum](danfo.dataframe.sum.md) -3. [std](danfo.dataframe.std.md) -4. [var](danfo.dataframe.var.md) -5. [mean](danfo.dataframe.mean.md) -6. [cumsum](danfo.dataframe.cumsum.md) -7. [cummax](danfo.dataframe.cummax.md) -8. [cumprod](danfo.dataframe.cumprod.md) -9. [cummin](danfo.dataframe.cummin.md) -10. [max](danfo.dataframe.max.md) -11. [min](danfo.dataframe.min.md) - -## Example of Groupby and apply a sum function - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]).sum() - -group_df.print() - -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B_sum │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 7 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 119 │ 118 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -## **Groupby a two columns from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A", "B"]).sum() - -group_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 2 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Apple │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference copy/dataframe/danfo.dataframe.gt.md b/api-reference copy/dataframe/danfo.dataframe.gt.md deleted file mode 100644 index ec3f7ba..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.gt.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -description: Get Greater than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.gt - -danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.gt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.gt(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.gt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.gt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.head.md b/api-reference copy/dataframe/danfo.dataframe.head.md deleted file mode 100644 index 3fe62c4..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.head.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the first n rows of the DataFrame based on position. ---- - -# DataFrame.head - -danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.head(2) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.iloc.md b/api-reference copy/dataframe/danfo.dataframe.iloc.md deleted file mode 100644 index ffd7e25..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.iloc.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -description: Purely integer-location based indexing for selection by position. ---- - -# DataFrame.iloc - -danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A string slice object with ints, e.g. `"1:7"` -* A boolean array. - -_**Note:** only the start index is included._ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,1,3]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row and return all columns** - -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: ["1:3"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of column and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by the specified index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,3], columns: [1,2]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by slices - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -╔═══╤═══════════════════╗ -║ │ Count ║ -╟───┼───────────────────╢ -║ 2 │ 30 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### More default slicing behavior - -If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.isna.md b/api-reference copy/dataframe/danfo.dataframe.isna.md deleted file mode 100644 index 830bda5..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.isna.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Return a boolean same-sized object indicating if the values are NaN. - NaN/undefined values gets mapped to true values, and everything else gets - mapped to false values. ---- - -# DataFrame.isna - -danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.isna().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ false │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ false │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.it.md b/api-reference copy/dataframe/danfo.dataframe.it.md deleted file mode 100644 index 3759197..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.it.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: Get Less than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.It - -danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.lt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10, 40]) - -let df_rep = df.lt(sf, { axis: 1 }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.lt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.lt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.le.md b/api-reference copy/dataframe/danfo.dataframe.le.md deleted file mode 100644 index 31ce3f7..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.le.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: >- - Get Less than or Equal to of DataFrame and other, element-wise (binary - operator eq). ---- - -# DataFrame.le - -danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.le(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.le(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.le(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.le(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.loc.md b/api-reference copy/dataframe/danfo.dataframe.loc.md deleted file mode 100644 index abdcdd9..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.loc.md +++ /dev/null @@ -1,367 +0,0 @@ ---- -description: Access a group of rows and columns by label(s) ---- - -# DataFrame.loc - -danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -`.loc()` is label position based-from `0` to `length-1` of the row axis. - -Allowed inputs for are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Index by specific rows and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({rows: ["a", "c"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a list of column names and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({columns: ["Count", "Price"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ a │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ b │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Index both axes by the specified labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: ["c","d"], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after slicing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ Banana │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ Pear │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -df`.loc({ row: [a:e]}).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -df``.loc({ row: [`"a":"e"`]}).print()``\ -\ -_**Inner**_ _**quotes are not needed for numeric indices!**_ -{% endhint %} - -### Slice DataFrame rows by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.loc({ rows: df["Count"].gt(6) }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -### Slice DataFrame rows by multiple boolean conditions - -{% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame._ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let condition = df["Count"].gt(6).and(df["Price"].lt(250)) -let sub_df = df.loc({ rows: condition }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` - -### Slice DataFrame with boolean mask - -{% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) - -let sub_df = df.loc({ rows: [false, true, true, true] }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` diff --git a/api-reference copy/dataframe/danfo.dataframe.max.md b/api-reference copy/dataframe/danfo.dataframe.max.md deleted file mode 100644 index a5c2119..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.max.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Return the maximum of the values for the requested axis. ---- - -# DataFrame.max - -danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Return the maximum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.max().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 11 ║ -╟───┼──────────────────────╢ -║ B │ 89 ║ -╟───┼──────────────────────╢ -║ C │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the maximum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.max({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 15 ║ -╟───┼──────────────────────╢ -║ 2 │ 40 ║ -╟───┼──────────────────────╢ -║ 3 │ 89 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.mean.md b/api-reference copy/dataframe/danfo.dataframe.mean.md deleted file mode 100644 index 172cff5..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.mean.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the mean of the values for the requested axis. ---- - -# DataFrame.mean - -danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Computes the mean of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.mean().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 4 ║ -╟───┼──────────────────────╢ -║ B │ 38.5 ║ -╟───┼──────────────────────╢ -║ C │ 31.75 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Computes the mean of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -let cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.mean({ axis: 0 }).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11.333333015441895 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.333333492279053 ║ -╟───┼──────────────────────╢ -║ 2 │ 24 ║ -╟───┼──────────────────────╢ -║ 3 │ 56.33333206176758 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.median.md b/api-reference copy/dataframe/danfo.dataframe.median.md deleted file mode 100644 index 3e33583..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.median.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the median of the values for the requested axis. ---- - -# DataFrame.median - -danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculates the median of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.median().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 2 ║ -╟───┼──────────────────────╢ -║ B │ 25 ║ -╟───┼──────────────────────╢ -║ C │ 23 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the median of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.median({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 30 ║ -╟───┼──────────────────────╢ -║ 3 │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.min.md b/api-reference copy/dataframe/danfo.dataframe.min.md deleted file mode 100644 index 49a13d6..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.min.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the minimum of the values for the requested axis. ---- - -# DataFrame.min - -danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Returns the minimum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.min().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 1 ║ -╟───┼──────────────────────╢ -║ B │ 15 ║ -╟───┼──────────────────────╢ -║ C │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the minimum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.min({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.mod.md b/api-reference copy/dataframe/danfo.dataframe.mod.md deleted file mode 100644 index 18558e6..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.mod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Get Modulo of DataFrame and other, element-wise (binary operator mod). ---- - -# DataFrame.mod - -danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Modulo of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mod(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mod(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 4 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mod(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 5 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mod(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Modulo works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mod(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.mul.md b/api-reference copy/dataframe/danfo.dataframe.mul.md deleted file mode 100644 index 3303d77..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.mul.md +++ /dev/null @@ -1,252 +0,0 @@ ---- -description: Get Multiplication of dataframe and other, element-wise (binary operator mul). ---- - -# DataFrame.mul - -danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Multiplication of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mul(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mul(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 4 │ 15 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 16 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mul(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 100 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 8 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mul(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mul(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.ne.md b/api-reference copy/dataframe/danfo.dataframe.ne.md deleted file mode 100644 index dd45cf0..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.ne.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.ne - -danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.ne(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ne(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ne(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10, 40, 30, 20] - -let df_rep = df.le(val) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ true │ false │ false │ true ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ false │ true │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.pow.md b/api-reference copy/dataframe/danfo.dataframe.pow.md deleted file mode 100644 index e6f1e6c..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.pow.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -description: >- - Get Exponential power of dataframe and other, element-wise (binary operator - pow). ---- - -# DataFrame.pow - -danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Exponential of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.pow(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.pow(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 243 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 256 │ 32 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 625 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 1024 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.pow(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1048576 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1024 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 95367433551872 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 16 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.pow(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Exponential works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.pow(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.query.md b/api-reference copy/dataframe/danfo.dataframe.query.md deleted file mode 100644 index 129c8e7..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.query.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -description: >- - Query the DataFrame by the result of a logical comparison or boolean mask. - Supports logical operations like (">", "<", ">=", "<=", and. "==") ---- - -# DataFrame.query - -danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | - -**Returns:** - - **** return **new DataFrame** - -## **Examples** - -## **Query a DataFrame using a boolean mask** - -{% hint style="info" %} -Querying by a boolean condition is supported from v0.3.0 and above. -{% endhint %} - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5) }) -query_df.print() //after query -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) -query_df.print() //after query - -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -## **Query a DataFrame using logical operators** - -To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() //before query - -let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) -query_df.print() //after query -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query by a string column in a DataFrame** - -The query method also works on string columns. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query a DataFrame inplace** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.query({ - column: "B", - is: ">", - to: 5, - inplace: true -}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.replace.md b/api-reference copy/dataframe/danfo.dataframe.replace.md deleted file mode 100644 index 82fa16d..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.replace.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -description: Replaces values in a DataFrame with specified values ---- - -# DataFrame.replace - -> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| oldValue | String, boolean, Number | The value you want to replace | | -| newValue | String, boolean, Number | The new value you want to replace the old value with | | -| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -**** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_rep = df.replace(10, -999, { columns: ["Col1"] }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -999 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 45 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 56 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -999 │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By not specifying a **** column**,** the **** replace works on all columns **** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] -let df = new dfd.DataFrame(data) -//replace value in all column -let df_rep = df.replace("A", "BOY") - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ BOY │ BOY │ BOY │ B ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ B │ C │ C │ D ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.round.md b/api-reference copy/dataframe/danfo.dataframe.round.md deleted file mode 100644 index e12cb52..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.round.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: Round elements in a DataFrame to a specified number of decimal places. ---- - -# DataFrame.round - -danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Round elements to 1dp (Default) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1 │ 3.6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.1 │ 40.2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Round elements to a specified number of decimal places - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round(2) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round operation - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.12 │ 3.57 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.23 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference copy/dataframe/danfo.dataframe.sample.md b/api-reference copy/dataframe/danfo.dataframe.sample.md deleted file mode 100644 index b8a4c96..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.sample.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: Return a random sample of rows from DataFrame. ---- - -# DataFrame.sample - -danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | - -**Returns:** - - **** return **{Promies} resolves to DataFrame** - -**** - -## Sample a DataFrame randomly - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(2); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sample a DataFrame randomly with seed - -By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(3, { seed: 2 }); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.std.md b/api-reference copy/dataframe/danfo.dataframe.std.md deleted file mode 100644 index 1a37e2e..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.std.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return sample standard deviation over requested axis. ---- - -# DataFrame.std - -danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculates the standard deviation of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4.69041575982343 ║ -╟───┼──────────────────────╢ -║ 1 │ 34.23935357645254 ║ -╟───┼──────────────────────╢ -║ 2 │ 35.103418636936205 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the standard deviation of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 8.504900548115383 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.094598884597588 ║ -╟───┼──────────────────────╢ -║ 2 │ 19.697715603592208 ║ -╟───┼──────────────────────╢ -║ 3 │ 47.37439533475159 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference copy/dataframe/danfo.dataframe.sub.md b/api-reference copy/dataframe/danfo.dataframe.sub.md deleted file mode 100644 index e36ddcc..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.sub.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -description: Get Subtraction of dataframe and other, element-wise (binary operator sub). ---- - -# DataFrame.sub - -danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Subtraction of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.sub(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.sub(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ -3 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ -3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ -5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -3 │ -1 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.sub(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ -18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ -1 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ -15 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -10 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.sub(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Subtraction works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.sub(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/dataframe/danfo.dataframe.sum.md b/api-reference copy/dataframe/danfo.dataframe.sum.md deleted file mode 100644 index 3937d3f..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.sum.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Return the sum of the values for the requested axis. ---- - -# DataFrame.sum - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Sum elements along default axis (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum() -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤════════════════════╗ -║ A │ 37.199999999999996 ║ -╟───┼────────────────────╢ -║ B │ 41 ║ -╟───┼────────────────────╢ -║ C │ -10 ║ -╚═══╧════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sum elements along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum({axis: 0}) -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ sum ║ -╟───┼──────────────────────╢ -║ 0 │ 33.9 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 82.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -54 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.tail.md b/api-reference copy/dataframe/danfo.dataframe.tail.md deleted file mode 100644 index 165acac..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.tail.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the last n rows from the DataFrame based on position. ---- - -# DataFrame.tail - -danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.tail(3) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/danfo.dataframe.var.md b/api-reference copy/dataframe/danfo.dataframe.var.md deleted file mode 100644 index ea0daf2..0000000 --- a/api-reference copy/dataframe/danfo.dataframe.var.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return unbiased variance over requested axis. ---- - -# DataFrame.var - -danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculate variance of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 22 ║ -╟───┼──────────────────────╢ -║ 1 │ 1172.3333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 1232.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculate variance of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 72.33333333333334 ║ -╟───┼──────────────────────╢ -║ 1 │ 50.33333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 388 ║ -╟───┼──────────────────────╢ -║ 3 │ 2244.333333333333 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference copy/dataframe/dataframe.append.md b/api-reference copy/dataframe/dataframe.append.md deleted file mode 100644 index bc2e29d..0000000 --- a/api-reference copy/dataframe/dataframe.append.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -description: Adds new row to the end of a DataFrame ---- - -# DataFrame.append - -danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] - -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | -| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Appends a new row to the end of a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data) -df.print() - -let new_df = df.append([[20, 40, 60, "d"]], [3]) -new_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 40 │ 60 │ d ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/dataframe/dataframe.apply_map.md b/api-reference copy/dataframe/dataframe.apply_map.md deleted file mode 100644 index 3819821..0000000 --- a/api-reference copy/dataframe/dataframe.apply_map.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Apply a function to a Dataframe values element-wise. ---- - -# DataFrame.apply\_map - -danfo.DataFrame.**apply\_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Apply a function to all values in a DataFrame - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - short_name: ["NG", "GH", "EGY", "SA"], - long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] -} -let df = new dfd.DataFrame(data) - -function lower(x) { - return `${x}`.toLowerCase() -} - -let df_new = df.apply_map(lower) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ short_name │ long_name ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ ng │ nigeria ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ gh │ ghana ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ egy │ eqypt ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ sa │ south africa ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.astype.md b/api-reference copy/dataframe/dataframe.astype.md deleted file mode 100644 index e6434dc..0000000 --- a/api-reference copy/dataframe/dataframe.astype.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -description: Cast column of a DataFrame to a specified dtype. ---- - -# DataFrame.astype - -danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Cast a float dtype column to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.print() -df.ctypes.print() - -let df_new = df.astype({column: "A", dtype: "int32"}) -df_new.print() - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before casting -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ - - - //after casting - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Casting a string column of numbers to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["20", "13", "45", "90"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ 13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ 45 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -**Note:** Casting a string column of alphabets/words to numeric form will return NaNs as values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.axes.md b/api-reference copy/dataframe/dataframe.axes.md deleted file mode 100644 index 399a0a4..0000000 --- a/api-reference copy/dataframe/dataframe.axes.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: >- - Return an Object containing the axes of the DataFrame. It has the row axis - labels and column axis labels as the only members. They are returned in that - order. ---- - -# DataFrame.axis - -danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Object** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.axis) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -{ index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.drop.md b/api-reference copy/dataframe/dataframe.drop.md deleted file mode 100644 index 0b742aa..0000000 --- a/api-reference copy/dataframe/dataframe.drop.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -description: >- - Drop specified labels from rows or columns.Remove rows or columns by - specifying label names and corresponding axis. ---- - -# DataFrame.drop - -danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Drop columns by specifying the names - -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.drop({ columns: ["C", "B"], inplace: true }); -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ D ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ a ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ b ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ c ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ c ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying int labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] -} - -let df = new dfd.DataFrame(data) -df.drop({ index: [0, 2], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying string labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.drop({ index: ["a", "c"], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.dtypes.md b/api-reference copy/dataframe/dataframe.dtypes.md deleted file mode 100644 index 791d296..0000000 --- a/api-reference copy/dataframe/dataframe.dtypes.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Return the inferred column types in the DataFrame. This returns a Series with - the data type of each column. The result’s index is the original DataFrame’s - columns. ---- - -# DataFrame.ctypes - -danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] - -**Returns:** - - **** return **Series** - -## **Examples** - -Returns auto-generated **** index of a **** DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Columns with mixed types are represented as **string.** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference copy/dataframe/dataframe.index.md b/api-reference copy/dataframe/dataframe.index.md deleted file mode 100644 index a185e63..0000000 --- a/api-reference copy/dataframe/dataframe.index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -description: The index (row labels) of the DataFrame. ---- - -# DataFrame.index - -danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -## **Examples** - -Returns auto-generated **** index of a **** DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[0, 1, 2, 3] -``` -{% endtab %} -{% endtabs %} - - - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["r1", "r2", "r3", "r4"]) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 'r1', 'r2', 'r3', 'r4' ] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.ndim.md b/api-reference copy/dataframe/dataframe.ndim.md deleted file mode 100644 index c64dd09..0000000 --- a/api-reference copy/dataframe/dataframe.ndim.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: >- - Return an int representing the number of axes / array dimensions. Returns 1 if - Series. Otherwise return 2 for DataFrame. ---- - -# DataFrame.ndim - -danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** - -**Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.ndim) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -2 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.nunique-1.md b/api-reference copy/dataframe/dataframe.nunique-1.md deleted file mode 100644 index 8166904..0000000 --- a/api-reference copy/dataframe/dataframe.nunique-1.md +++ /dev/null @@ -1,98 +0,0 @@ -# DataFrame.nunique - -danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | -------------------------------------- | ------- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | - -**Returns:** - - **** return **Series** - -## **Examples** - -### Return number of unique values along column axis (axis=1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 4 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} - -### Return number of unique values in row axis (axis=0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique(axis=0).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note:** To get the unique elements along an axis, use **** [DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference copy/dataframe/dataframe.print.md b/api-reference copy/dataframe/dataframe.print.md deleted file mode 100644 index d03232d..0000000 --- a/api-reference copy/dataframe/dataframe.print.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: >- - Pretty prints default (10) number of rows in a DataFrame or Series to the - console ---- - -# DataFrame.print - -danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ FR ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ GH ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Using JavaScript default **console.log** to display a DataFrame will return the Object instead unless you manually cast it to a String - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -console.log(df) -console.log(String(df)); -// console.log(df + ""); //same result as above -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -DataFrame { - '$isSeries': false, - '$config': Configs { - tableDisplayConfig: {}, - tableMaxRow: 10, - tableMaxColInConsole: 21, - dtypeTestLim: 7, - lowMemoryMode: false - }, - '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], - '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], - '$index': [ 0, 1, 2 ], - '$dtypes': [ 'float32', 'int32', 'string' ], - '$columns': [ 'Abs', 'Count', 'country code' ] -} -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ FR ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ GH ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.rename.md b/api-reference copy/dataframe/dataframe.rename.md deleted file mode 100644 index c33ce99..0000000 --- a/api-reference copy/dataframe/dataframe.rename.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: >- - Change axes labels. Object values must be unique (1-to-1). Labels not - contained in a dict / Series will be left as-is. Extra labels listed don’t - throw an error. ---- - -# DataFrame.rename - -danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Rename columns - -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df.rename({ mapper: {"A": "new_name"},inplace: true }) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename more the one column at time - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ new_c ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename index by labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df = df.rename({ mapper: { "a": 0 }, axis: 0 }) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.reset_index.md b/api-reference copy/dataframe/dataframe.reset_index.md deleted file mode 100644 index ddee8e0..0000000 --- a/api-reference copy/dataframe/dataframe.reset_index.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -description: Reset the index of the DataFrame, and use the default one instead. ---- - -# DataFrame.reset\_index - -danfo.DataFrame.**reset\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df.print() - -df.reset_index({ inplace: true }) //inplace -//df = df.reset_index() //not in inplace - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.select_dtypes.md b/api-reference copy/dataframe/dataframe.select_dtypes.md deleted file mode 100644 index ba5044e..0000000 --- a/api-reference copy/dataframe/dataframe.select_dtypes.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return a subset of the DataFrame’s columns based on the column dtypes. ---- - -# DataFrame.select\_dtypes - -danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | -------------------------------- | ------- | -| include | Array | List of column dtypes to return | | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -float_df = df.select_dtypes(['float32']) -float_df.print() - -mix_df = df.select_dtypes(include=['float32', "int32"]) -mix_df.print() - -str_df = df.select_dtypes(include=['string']) -str_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//select float column(s) -╔═══╤══════════════════════╗ -║ │ A ║ -╟───┼──────────────────────╢ -║ 0 │ -20.1 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 2 │ 47.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -20 ║ -╚═══╧══════════════════════╝ - - - //select both float and int columns - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//return string type column -╔═══╤══════════════════════╗ -║ │ D ║ -╟───┼──────────────────────╢ -║ 0 │ a ║ -╟───┼──────────────────────╢ -║ 1 │ b ║ -╟───┼──────────────────────╢ -║ 2 │ 20 ║ -╟───┼──────────────────────╢ -║ 3 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.set_index.md b/api-reference copy/dataframe/dataframe.set_index.md deleted file mode 100644 index e82c213..0000000 --- a/api-reference copy/dataframe/dataframe.set_index.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -description: >- - Set the DataFrame index using existing columns or an array (of the equal - length). ---- - -# DataFrame.set_index - -danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | - -## **Examples** - -### **Setting index to a column in the DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ -20 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 30 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **** - -### **Setting index to a column in the DataFrame and dropping the column** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", drop: true, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ B │ C ║ -╟────────────┼───────────────────┼───────────────────╢ -║ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Set index to an array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.print() - -let new_index = ["a", "b", "c"] -df.set_index({index: new_index, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). diff --git a/api-reference copy/dataframe/dataframe.shape.md b/api-reference copy/dataframe/dataframe.shape.md deleted file mode 100644 index 746491d..0000000 --- a/api-reference copy/dataframe/dataframe.shape.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -description: Returns an Array representing the dimensionality of the DataFrame. ---- - -# DataFrame.shape - -danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.shape) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[4,3] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.sort_index.md b/api-reference copy/dataframe/dataframe.sort_index.md deleted file mode 100644 index 81d5b7f..0000000 --- a/api-reference copy/dataframe/dataframe.sort_index.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Sort DataFrame by index ---- - -# DataFrame.sort\_index - -DataFrame.**sort\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], - index: ["b", "a", "c"] }) -df.print() - -let df2 = df.sort_index({ ascending: false }) -df2.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after sorting in descending order - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/dataframe/dataframe.sort_values.md b/api-reference copy/dataframe/dataframe.sort_values.md deleted file mode 100644 index 54345b1..0000000 --- a/api-reference copy/dataframe/dataframe.sort_values.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Sort a Dataframe in ascending or descending order by a specified column name. ---- - -# DataFrame.sort\_values - -danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "C", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Sort DataFrame by a column in descending order** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "B", inplace: true, ascending: false}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.tensor.md b/api-reference copy/dataframe/dataframe.tensor.md deleted file mode 100644 index 822886e..0000000 --- a/api-reference copy/dataframe/dataframe.tensor.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -description: >- - Return a Tensorflow tensor representation of the DataFrame. Only the values in - the DataFrame will be returned, the axes labels will be removed. ---- - -# DataFrame.tensor - -danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **tf.tensor** - -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30]} - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -Tensor - [[-20 , 34, 20], - [30 , -4, 20], - [47.2999992, 5 , 30], - [-20 , 6 , 30]] -``` -{% endtab %} -{% endtabs %} - -String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 - -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 0, - rankType: '2' -} - -Tensor - [[20.2000008, 34, NaN], - [30 , 4 , NaN], - [47.2999992, 5 , NaN]] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/dataframe/dataframe.to_csv.md b/api-reference copy/dataframe/dataframe.to_csv.md deleted file mode 100644 index 8e84e9a..0000000 --- a/api-reference copy/dataframe/dataframe.to_csv.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -description: Convert DataFrame data to a comma-separated values (csv) ---- - -# DataFrame.to\_csv - -DataFrame.**to\_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| | | | | -| -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -*** - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = df.to_csv({ download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in browser - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ fileName: "testOut.csv", download: true}); -``` diff --git a/api-reference copy/dataframe/dataframe.to_excel.md b/api-reference copy/dataframe/dataframe.to_excel.md deleted file mode 100644 index 4adf437..0000000 --- a/api-reference copy/dataframe/dataframe.to_excel.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# DataFrame.to_excel - -> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in a browser - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ fileName: "testOut.xlsx"}); -``` diff --git a/api-reference copy/dataframe/dataframe.to_json.md b/api-reference copy/dataframe/dataframe.to_json.md deleted file mode 100644 index 326f422..0000000 --- a/api-reference copy/dataframe/dataframe.to_json.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -description: Convert DataFrame to JSON format ---- - -# DataFrame.to\_json - -> DataFrame.**to\_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| | | | | -| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = df.to_json({ download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = df.to_json({ - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ fileName: "test_out.json" }); -``` diff --git a/api-reference copy/dataframe/dataframe.values.md b/api-reference copy/dataframe/dataframe.values.md deleted file mode 100644 index 598e395..0000000 --- a/api-reference copy/dataframe/dataframe.values.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Return a the JavaScript array representation of the DataFrame. ---- - -# DataFrame.values - -danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Array** - -**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -console.log(df.values) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - [ -20.1, 34, 20 ], - [ 30, -4, -20 ], - [ 47.3, 5, 30 ], - [ -20, 6, -40 ] -] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/general-functions/README.md b/api-reference copy/general-functions/README.md deleted file mode 100644 index 07815b0..0000000 --- a/api-reference copy/general-functions/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: Top level functions that can be called from the Danfo namespace ---- - -# General Functions - -### Data manipulations - -| | | -| ------------------------------------- | ----------------------------------------------------------------------------------------------- | -| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | -| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | -| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | - -### Data Processing/Normalization - -| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | -| ----------------------------------------- | ---------------------------------------------------------------------- | -| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | -| [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | -| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | - -### Top-level dealing with datetime - -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | -| ------------------------------------ | --------------------------------------- | -| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference copy/general-functions/danfo.concat.md b/api-reference copy/general-functions/danfo.concat.md deleted file mode 100644 index e248f46..0000000 --- a/api-reference copy/general-functions/danfo.concat.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Concatenate DataFrames and Series along an axis ---- - -# danfo.concat - -danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Concatenate two DataFrames along column axis (1)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) -com_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two DataFrames along row axis (0)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two Series along row axis (0)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. diff --git a/api-reference copy/general-functions/danfo.date_range.md b/api-reference copy/general-functions/danfo.date_range.md deleted file mode 100644 index 9c4a337..0000000 --- a/api-reference copy/general-functions/danfo.date_range.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -description: Return a fixed frequency Dates spread between start and end parameters. ---- - -# danfo.date\_range - -danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '2/1/2018, 12:00:00 AM', - '3/1/2018, 12:00:00 AM', - '4/1/2018, 12:00:00 AM', - '5/1/2018, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '1/1/2019, 12:00:00 AM', - '1/1/2020, 12:00:00 AM', - '1/1/2021, 12:00:00 AM', - '1/1/2022, 12:00:00 AM', - '1/1/2023, 12:00:00 AM', - '1/1/2024, 12:00:00 AM', - '1/1/2025, 12:00:00 AM', - '1/1/2026, 12:00:00 AM', - '1/1/2027, 12:00:00 AM', - '1/1/2028, 12:00:00 AM', - '1/1/2029, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference copy/general-functions/danfo.get_dummies.md b/api-reference copy/general-functions/danfo.get_dummies.md deleted file mode 100644 index e53fd81..0000000 --- a/api-reference copy/general-functions/danfo.get_dummies.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -description: Convert categorical variable into dummy/indicator variables. ---- - -# danfo.get\_dummies - -danfo.**get\_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| data | Series or Dataframe | The data to dummify | | -| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] -let sf1 = new dfd.Series(datasf) - -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert all categorical columns in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ fruits_pear │ fruits_mango │ ... │ fruits_bean │ Country_NG │ Country_GH │ Country_RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 1 │ 0 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 0 │ 1 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ 0 │ 0 │ ... │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 0 │ 1 │ ... │ 0 │ 0 │ 0 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ 0 │ 0 │ ... │ 1 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert a specific column in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ Country │ fruits_pear │ fruits_mango │ fruits_pawpaw │ fruits_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ NG │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ NG │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ GH │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ RU │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ RU │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) -{% endhint %} diff --git a/api-reference copy/general-functions/danfo.labelencoder.md b/api-reference copy/general-functions/danfo.labelencoder.md deleted file mode 100644 index b0745a8..0000000 --- a/api-reference copy/general-functions/danfo.labelencoder.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Encode target labels with value between 0 and n_classes-1. ---- - -# danfo.LabelEncoder - -class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. - -## **Examples** - -### **Label Encode values in a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = ["dog","cat","man","dog","cat","man","man","cat"] -let series = new dfd.Series(data) - -let encode = new dfd.LabelEncoder() - -encode.fit(series) -console.log(encode); - -let sf_enc = encode.transform(series.values) -sf_enc.print() - -let new_sf = encode.transform(["dog","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'dog', 'cat', 'man' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╟───┼──────────────────────╢ -║ 5 │ 2 ║ -╟───┼──────────────────────╢ -║ 6 │ 2 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with -1** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.LabelEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference copy/general-functions/danfo.merge.md b/api-reference copy/general-functions/danfo.merge.md deleted file mode 100644 index 0c4b760..0000000 --- a/api-reference copy/general-functions/danfo.merge.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -description: >- - Merge DataFrame or named Series objects with a database-style join.The join is - done on columns or indexes. ---- - -# danfo.merge - -danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. - -danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. - -For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user\_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. - -### **Merging by a single key found in both axis** - -By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - //first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on column 'Key1' - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### **Inner Join/Merge by multiple keys found in both axis** - -Merging by two keys takes into consideration the keys appearing in both`left` and `right DataFrame.` - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", 'Key2'], how: "inner"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on two keys - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent - -### Outer join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1"], how: "outer"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//First DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//After outer join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Left join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "left"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - After left join -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ NaN │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Right join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "right"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after right join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ NaN │ NaN │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. -{% endhint %} diff --git a/api-reference copy/general-functions/danfo.minmaxscaler.md b/api-reference copy/general-functions/danfo.minmaxscaler.md deleted file mode 100644 index d58af8b..0000000 --- a/api-reference copy/general-functions/danfo.minmaxscaler.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -description: Transform features by scaling each feature to a range of max and min values. ---- - -# danfo.MinMaxScaler - -class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. - -This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). - -The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize DataFrame Object using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.19191919267... │ 0.02902902849... │ 0.00950475223... │ 0.00333333341... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize Series Object Using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -let sf = df.iloc({columns: ["0"]}) - -scaler.fit(sf) - -let df_enc = scaler.transform(sf) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - Shape: (3,1) - -╔═══╤═══════════════════╗ -║ │ 0 ║ -╟───┼───────────────────╢ -║ 0 │ 1 ║ -╟───┼───────────────────╢ -║ 1 │ 0.19191919267... ║ -╟───┼───────────────────╢ -║ 2 │ 0 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference copy/general-functions/danfo.onehotencoder.md b/api-reference copy/general-functions/danfo.onehotencoder.md deleted file mode 100644 index 81c913d..0000000 --- a/api-reference copy/general-functions/danfo.onehotencoder.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Encode categorical features as a one-hot numeric array. ---- - -# danfo.OneHotEncoder - -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] - -danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","bean"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with 0s all through** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","woman", "cup"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference copy/general-functions/danfo.standardscaler.md b/api-reference copy/general-functions/danfo.standardscaler.md deleted file mode 100644 index 89ce861..0000000 --- a/api-reference copy/general-functions/danfo.standardscaler.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: Standardize features by removing the mean and scaling to unit variance. ---- - -# danfo.StandardScaler - -class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: - -> z = (x - u) / s - -where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. - -The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize Series Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.StandardScaler() - -let sf = new dfd.Series([100,1000,2000, 3000]) -sf.print() - -scaler.fit(sf) - -let sf_enc = scaler.transform(sf) -sf_enc.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 100 ║ -╟───┼──────────────────────╢ -║ 1 │ 1000 ║ -╟───┼──────────────────────╢ -║ 2 │ 2000 ║ -╟───┼──────────────────────╢ -║ 3 │ 3000 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1.1375757455825806 ║ -╟───┼──────────────────────╢ -║ 1 │ -0.4191068708896637 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.37919193506240845 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.1774907112121582 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize DataFrame Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.StandardScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 89, 12], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference copy/general-functions/danfo.to_datetime.md b/api-reference copy/general-functions/danfo.to_datetime.md deleted file mode 100644 index 7012100..0000000 --- a/api-reference copy/general-functions/danfo.to_datetime.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -description: Converts an array of Date time string to Date object. ---- - -# danfo.toDateTime - -danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | -| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -Converts a **Series** of Date strings to Date time and get time properties - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) -let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime(data) - -dt.month().print() -dt.month_name().print() -dt.weekdays().print() -dt.day().print() -dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - -//Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 - -//string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec - -//string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - -//Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference copy/groupby.md b/api-reference copy/groupby.md deleted file mode 100644 index 1db2e52..0000000 --- a/api-reference copy/groupby.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -description: >- - GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby(), - danfo.Series.groupby() ---- - -# Groupby - -### Indexing, iteration - -| [`GroupBy.__iter__`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.__iter__.html#pandas.core.groupby.GroupBy.__iter__)\(\) | Groupby iterator. | -| :--- | :--- | -| [`GroupBy.groups`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups) | Dict {group name -> group labels}. | -| [`GroupBy.indices`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.indices.html#pandas.core.groupby.GroupBy.indices) | Dict {group name -> group indices}. | -| [`GroupBy.get_group`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.get_group.html#pandas.core.groupby.GroupBy.get_group)\(name\[, obj\]\) | Construct DataFrame from group with provided name. | - -| [`Grouper`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Grouper.html#pandas.Grouper)\(\*args, \*\*kwargs\) | A Grouper allows the user to specify a groupby instruction for an object. | -| :--- | :--- | - - -### Function application - -| [`GroupBy.apply`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.apply.html#pandas.core.groupby.GroupBy.apply)\(func, \*args, \*\*kwargs\) | Apply function func group-wise and combine the results together. | -| :--- | :--- | -| [`GroupBy.agg`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.agg.html#pandas.core.groupby.GroupBy.agg)\(func, \*args, \*\*kwargs\) | | -| [`SeriesGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.aggregate.html#pandas.core.groupby.SeriesGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`DataFrameGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html#pandas.core.groupby.DataFrameGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`SeriesGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.transform.html#pandas.core.groupby.SeriesGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed Series on each group and return a Series having the same indexes as the original object filled with the transformed values | -| [`DataFrameGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.transform.html#pandas.core.groupby.DataFrameGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed DataFrame on each group and return a DataFrame having the same indexes as the original object filled with the transformed values | -| [`GroupBy.pipe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pipe.html#pandas.core.groupby.GroupBy.pipe)\(func, \*args, \*\*kwargs\) | Apply a function func with arguments to this GroupBy object and return the function’s result. | - -### Computations / descriptive stats - -| [`GroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.all.html#pandas.core.groupby.GroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`GroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.any.html#pandas.core.groupby.GroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`GroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.bfill.html#pandas.core.groupby.GroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.backfill.html#pandas.core.groupby.GroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.count.html#pandas.core.groupby.GroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`GroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumcount.html#pandas.core.groupby.GroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`GroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummax.html#pandas.core.groupby.GroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`GroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummin.html#pandas.core.groupby.GroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`GroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumprod.html#pandas.core.groupby.GroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`GroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumsum.html#pandas.core.groupby.GroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`GroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ffill.html#pandas.core.groupby.GroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.first`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html#pandas.core.groupby.GroupBy.first)\(\[numeric\_only, min\_count\]\) | Compute first of group values. | -| [`GroupBy.head`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.head.html#pandas.core.groupby.GroupBy.head)\(\[n\]\) | Return first n rows of each group. | -| [`GroupBy.last`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html#pandas.core.groupby.GroupBy.last)\(\[numeric\_only, min\_count\]\) | Compute last of group values. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max)\(\[numeric\_only, min\_count\]\) | Compute max of group values. | -| [`GroupBy.mean`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.mean.html#pandas.core.groupby.GroupBy.mean)\(\[numeric\_only\]\) | Compute mean of groups, excluding missing values. | -| [`GroupBy.median`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.median.html#pandas.core.groupby.GroupBy.median)\(\[numeric\_only\]\) | Compute median of groups, excluding missing values. | -| [`GroupBy.min`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.min.html#pandas.core.groupby.GroupBy.min)\(\[numeric\_only, min\_count\]\) | Compute min of group values. | -| [`GroupBy.ngroup`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ngroup.html#pandas.core.groupby.GroupBy.ngroup)\(\[ascending\]\) | Number each group from 0 to the number of groups - 1. | -| [`GroupBy.nth`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.nth.html#pandas.core.groupby.GroupBy.nth)\(n\[, dropna\]\) | Take the nth row from each group if n is an int, or a subset of rows if n is a list of ints. | -| [`GroupBy.ohlc`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ohlc.html#pandas.core.groupby.GroupBy.ohlc)\(\) | Compute open, high, low and close values of a group, excluding missing values. | -| [`GroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pad.html#pandas.core.groupby.GroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.prod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.prod.html#pandas.core.groupby.GroupBy.prod)\(\[numeric\_only, min\_count\]\) | Compute prod of group values. | -| [`GroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html#pandas.core.groupby.GroupBy.rank)\(\[method, ascending, na\_option, …\]\) | Provide the rank of values within each group. | -| [`GroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pct_change.html#pandas.core.groupby.GroupBy.pct_change)\(\[periods, fill\_method, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`GroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.size.html#pandas.core.groupby.GroupBy.size)\(\) | Compute group sizes. | -| [`GroupBy.sem`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sem.html#pandas.core.groupby.GroupBy.sem)\(\[ddof\]\) | Compute standard error of the mean of groups, excluding missing values. | -| [`GroupBy.std`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.std.html#pandas.core.groupby.GroupBy.std)\(\[ddof\]\) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum)\(\[numeric\_only, min\_count\]\) | Compute sum of group values. | -| [`GroupBy.var`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.var.html#pandas.core.groupby.GroupBy.var)\(\[ddof\]\) | Compute variance of groups, excluding missing values. | -| [`GroupBy.tail`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.tail.html#pandas.core.groupby.GroupBy.tail)\(\[n\]\) | Return last n rows of each group. | - -The following methods are available in both `SeriesGroupBy` and `DataFrameGroupBy` objects, but may differ slightly, usually in that the `DataFrameGroupBy` version usually permits the specification of an axis argument, and often an argument indicating whether to restrict application to columns of a specific data type. - -| [`DataFrameGroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.all.html#pandas.core.groupby.DataFrameGroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`DataFrameGroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.any.html#pandas.core.groupby.DataFrameGroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`DataFrameGroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.backfill.html#pandas.core.groupby.DataFrameGroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.bfill.html#pandas.core.groupby.DataFrameGroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.corr`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corr.html#pandas.core.groupby.DataFrameGroupBy.corr) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrameGroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.count.html#pandas.core.groupby.DataFrameGroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`DataFrameGroupBy.cov`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cov.html#pandas.core.groupby.DataFrameGroupBy.cov) | Compute pairwise covariance of columns, excluding NA/null values. | -| [`DataFrameGroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumcount.html#pandas.core.groupby.DataFrameGroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`DataFrameGroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummax.html#pandas.core.groupby.DataFrameGroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`DataFrameGroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummin.html#pandas.core.groupby.DataFrameGroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`DataFrameGroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumprod.html#pandas.core.groupby.DataFrameGroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`DataFrameGroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumsum.html#pandas.core.groupby.DataFrameGroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`DataFrameGroupBy.describe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.describe.html#pandas.core.groupby.DataFrameGroupBy.describe)\(\*\*kwargs\) | Generate descriptive statistics. | -| [`DataFrameGroupBy.diff`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.diff.html#pandas.core.groupby.DataFrameGroupBy.diff) | First discrete difference of element. | -| [`DataFrameGroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.ffill.html#pandas.core.groupby.DataFrameGroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.fillna`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.fillna.html#pandas.core.groupby.DataFrameGroupBy.fillna) | Fill NA/NaN values using the specified method. | -| [`DataFrameGroupBy.filter`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.filter.html#pandas.core.groupby.DataFrameGroupBy.filter)\(func\[, dropna\]\) | Return a copy of a DataFrame excluding filtered elements. | -| [`DataFrameGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.hist.html#pandas.core.groupby.DataFrameGroupBy.hist) | Make a histogram of the DataFrame’s. | -| [`DataFrameGroupBy.idxmax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmax.html#pandas.core.groupby.DataFrameGroupBy.idxmax) | Return index of first occurrence of maximum over requested axis. | -| [`DataFrameGroupBy.idxmin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmin.html#pandas.core.groupby.DataFrameGroupBy.idxmin) | Return index of first occurrence of minimum over requested axis. | -| [`DataFrameGroupBy.mad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.mad.html#pandas.core.groupby.DataFrameGroupBy.mad) | Return the mean absolute deviation of the values for the requested axis. | -| [`DataFrameGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.nunique.html#pandas.core.groupby.DataFrameGroupBy.nunique)\(\[dropna\]\) | Return DataFrame with counts of unique elements in each position. | -| [`DataFrameGroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pad.html#pandas.core.groupby.DataFrameGroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pct_change.html#pandas.core.groupby.DataFrameGroupBy.pct_change)\(\[periods, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`DataFrameGroupBy.plot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.plot.html#pandas.core.groupby.DataFrameGroupBy.plot) | Class implementing the .plot attribute for groupby objects. | -| [`DataFrameGroupBy.quantile`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.quantile.html#pandas.core.groupby.DataFrameGroupBy.quantile)\(\[q, interpolation\]\) | Return group values at the given quantile, a la numpy.percentile. | -| [`DataFrameGroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.rank.html#pandas.core.groupby.DataFrameGroupBy.rank)\(\[method, ascending, …\]\) | Provide the rank of values within each group. | -| [`DataFrameGroupBy.resample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.resample.html#pandas.core.groupby.DataFrameGroupBy.resample)\(rule, \*args, \*\*kwargs\) | Provide resampling when using a TimeGrouper. | -| [`DataFrameGroupBy.sample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html#pandas.core.groupby.DataFrameGroupBy.sample)\(\[n, frac, replace, …\]\) | Return a random sample of items from each group. | -| [`DataFrameGroupBy.shift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.shift.html#pandas.core.groupby.DataFrameGroupBy.shift)\(\[periods, freq, …\]\) | Shift each group by periods observations. | -| [`DataFrameGroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.size.html#pandas.core.groupby.DataFrameGroupBy.size)\(\) | Compute group sizes. | -| [`DataFrameGroupBy.skew`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.skew.html#pandas.core.groupby.DataFrameGroupBy.skew) | Return unbiased skew over requested axis. | -| [`DataFrameGroupBy.take`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.take.html#pandas.core.groupby.DataFrameGroupBy.take) | Return the elements in the given _positional_ indices along an axis. | -| [`DataFrameGroupBy.tshift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.tshift.html#pandas.core.groupby.DataFrameGroupBy.tshift) | \(DEPRECATED\) Shift the time index, using the index’s frequency if available. | - -The following methods are available only for `SeriesGroupBy` objects. - -| [`SeriesGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.hist.html#pandas.core.groupby.SeriesGroupBy.hist) | Draw histogram of the input series using matplotlib. | -| :--- | :--- | -| [`SeriesGroupBy.nlargest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nlargest.html#pandas.core.groupby.SeriesGroupBy.nlargest) | Return the largest n elements. | -| [`SeriesGroupBy.nsmallest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nsmallest.html#pandas.core.groupby.SeriesGroupBy.nsmallest) | Return the smallest n elements. | -| [`SeriesGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nunique.html#pandas.core.groupby.SeriesGroupBy.nunique)\(\[dropna\]\) | Return number of unique elements in the group. | -| [`SeriesGroupBy.unique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.unique.html#pandas.core.groupby.SeriesGroupBy.unique) | Return unique values of Series object. | -| [`SeriesGroupBy.value_counts`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.value_counts.html#pandas.core.groupby.SeriesGroupBy.value_counts)\(\[normalize, …\]\) | | -| [`SeriesGroupBy.is_monotonic_increasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing) | Alias for is\_monotonic. | -| [`SeriesGroupBy.is_monotonic_decreasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing) | Return boolean if values in the object are monotonic\_decreasing. | - -The following methods are available only for `DataFrameGroupBy` objects. - -| [`DataFrameGroupBy.corrwith`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corrwith.html#pandas.core.groupby.DataFrameGroupBy.corrwith) | Compute pairwise correlation. | -| :--- | :--- | -| [`DataFrameGroupBy.boxplot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.boxplot.html#pandas.core.groupby.DataFrameGroupBy.boxplot)\(\[subplots, column, …\]\) | Make box plots from DataFrameGroupBy data. | - diff --git a/api-reference copy/groupby/README.md b/api-reference copy/groupby/README.md deleted file mode 100644 index 9a1db65..0000000 --- a/api-reference copy/groupby/README.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: 'GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby()' ---- - -# Groupby - -### Indexing, iteration - -| | | -| :--- | :--- | -| [`GroupBy.get_group`](groupby.get_groups.md) | Construct DataFrame from group with provided name. | - -### Function application - -| | | -| :--- | :--- | -| [`GroupBy.agg`](groupby.agg.md) | Aggregate using one or more operations over the specified axis. | - -### Computations / descriptive stats - -| | | -| :--- | :--- | -| [`GroupBy.count`](groupby.count.md) | Compute count of group, excluding missing values. | -| [`GroupBy.cummax`](groupby.cummax.md) | Cumulative max for each group. | -| [`GroupBy.cummin`](groupby.cummin.md) | Cumulative min for each group. | -| [`GroupBy.cumprod`](groupby.cumprod.md) | Cumulative product for each group. | -| [`GroupBy.cumsum`](groupby.cumsum.md) | Cumulative sum for each group. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max) | Compute max of group values. | -| [`GroupBy.mean`](groupby.mean.md) | Compute mean of groups, excluding missing values. | -| [`GroupBy.min`](groupby.min.md) | Compute min of group values. | -| [`GroupBy.std`](groupby.std.md) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum) | Compute sum of group values. | -| [`GroupBy.var`](groupby.var.md) | Compute variance of groups, excluding missing values. | - diff --git a/api-reference copy/groupby/groupby.agg.md b/api-reference copy/groupby/groupby.agg.md deleted file mode 100644 index fae8802..0000000 --- a/api-reference copy/groupby/groupby.agg.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -description: Obtain data aggregate per groups for each column ---- - -# Groupby.agg - -> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | -| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | - -**Return:** DataFrame - -**Examples** - -Using mean and sum aggregate - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Mean and Sum aggregate on dataframe groupby two column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference copy/groupby/groupby.apply.md b/api-reference copy/groupby/groupby.apply.md deleted file mode 100644 index 2150a21..0000000 --- a/api-reference copy/groupby/groupby.apply.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -description: Apply custom aggregate function to grouped data ---- - -# Groupby.apply - -danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function \| function to be applied to grouped data | Undefined | | - -**Returns:** - - ****return **DataFrame** - -## **Examples** - -Using apply to create a custom function that subtract the minimum value of each grouped data from each of its values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - 'A': ['foo', 'bar', 'foo', 'bar', - - 'foo', 'bar', 'foo', 'foo'], - - 'B': ['one', 'one', 'two', 'three', - - 'two', 'two', 'one', 'three'], - - 'C': [1, 3, 2, 4, 5, 2, 6, 7], - - 'D': [3, 2, 4, 1, 5, 6, 7, 8] - }; -let df = new dfd.DataFrame(data); -let group_df = df.groupby(["A", "B"]); - -const subMin = (x) => { - return x.sub(x.min()); -}; - -group_df.apply(subMin).print(); - -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_apply │ D_apply ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 5 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 3 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -\*\*\*\* diff --git a/api-reference copy/groupby/groupby.col.md b/api-reference copy/groupby/groupby.col.md deleted file mode 100644 index 02e7cdd..0000000 --- a/api-reference copy/groupby/groupby.col.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: Obtain the column(s) per groups ---- - -# Groupby.col - -> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| col\_names | Array | List of column | | - -Returns: Groupby Data structure - -Note: This is similar to pandas `df.groupby(["column"])["col_names"]` - -**Examples** - -Obtain a column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]) - -//for more coumns -grp.col(["C","D"]) -``` -{% endtab %} -{% endtabs %} - -Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. - -```text -//it returns the groupby data structure -GroupBy { - key_col: [ 'A' ], - col_dict: { - foo: [ [Array], [Array], [Array], [Array], [Array] ], - bar: [ [Array], [Array], [Array] ] - }, - data: [ - [ 'foo', 'one', 1, 3 ], - [ 'bar', 'one', 3, 2 ], - [ 'foo', 'two', 2, 4 ], - [ 'bar', 'three', 4, 1 ], - [ 'foo', 'two', 5, 5 ], - [ 'bar', 'two', 2, 6 ], - [ 'foo', 'one', 6, 7 ], - [ 'foo', 'three', 7, 8 ] - ], - column_name: [ 'A', 'B', 'C', 'D' ], - data_tensors: { - foo: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - }, - bar: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - } - }, - group_col_name: [ 'C' ], - group_col: { foo: [ [Series] ], bar: [ [Series] ] } -} -``` - - - diff --git a/api-reference copy/groupby/groupby.count.md b/api-reference copy/groupby/groupby.count.md deleted file mode 100644 index 36733be..0000000 --- a/api-reference copy/groupby/groupby.count.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Count the occurrence of values in columns per groups ---- - -# Groupby.count - -> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).count().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.cummax.md b/api-reference copy/groupby/groupby.cummax.md deleted file mode 100644 index 8231a61..0000000 --- a/api-reference copy/groupby/groupby.cummax.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative max per groups for each column ---- - -# Groupby.cummax - -> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative max of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 4 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 4 │ 6 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 4 │ 6 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference copy/groupby/groupby.cummin.md b/api-reference copy/groupby/groupby.cummin.md deleted file mode 100644 index 7fd9ed6..0000000 --- a/api-reference copy/groupby/groupby.cummin.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative minimum per groups for each column ---- - -# Groupby.cummin - -> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative min of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 2 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 2 │ 1 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference copy/groupby/groupby.cumprod.md b/api-reference copy/groupby/groupby.cumprod.md deleted file mode 100644 index af46123..0000000 --- a/api-reference copy/groupby/groupby.cumprod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cumulative product per group for each column ---- - -# Groupby.cumprod - -> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative product of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 │ 420 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 │ 3360 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 24 │ 12 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 24 │ 12 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 21 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference copy/groupby/groupby.cumsum.md b/api-reference copy/groupby/groupby.cumsum.md deleted file mode 100644 index 3b2b0e6..0000000 --- a/api-reference copy/groupby/groupby.cumsum.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -description: Obtain the cumulative sum per groups for each column ---- - -# Groupby.cumsum - -> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative sum of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 │ 19 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 │ 27 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 9 │ 9 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 9 │ 9 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.get_groups.md b/api-reference copy/groupby/groupby.get_groups.md deleted file mode 100644 index 0cdf912..0000000 --- a/api-reference copy/groupby/groupby.get_groups.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -description: Obtain the data for each element of the groupby column ---- - -# Groupby.get\_groups - -> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] - -| Parameters | Type | Description | default | -| :--- | :--- | :--- | :--- | -| key | Array | element of the groupby column | | - -**Returns**: DataFrame - -**Example** - -Group the dataframe by column A and obtain the group belonging to the values in column A - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) - -grp.get_groups(["foo"]).print() - -grp.get_groups(["bar"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get groups for key "foo" - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get groups for key "bar" - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ three │ 4 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) - -grp.get_groups(["foo","one"]).print() - -grp.get_groups(["bar","one"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get_groups(["foo","one"] - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get_groups(["bar","one"]) - - - Shape: (1,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference copy/groupby/groupby.max.md b/api-reference copy/groupby/groupby.max.md deleted file mode 100644 index 43470f6..0000000 --- a/api-reference copy/groupby/groupby.max.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -description: Obtain the maximum value of columns per groups ---- - -# Groupby.max - -> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] - -**Parameters:** None - -**Returns**: DataFrame - -**Example** - -Obtain the maximum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference copy/groupby/groupby.mean.md b/api-reference copy/groupby/groupby.mean.md deleted file mode 100644 index add6958..0000000 --- a/api-reference copy/groupby/groupby.mean.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -description: Obtain the mean per groups for each column(s) ---- - -# Groupby.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the mean of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 5.40000009536... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.min.md b/api-reference copy/groupby/groupby.min.md deleted file mode 100644 index 0151e64..0000000 --- a/api-reference copy/groupby/groupby.min.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -description: Obtain the minimum value per groups for a coumn(s) ---- - -# Groupby.min - -> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the minimum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the minimum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.std.md b/api-reference copy/groupby/groupby.std.md deleted file mode 100644 index c792a8e..0000000 --- a/api-reference copy/groupby/groupby.std.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the standard deviation per groups for specified columns ---- - -# Groupby.std - -> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the standard deviation of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... │ 2.07364413533... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 2.64575131106... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).std().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... │ 2.82842712474... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... │ 0.70710678118... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.sum.md b/api-reference copy/groupby/groupby.sum.md deleted file mode 100644 index f6f2900..0000000 --- a/api-reference copy/groupby/groupby.sum.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -description: Obtain the sum per groups for columns ---- - -# Groupby.sum - -> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the sum of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/groupby/groupby.var.md b/api-reference copy/groupby/groupby.var.md deleted file mode 100644 index 373109f..0000000 --- a/api-reference copy/groupby/groupby.var.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the variance per groups for a specified column ---- - -# Groupby.var - -> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 │ 4.3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).var().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 │ 0.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference copy/input-output/README.md b/api-reference copy/input-output/README.md deleted file mode 100644 index e86d5de..0000000 --- a/api-reference copy/input-output/README.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Functions for reading tabular/structured data into DataFrame/Series Objects ---- - -# Input/Output - -## CSV - -| \`\` | | -| ----------------------------------- | -------------------------------------------------------- | -| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | -| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | -| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | - -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference copy/input-output/danfo.read_csv.md b/api-reference copy/input-output/danfo.read_csv.md deleted file mode 100644 index a291533..0000000 --- a/api-reference copy/input-output/danfo.read_csv.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -description: >- - Reads a comma-separated values (CSV) file into DataFrame. Also supports the - reading of CSV files in chunks. ---- - -# danfo.read\_csv - -> danfo.**read\_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] - -| | | | | -| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | -| **configs**: | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

dynamicTyping: true,

header: true

}

| - -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. - -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("./user_names.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading files from a URL** - -By specifying a valid URL, you can load CSV files from any location into Danfo\*\*'\*\*s data structure: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/input-output/danfo.read_excel.md b/api-reference copy/input-output/danfo.read_excel.md deleted file mode 100644 index 459aa30..0000000 --- a/api-reference copy/input-output/danfo.read_excel.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Reads an excel file into DataFrame. ---- - -# danfo.read_excel - -> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] - -| Parameters | Type | Description | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| source | string | **source** : string, URL or local file path to retreive Excel file. | -| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| - -> **Returns:** -> -> ** **return** **{**Promise**} DataFrame structure of parsed Excel data - -### Example - -The **read_excel** method can read excel files saved on a local disk, or over the internet. - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") -const path = require("path") - -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") - -async function load_process_data() { - let df = await dfd.read_excel(local_xcel) - df.head().print() -} - -load_process_data() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/input-output/danfo.read_json.md b/api-reference copy/input-output/danfo.read_json.md deleted file mode 100644 index 3c17457..0000000 --- a/api-reference copy/input-output/danfo.read_json.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -description: Reads a JSON file into DataFrame. ---- - -# danfo.read\_json - -> danfo.**read\_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] - -| | | | | -| -------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**source**_ | Input file object, string file\*\* \*\*path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | -| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| - -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. - -### **Reading JSON files from local disk** - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/input-output/danfo.to_csv.md b/api-reference copy/input-output/danfo.to_csv.md deleted file mode 100644 index c3403cf..0000000 --- a/api-reference copy/input-output/danfo.to_csv.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -description: Writes a DataFrame or Series to CSV format. ---- - -# danfo.to\_csv - -> danfo.**to\_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] - -| | | | | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = dfd.to_csv(df, { download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in Client-side lib - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -const dfd = require("danfojs") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { fileName: "testOut.csv", download: true}); -``` diff --git a/api-reference copy/input-output/danfo.to_excel.md b/api-reference copy/input-output/danfo.to_excel.md deleted file mode 100644 index 1fe1adf..0000000 --- a/api-reference copy/input-output/danfo.to_excel.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# danfo.to_excel - -> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in Client-side lib - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { fileName: "testOut.xlsx"}); -``` diff --git a/api-reference copy/input-output/danfo.to_json.md b/api-reference copy/input-output/danfo.to_json.md deleted file mode 100644 index baac615..0000000 --- a/api-reference copy/input-output/danfo.to_json.md +++ /dev/null @@ -1,124 +0,0 @@ -# danfo.to\_json - -> danfo.**to\_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| | | | | -| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = dfd.to_json(df, { download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = dfd.to_json(df, { - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { fileName: "test_out.json" }); -``` diff --git a/api-reference copy/input-output/read.md b/api-reference copy/input-output/read.md deleted file mode 100644 index c38778e..0000000 --- a/api-reference copy/input-output/read.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -description: >- - The generic read function loads a tabular data using the Frictionless - specification. ---- - -# read - -> danfo.**read**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] - - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - stringA path to the file/resources. It can be a local file, a URL to tabular - data (CSV, EXCEL) or Datahub.io Data Resource.
configs - object -

-

Configuration options. Supported params are:

-

data_num (Defaults => 0): The specific dataset to load, when - reading data from a datapackage.json,

-

header (Defaults => true): Whether the dataset contains a header - or not.

-

sheet (Defaults => 0): Number of the excel sheet which u want - to load.

-

}

-
- -**Returns:** - - ****_**Promise**_. Resolves to DataFrame - -The **read** function uses [frictionless.js](https://github.com/frictionlessdata/frictionless-js) underhood.[`frictionless.js`](https://github.com/frictionlessdata/frictionless-js) is a lightweight, standardized "stream-plus-metadata" interface for accessing files and datasets, especially tabular ones \(CSV, Excel\). It follows the [Frictionless spec](https://frictionlessdata.io/specs/) - -> ### **Note**: The `read` method is only available in danfojs-node at the moment. - -### Read a CSV file - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("file.csv") - let sample = await df.sample(10) - sample.print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### **Loading Files from URL** - -By specifying a valid URL, you can load CSV/EXCEL file: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") - df.head().print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### Loading Data from a Data Package Descriptor - -You can load data from a frictionless data package [descriptor](https://specs.frictionlessdata.io/data-package/#descriptor). A data package descriptor is a central file in a Data Package. It is a JSON file that provides: - -* General metadata such as the package’s title, license, publisher etc -* A list of the data “resources” that make up the package including their location on disk or online and other relevant information \(including, possibly, schema information about these data resources in a structured form\) - -For instance, in the example below, we load the first resource in the [Natural Gas dataset](https://datahub.io/core/natural-gas) from datahub.io. - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - const package_url = - "https://datahub.io/core/natural-gas/datapackage.json"; - - const df = await dfd.read(package_url, { data_num: 1 }); - df.head().print(); - -load_data() -``` -{% endtab %} -{% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Date │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1997-01-07 │ 3.81999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1997-01-08 │ 3.79999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 1997-01-09 │ 3.60999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 1997-01-10 │ 3.91999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ 1997-01-13 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference copy/plotting/README.md b/api-reference copy/plotting/README.md deleted file mode 100644 index 93161e3..0000000 --- a/api-reference copy/plotting/README.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: >- - DataFrame and Series have inbuilt support for plotting using Plotly's backend. - All customization can be done using Plotly's parameter passed to the config - object. ---- - -# Plotting - -* [Line Charts](line-charts.md) -* [Bar Charts](bar-charts.md) -* [Scatter Plots](scatter-plots.md) -* [Histograms](histograms.md) -* [Pie Charts](pie-charts.md) -* [Tables](tables.md) -* [Box Plots](box-plots.md) -* [Violin Plots](violin-plots.md) -* [Timeseries Plots](timeseries-plots.md) - diff --git a/api-reference copy/plotting/bar-charts.md b/api-reference copy/plotting/bar-charts.md deleted file mode 100644 index 6606bdc..0000000 --- a/api-reference copy/plotting/bar-charts.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Makes a vertical bar plot. ---- - -# Bar Charts - -A bar plot presents categorical data with rectangular bars with lengths proportional to the values that they represent. - -## Examples - -The **bar** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. - -### Bar plot on Series - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (6).png>) - -### Bar plot on DataFrame - -```markup - - - - - - - - - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (7).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/plotting/box-plots.md b/api-reference copy/plotting/box-plots.md deleted file mode 100644 index 2adb60a..0000000 --- a/api-reference copy/plotting/box-plots.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -description: Make a box plot from DataFrame columns. ---- - -# Box Plots - -Make a box-and-whisker plot from DataFrame columns, optionally grouped by some other columns. A box plot is a method for graphically depicting groups of numerical data through their quartiles. - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (23).png>) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (24).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/plotting/configuring-your-plots.md b/api-reference copy/plotting/configuring-your-plots.md deleted file mode 100644 index 4cedbb2..0000000 --- a/api-reference copy/plotting/configuring-your-plots.md +++ /dev/null @@ -1,68 +0,0 @@ -# Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. - -For example in the following code, we show how to set some basic configuration as well as layout for a line plot. - -```markup - - - - - - - - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (32).png>) diff --git a/api-reference copy/plotting/histograms.md b/api-reference copy/plotting/histograms.md deleted file mode 100644 index adabd84..0000000 --- a/api-reference copy/plotting/histograms.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -description: Draw one histogram of the DataFrame’s columns, or single histogram for Series ---- - -# Histograms - -A histogram is a representation of the distribution of data. This function groups the values of all given Series in the DataFrame into bins - -## Examples - -### Histogram of a Column in a DataFrame - -In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (10).png>) - -### Customized Histogram plots on DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (20).png>) - -### Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: - -```javascript -var layout = { - title: 'A sample plot', - xaxis: { - title: 'X', - }, - yaxis: { - title: 'Y', - } -} - -df.plot("div_tag").histogram({layout: layout}) -``` - -{% hint style="info" %} -For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. -{% endhint %} diff --git a/api-reference copy/plotting/line-charts.md b/api-reference copy/plotting/line-charts.md deleted file mode 100644 index 79fe4d3..0000000 --- a/api-reference copy/plotting/line-charts.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -description: >- - Plot Series or DataFrame as lines. This function is useful to plot lines using - DataFrame’s values as coordinates. ---- - -# Line Charts - -## Examples - -### Basic Line plot on Series - -The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (4).png>) - -### Line plots on DataFrame - -The example below shows the plot of column values against a common x-axis (index) - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (2).png>) - -The example below shows how to plot two columns in a DataFrame against each other. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (3).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/plotting/pie-charts.md b/api-reference copy/plotting/pie-charts.md deleted file mode 100644 index 6dce73d..0000000 --- a/api-reference copy/plotting/pie-charts.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -description: Generate a pie plot. ---- - -# Pie Charts - -A pie plot is a proportional representation of the numerical data in a column - -## Examples - -### Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (12).png>) - -### Multiple Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (21).png>) - -### Configure Position of Pie Charts - -If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (22).png>) - -{% hint style="info" %} -For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. -{% endhint %} diff --git a/api-reference copy/plotting/scatter-plots.md b/api-reference copy/plotting/scatter-plots.md deleted file mode 100644 index 77649d1..0000000 --- a/api-reference copy/plotting/scatter-plots.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -description: Create a scatter plot of columns in a DataFrame ---- - -# Scatter Plots - -The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. - -## Examples - -### Scatter Plots on Columns in a DataFrame - -In the example below, we use the titanic dataset, to show a close to real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot-8- (1) (1).png>) - -### More Examples - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (19).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/plotting/tables.md b/api-reference copy/plotting/tables.md deleted file mode 100644 index c67f0e2..0000000 --- a/api-reference copy/plotting/tables.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Turn DataFrame/Series in D3.js-based tables ---- - -# Tables - -## Examples - -### Create Interactive Tables from DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) - -### Configure the header and cell of a table - -To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference copy/plotting/timeseries-plots.md b/api-reference copy/plotting/timeseries-plots.md deleted file mode 100644 index 7bbb089..0000000 --- a/api-reference copy/plotting/timeseries-plots.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Timeseries plot are based on date index ---- - -# Timeseries Plots - -## Examples - -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot-29- (2) (1).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/plotting/violin-plots.md b/api-reference copy/plotting/violin-plots.md deleted file mode 100644 index a3e6c11..0000000 --- a/api-reference copy/plotting/violin-plots.md +++ /dev/null @@ -1,112 +0,0 @@ -# Violin Plots - -Make a violin plot from DataFrame columns, optionally grouped by some other columns. A violin plot is a method for graphically depicting groups of numerical data through their quartiles. See also [Box Plot](box-plots.md) - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (25).png>) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (26).png>) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (27).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference copy/series/README.md b/api-reference copy/series/README.md deleted file mode 100644 index 421bc63..0000000 --- a/api-reference copy/series/README.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -description: One-dimensional ndarray with axis labels (including time series). ---- - -# Series - -> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ], **index:** \[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] - -### Attributes - -| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | -| --------------------------------- | ------------------------------------------- | - -| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | -| ----------------------------------- | ---------------------------------------------------------------- | -| [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | -| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | -| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | -| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | - -### Conversion - -| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | -| --------------------------------------------------- | ---------------------------------------------- | -| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| | | -| ------------------------------------------------------- | ------------------------------------------------------------------ | -| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | -| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | - -### Binary operator functions - -| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | -| --------------------------------- | --------------------------------------------------------------------------------------- | -| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | -| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | -| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | -| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | -| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | -| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | -| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | -| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | -| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | -| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | -| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | -| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | -| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | - -### Function application & GroupBy - -| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | -| --------------------------------- | ------------------------------------------------------- | -| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | - -### Computations / descriptive stats - -| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | -| ----------------------------------------------------------- | ---------------------------------------------------------------- | -| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | -| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | -| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | -| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | -| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | -| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | -| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | -| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | -| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | -| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | -| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | -| [`Series.unique`](series.unique.md) | Return unique values of Series object. | -| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value\_counts.md) | Return a Series containing counts of unique values. | - -### Reindexing / selection / label manipulation - -| | | -| ------------------------------------------------------ | -------------------------------------------------------- | -| [`Series.drop_duplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------- | ------------------------------------------------ | -| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | -| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | -| [`Series.isna`](series.isna.md) | Detect missing values. | -| [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | - -### Reshaping, sorting - -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| ---------------------------------------------- | ------------------------------------------------------------- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort\_values.md) | Sort by the values. | - -### Accessors - -Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. - -| Data Type | Accessor | -| --------- | -------- | -| Datetime | dt | -| String | str | - -#### Datetimelike properties - -`Series.dt` can be used to access the values of the series as datetime and return several properties. These can be accessed like `Series.dt.`. - -**Datetime methods** - -| | | -| -------------------------------------------------- | ------------------------------------------------------------------ | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | -| [`Series.dt.month_name`](series.dt.month\_name.md) | Return the month names of the DateTimeIndex with specified locale. | - -#### String handling - -`Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. - -| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | -| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | -| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | -| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | -| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | -| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | -| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | -| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | -| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | -| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | -| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | -| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | -| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | -| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | -| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | -| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | -| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | -| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | -| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| ----------------------------------------------------- | ------------------------------------------------------------- | -| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | -| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| ------------------------------------------------------ | ---------------------------------------------------- | -| [`Series.to_csv`](../dataframe/dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`Series.to_json`](../dataframe/dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference copy/series/creating-a-series.md b/api-reference copy/series/creating-a-series.md deleted file mode 100644 index 3c8e4ba..0000000 --- a/api-reference copy/series/creating-a-series.md +++ /dev/null @@ -1,210 +0,0 @@ -# Creating a Series - -new danfo.**Series**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. - -### Creating a Series from an object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```javascript -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series from an array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = ["bval1", "bval2", "bval3", "bval4"] -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series and specifying index and dtypes - -You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. - -> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2, 3, 4, 5]; -let index = ["a", "b", "c", "d", "e"]; -let dtypes = ["int32",] - -let df = new Series(data1, { index, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╚═══╧═══╝ -``` - -### Creating a Series and specifying memory mode - -To use less space on Series creation, you can set the low memory mode as demonstrated below: - -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2.3, 3, 4, 5, "girl"]; - -let df = new Series(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the Series. -{% endhint %} - diff --git a/api-reference copy/series/danfo.series.add.md b/api-reference copy/series/danfo.series.add.md deleted file mode 100644 index 7cd6150..0000000 --- a/api-reference copy/series/danfo.series.add.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: 'Return Addition of series and other, element-wise (binary operator add).' ---- - -# danfo.Series.add - -Return Addition of series and other, element-wise \(binary operator add\). - - **parameter:** {other} Series or Number to add - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 6] -let data2 = [30, 40, 39, 1, 2, 1] -let sf = new Series(data) -let sf2 = new Series(data2) -sf.add(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.apply.md b/api-reference copy/series/danfo.series.apply.md deleted file mode 100644 index d59a99c..0000000 --- a/api-reference copy/series/danfo.series.apply.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -description: invoke a function on Series Value ---- - -# danfo.Series.apply - -> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function | Function \(can be anonymous\) to apply | | - -**Returns:** - - ****return **Series** - -\*\*\*\* - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply1.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_apply2.png) - - - diff --git a/api-reference copy/series/danfo.series.copy.md b/api-reference copy/series/danfo.series.copy.md deleted file mode 100644 index c610c04..0000000 --- a/api-reference copy/series/danfo.series.copy.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.copy - -Make a new copy of Series - - - -**parameter:** - - **return:** {Series} - -**Example** - -```javascript -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf_copy = sf.copy() - - -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf = sf.set_index({ "index": ["a", "b", "c", "d"] }) -sf_copy = sf.copy() -``` - diff --git a/api-reference copy/series/danfo.series.count.md b/api-reference copy/series/danfo.series.count.md deleted file mode 100644 index 50a5789..0000000 --- a/api-reference copy/series/danfo.series.count.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.count - -Return number of non-NA/null observations in the Series. - -This is equivalent to the method numpy.sum - - **parameter:** - - **return:** {Number}, sum of values in Series - -**Example** - -```javascript -let data = ["boy", "gitl", "woman", NaN] -let sf = new Series(data) -sf.count() -``` - - - diff --git a/api-reference copy/series/danfo.series.describe.md b/api-reference copy/series/danfo.series.describe.md deleted file mode 100644 index 184dbe9..0000000 --- a/api-reference copy/series/danfo.series.describe.md +++ /dev/null @@ -1,26 +0,0 @@ -# danfo.Series.describe - - - -Generate descriptive statistics. Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding NaN values - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three"] }) - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -df.reset_index() -``` - diff --git a/api-reference copy/series/danfo.series.div.md b/api-reference copy/series/danfo.series.div.md deleted file mode 100644 index ae2731b..0000000 --- a/api-reference copy/series/danfo.series.div.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# danfo.Series.div - -Return division of series and other, element-wise \(binary operator div\). - -Equivalent to series / other - - **parameter:** {other} Series, Number to divide with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.div(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.head.md b/api-reference copy/series/danfo.series.head.md deleted file mode 100644 index 1bc9d5e..0000000 --- a/api-reference copy/series/danfo.series.head.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -description: This function returns the first n rows for the object based on position. ---- - -# danfo.Series.head - - - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let cols = ["A"] -let sf = new Series(data, { columns: cols }) -sf.head() -``` - - - diff --git a/api-reference copy/series/danfo.series.map.md b/api-reference copy/series/danfo.series.map.md deleted file mode 100644 index 9d7cad4..0000000 --- a/api-reference copy/series/danfo.series.map.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: Map the value of a series to it representation ---- - -# danfo.Series.map - -> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] - -| Parameter | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function or Object | callable can either be a function or an object\({}\) | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map) - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map1.png) - diff --git a/api-reference copy/series/danfo.series.max.md b/api-reference copy/series/danfo.series.max.md deleted file mode 100644 index cac4ba1..0000000 --- a/api-reference copy/series/danfo.series.max.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.max - diff --git a/api-reference copy/series/danfo.series.maximum.md b/api-reference copy/series/danfo.series.maximum.md deleted file mode 100644 index 9082120..0000000 --- a/api-reference copy/series/danfo.series.maximum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.maximum - -Return maximum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check maximum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.maximum(sf2) -``` - - - diff --git a/api-reference copy/series/danfo.series.mean.md b/api-reference copy/series/danfo.series.mean.md deleted file mode 100644 index 6ace487..0000000 --- a/api-reference copy/series/danfo.series.mean.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mean - diff --git a/api-reference copy/series/danfo.series.median.md b/api-reference copy/series/danfo.series.median.md deleted file mode 100644 index 077c0ec..0000000 --- a/api-reference copy/series/danfo.series.median.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.median - diff --git a/api-reference copy/series/danfo.series.min.md b/api-reference copy/series/danfo.series.min.md deleted file mode 100644 index 22f3589..0000000 --- a/api-reference copy/series/danfo.series.min.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.min - diff --git a/api-reference copy/series/danfo.series.minimum.md b/api-reference copy/series/danfo.series.minimum.md deleted file mode 100644 index 2a9d9c6..0000000 --- a/api-reference copy/series/danfo.series.minimum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.minimum - - - -Return minimum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check minimum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.minimum(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.mod.md b/api-reference copy/series/danfo.series.mod.md deleted file mode 100644 index 577014d..0000000 --- a/api-reference copy/series/danfo.series.mod.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Modulo of series and other, element-wise (binary operator mod).' ---- - -# danfo.Series.mod - -Return Modulo of series and other, element-wise \(binary operator mod\). - -Equivalent to series % other - - **parameter:** {other} Series, Number - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mod(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.mode.md b/api-reference copy/series/danfo.series.mode.md deleted file mode 100644 index 8d86e6e..0000000 --- a/api-reference copy/series/danfo.series.mode.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mode - diff --git a/api-reference copy/series/danfo.series.mul.md b/api-reference copy/series/danfo.series.mul.md deleted file mode 100644 index 6cdac92..0000000 --- a/api-reference copy/series/danfo.series.mul.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: 'Return Multiplication of series and other, element-wise (binary operator mul).' ---- - -# danfo.Series.mul - -Return Multiplication of series and other, element-wise \(binary operator mul\). - -Equivalent to series \* other, but with support to substitute a fill\_value for missing data in one of the inputs. - - **parameter:** {Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mul(sf2) -``` - - - diff --git a/api-reference copy/series/danfo.series.pow.md b/api-reference copy/series/danfo.series.pow.md deleted file mode 100644 index 291a993..0000000 --- a/api-reference copy/series/danfo.series.pow.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# danfo.Series.pow - -Return Exponential power of series and other, element-wise \(binary operator pow\). - -Equivalent to series \*\* other - - **parameter:** {other} Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.pow(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.reset_index.md b/api-reference copy/series/danfo.series.reset_index.md deleted file mode 100644 index 7a908a9..0000000 --- a/api-reference copy/series/danfo.series.reset_index.md +++ /dev/null @@ -1,31 +0,0 @@ -# danfo.Series.reset\_index - - - -Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. - - - -**parameter:** {kwargs} {inplace: Modify the Series in place \(do not create a new object, drop: Just reset the index, without inserting it as a column in the new DataFrame.} - - **return:** {Series} - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -let df_reset = df_new.reset_index() -df_reset.print() - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -let df_new = df.reset_index() -df_new -``` - diff --git a/api-reference copy/series/danfo.series.round.md b/api-reference copy/series/danfo.series.round.md deleted file mode 100644 index 2bbacbb..0000000 --- a/api-reference copy/series/danfo.series.round.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.round - -Round each value in a Series to the given number of decimals. - - - - **parameter:** {dp} Number, Numbers of Decimal places to round to - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf = new Series(data1) -sf.round(1) -``` - - - diff --git a/api-reference copy/series/danfo.series.sample.md b/api-reference copy/series/danfo.series.sample.md deleted file mode 100644 index fa8f326..0000000 --- a/api-reference copy/series/danfo.series.sample.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# danfo.Series.sample - -Gets \[num\] number of random rows in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.sample(2) -``` - - - diff --git a/api-reference copy/series/danfo.series.set_index.md b/api-reference copy/series/danfo.series.set_index.md deleted file mode 100644 index 5cb3d28..0000000 --- a/api-reference copy/series/danfo.series.set_index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# danfo.Series.set\_index - -> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object {} | The object contains the key **index** and assigned an array value of equal length to the Series. format {"index": \[Array\] } | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series.reset_index.png) - -```javascript -const dfd = require("danfojs") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["H", "L", "M","F","T"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_reset_index2.png) - diff --git a/api-reference copy/series/danfo.series.sort_values.md b/api-reference copy/series/danfo.series.sort_values.md deleted file mode 100644 index 0a0c4e7..0000000 --- a/api-reference copy/series/danfo.series.sort_values.md +++ /dev/null @@ -1,27 +0,0 @@ -# danfo.Series.sort\_values - - - -Sort a Series in ascending or descending order by some criterion. - - - - **parameter:** {kwargs} Object, {ascending \(Bool\): Whether to return sorted values in ascending order or not, inplace \(Bool\): Whether to perform sorting on the original Series or not} - - **return:** {Number} - -**Example** - -```javascript -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values() - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "inplace": true }) - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "ascending": false, "inplace": true }) -``` - diff --git a/api-reference copy/series/danfo.series.std.md b/api-reference copy/series/danfo.series.std.md deleted file mode 100644 index 8f48ef2..0000000 --- a/api-reference copy/series/danfo.series.std.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.std - -Return sample standard deviation over requested axis. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.std() -``` - - - diff --git a/api-reference copy/series/danfo.series.sub.md b/api-reference copy/series/danfo.series.sub.md deleted file mode 100644 index 8867c14..0000000 --- a/api-reference copy/series/danfo.series.sub.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Subtraction of series and other, element-wise (binary operator sub).' ---- - -# danfo.Series.sub - -Returns the subtraction between a series and other, element-wise \(binary operator subtraction\). - -Equivalent to series - other - - **parameter:** {other} Series, Number to subtract - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 39, 1, 2, 1] -let data2 = [1, 2, 3, 4, 5, 6] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.sub(sf2) -``` - diff --git a/api-reference copy/series/danfo.series.sum-1.md b/api-reference copy/series/danfo.series.sum-1.md deleted file mode 100644 index 6ec14cb..0000000 --- a/api-reference copy/series/danfo.series.sum-1.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.sum - -Return the sum of the values for the requested axis. - -This is equivalent to the method numpy.sum. - - **parameter:** - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.sum() -``` - diff --git a/api-reference copy/series/danfo.series.tail.md b/api-reference copy/series/danfo.series.tail.md deleted file mode 100644 index e83307d..0000000 --- a/api-reference copy/series/danfo.series.tail.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# danfo.Series.tail - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.tail() -``` - - - diff --git a/api-reference copy/series/danfo.series.tostring.md b/api-reference copy/series/danfo.series.tostring.md deleted file mode 100644 index 5807850..0000000 --- a/api-reference copy/series/danfo.series.tostring.md +++ /dev/null @@ -1,18 +0,0 @@ -# danfo.Series.toString - - - -Prints the data in a Series as a grid of row and columns - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript - -``` - diff --git a/api-reference copy/series/danfo.series.var.md b/api-reference copy/series/danfo.series.var.md deleted file mode 100644 index 822edc7..0000000 --- a/api-reference copy/series/danfo.series.var.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.var - - - -Return unbiased variance of Series. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.var() -``` - diff --git a/api-reference copy/series/series.abs.md b/api-reference copy/series/series.abs.md deleted file mode 100644 index 843dd5e..0000000 --- a/api-reference copy/series/series.abs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Returns the absolute value in a Series ---- - -# Series.abs - -> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [-10, 45, 56, -25, 23, -20, 10] -let sf = new dfd.Series(data1) - -sf.abs().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.add.md b/api-reference copy/series/series.add.md deleted file mode 100644 index e55b1b8..0000000 --- a/api-reference copy/series/series.add.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Addition of series and other, element-wise (binary operator add). ---- - -# Series.add - -> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.add(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 31 ║ -╟───┼──────────────────────╢ -║ 1 │ 42 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.add(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 5 ║ -╟───┼──────────────────────╢ -║ 3 │ 6 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.and.md b/api-reference copy/series/series.and.md deleted file mode 100644 index 85c22cb..0000000 --- a/api-reference copy/series/series.and.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical AND between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.and - -> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical AND between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.and(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ false ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.append.md b/api-reference copy/series/series.append.md deleted file mode 100644 index 53e8f03..0000000 --- a/api-reference copy/series/series.append.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: Add a new value or values to the end of a Series. ---- - -# Series.append - -danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | -| newValue | Array, Series | Object to append | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | -| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | - -**Returns:** - - **** return **Series** - -**** - -### **Append new Series to the end of a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) - -new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) -new_sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` -{% endtab %} -{% endtabs %} - -### **Append new Series to the end of a Series in-place** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) -let newIndex = ["f5", "f6", "f7"] - -sf1.append(sf2, newIndex, { inplace: true }) -sf1.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` - -### **Append an array to the end of Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sfArr = ["a", "b", "c"] - -new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) -new_sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.apply.md b/api-reference copy/series/series.apply.md deleted file mode 100644 index 7f7050e..0000000 --- a/api-reference copy/series/series.apply.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -description: Invoke a function on each value in a Series. ---- - -# Series.apply - -> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function | Function (can be anonymous) to apply | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** - - **** return **Series** - -**** - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╟───┼──────────────────────╢ -║ 5 │ 12 ║ -╟───┼──────────────────────╢ -║ 6 │ 14 ║ -╟───┼──────────────────────╢ -║ 7 │ 16 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0.6931471805599453 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.0986122886681096 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.3862943611198906 ║ -╟───┼──────────────────────╢ -║ 4 │ 1.6094379124341003 ║ -╟───┼──────────────────────╢ -║ 5 │ 1.791759469228055 ║ -╟───┼──────────────────────╢ -║ 6 │ 1.9459101490553132 ║ -╟───┼──────────────────────╢ -║ 7 │ 2.0794415416798357 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ rice ║ -╟───┼──────────────────────╢ -║ 1 │ beans ║ -╟───┼──────────────────────╢ -║ 2 │ yam ║ -╟───┼──────────────────────╢ -║ 3 │ banana ║ -╟───┼──────────────────────╢ -║ 4 │ wheat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.argmax.md b/api-reference copy/series/series.argmax.md deleted file mode 100644 index d7927d2..0000000 --- a/api-reference copy/series/series.argmax.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the largest value in the series ---- - -# Series.argmax - -> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmax() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -7 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.argmin.md b/api-reference copy/series/series.argmin.md deleted file mode 100644 index dfc661f..0000000 --- a/api-reference copy/series/series.argmin.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the smallest value in the series ---- - -# Series.argmin - -> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmin() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -0 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.argsort.md b/api-reference copy/series/series.argsort.md deleted file mode 100644 index b4608a4..0000000 --- a/api-reference copy/series/series.argsort.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Return the integer indices that would sort the Series values ---- - -# Series.argsort - -> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | -| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| - -**Returns:** Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [10, 45, 20, 10, 23, 20, 30, 11] -let sf = new dfd.Series(data) - -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 7 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 6 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -//sorted in descending order -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 6 ║ -╟───┼───╢ -║ 2 │ 4 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╟───┼───╢ -║ 6 │ 0 ║ -╟───┼───╢ -║ 7 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.astype.md b/api-reference copy/series/series.astype.md deleted file mode 100644 index 15a61ae..0000000 --- a/api-reference copy/series/series.astype.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.astype - diff --git a/api-reference copy/series/series.copy.md b/api-reference copy/series/series.copy.md deleted file mode 100644 index 9bbdb47..0000000 --- a/api-reference copy/series/series.copy.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Makes a deep copy of a Series ---- - -# Series.copy - -> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] - -**parameter:** - -**Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.copy() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21091 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.190901 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.564 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.0212 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.corr.md b/api-reference copy/series/series.corr.md deleted file mode 100644 index ee3263f..0000000 --- a/api-reference copy/series/series.corr.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.corr - diff --git a/api-reference copy/series/series.count.md b/api-reference copy/series/series.count.md deleted file mode 100644 index 832c794..0000000 --- a/api-reference copy/series/series.count.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the total number of values in a series ---- - -# Series.count - -> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.count()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -9 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.cummax.md b/api-reference copy/series/series.cummax.md deleted file mode 100644 index 8aded1a..0000000 --- a/api-reference copy/series/series.cummax.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns cumulative maximum over a series ---- - -# Series.cummax - -> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummax().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 56 ║ -╟───┼──────────────────────╢ -║ 5 │ 56 ║ -╟───┼──────────────────────╢ -║ 6 │ 56 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.cummin.md b/api-reference copy/series/series.cummin.md deleted file mode 100644 index 736cee5..0000000 --- a/api-reference copy/series/series.cummin.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns the cumulative min of a Series ---- - -# Series.cummin - -> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 5, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummin().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ 10 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 5 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.cumprod.md b/api-reference copy/series/series.cumprod.md deleted file mode 100644 index 84ec0e7..0000000 --- a/api-reference copy/series/series.cumprod.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Return the cumulative product of a series ---- - -# Series.cumprod - -> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumprod().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 450 ║ -╟───┼──────────────────────╢ -║ 2 │ 25200 ║ -╟───┼──────────────────────╢ -║ 3 │ 630000 ║ -╟───┼──────────────────────╢ -║ 4 │ 14490000 ║ -╟───┼──────────────────────╢ -║ 5 │ 289800000 ║ -╟───┼──────────────────────╢ -║ 6 │ 2898000000 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.cumsum.md b/api-reference copy/series/series.cumsum.md deleted file mode 100644 index 7b7a19a..0000000 --- a/api-reference copy/series/series.cumsum.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a cumulative sum of a series ---- - -# Series.cumsum - -> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumsum().print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 55 ║ -╟───┼──────────────────────╢ -║ 2 │ 111 ║ -╟───┼──────────────────────╢ -║ 3 │ 136 ║ -╟───┼──────────────────────╢ -║ 4 │ 159 ║ -╟───┼──────────────────────╢ -║ 5 │ 179 ║ -╟───┼──────────────────────╢ -║ 6 │ 189 ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference copy/series/series.describe.md b/api-reference copy/series/series.describe.md deleted file mode 100644 index ce52246..0000000 --- a/api-reference copy/series/series.describe.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -description: >- - Generate descriptive statistics. Descriptive statistics include those that - summarize the central tendency, dispersion and shape of a dataset’s - distribution, excluding NaN values ---- - -# Series.describe - -> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] - -**Parameters:** No parameter - -**return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) -sf.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔══════════╤══════════════════════╗ -║ │ 0 ║ -╟──────────┼──────────────────────╢ -║ count │ 6 ║ -╟──────────┼──────────────────────╢ -║ mean │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ std │ 1.8708286933869707 ║ -╟──────────┼──────────────────────╢ -║ min │ 1 ║ -╟──────────┼──────────────────────╢ -║ median │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ max │ 6 ║ -╟──────────┼──────────────────────╢ -║ variance │ 3.5 ║ -╚══════════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.div.md b/api-reference copy/series/series.div.md deleted file mode 100644 index 656a796..0000000 --- a/api-reference copy/series/series.div.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# Series.div - -> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -divide with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.div(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 20 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### divide with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.div(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.5 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.5 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dot.md b/api-reference copy/series/series.dot.md deleted file mode 100644 index 61a8bc2..0000000 --- a/api-reference copy/series/series.dot.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.dot - diff --git a/api-reference copy/series/series.drop_duplicates.md b/api-reference copy/series/series.drop_duplicates.md deleted file mode 100644 index 08edf09..0000000 --- a/api-reference copy/series/series.drop_duplicates.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Remove duplicate rows ---- - -# Series.drop\_duplicates - -> danfo.Series.**drop\_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | -| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| - -**Returns:** Series - -**Examples** - -### Drop duplicate by keeping the first occurrence of the duplicate value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates() - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop duplicate and keep only the last duplicated value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates({keep:"last"}) - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Remove duplicate value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] -let sf = new dfd.Series(data1) -sf.drop_duplicates({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ A ║ -╟───┼──────────────────────╢ -║ 3 │ B ║ -╟───┼──────────────────────╢ -║ 5 │ C ║ -╟───┼──────────────────────╢ -║ 7 │ D ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dropna.md b/api-reference copy/series/series.dropna.md deleted file mode 100644 index 2fab716..0000000 --- a/api-reference copy/series/series.dropna.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -description: Remove missing values from Series ---- - -# Series.dropna - -> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Drop all nan value and then return New Series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.dropna() - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop nan values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -sf.dropna({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.day.md b/api-reference copy/series/series.dt.day.md deleted file mode 100644 index 6461fa5..0000000 --- a/api-reference copy/series/series.dt.day.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the numerical representation of the week day. ---- - -# Series.dt.day - -> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) -let sf = new dfd.Series(data) - -sf.dt.day().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═══╗ -║ 0 │ 6 ║ -╟───┼───╢ -║ 1 │ 0 ║ -╟───┼───╢ -║ 2 │ 1 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 4 ║ -╟───┼───╢ -║ 6 │ 5 ║ -╟───┼───╢ -║ 7 │ 6 ║ -╟───┼───╢ -║ 8 │ 0 ║ -╟───┼───╢ -║ 9 │ 1 ║ -╚═══╧═══╝ -``` diff --git a/api-reference copy/series/series.dt.hour.md b/api-reference copy/series/series.dt.hour.md deleted file mode 100644 index 16369bb..0000000 --- a/api-reference copy/series/series.dt.hour.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the hours in a time series ---- - -# Series.dt.hour - -> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] - -**Parameters:** None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) -let sf = new dfd.Series(data) -// print series -sf.print() -// print hour series -sf.dt.hours().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 2:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.minute.md b/api-reference copy/series/series.dt.minute.md deleted file mode 100644 index ea8bfee..0000000 --- a/api-reference copy/series/series.dt.minute.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the minutes in a Time Series ---- - -# Series.dt.minutes - -> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] - -**Parameters**: None - -**Returns:** Series (int Elements) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) -let sf = new dfd.Series(data) -//print the series -sf.print() -//print the minutes series -sf.dt.minutes().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:01:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:02:00 AM ║ -╚═══╧══════════════════════╝ - -//print the minutes series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.month.md b/api-reference copy/series/series.dt.month.md deleted file mode 100644 index e21eeda..0000000 --- a/api-reference copy/series/series.dt.month.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: Obtain the month in a date time series ---- - -# Series.dt.month - -> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) -let sf = new dfd.Series(data) - -sf.dt.month().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 0 │ 6 ║ -╟───┼────╢ -║ 1 │ 7 ║ -╟───┼────╢ -║ 2 │ 9 ║ -╟───┼────╢ -║ 3 │ 9 ║ -╟───┼────╢ -║ 4 │ 11 ║ -╟───┼────╢ -║ 5 │ 11 ║ -╚═══╧════╝ -``` diff --git a/api-reference copy/series/series.dt.month_name.md b/api-reference copy/series/series.dt.month_name.md deleted file mode 100644 index 4e83618..0000000 --- a/api-reference copy/series/series.dt.month_name.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: obtain the month name in a Time Series ---- - -# Series.dt.month\_name - -> danfo.Series.dt.month\_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] - -**Parameters**: None - -**Returns:** Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print month names -sf.dt.month_name().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 2/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 3/1/2018, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═════╗ -║ 0 │ Jan ║ -╟───┼─────╢ -║ 1 │ Feb ║ -╟───┼─────╢ -║ 2 │ Mar ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.monthday.md b/api-reference copy/series/series.dt.monthday.md deleted file mode 100644 index b385f17..0000000 --- a/api-reference copy/series/series.dt.monthday.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the day of the month ---- - -# Series.dt.monthday - -> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] - -**Parameters:** None - -**Returns**: Series (Int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print monthdays -sf.dt.monthday().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/2/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/3/2000, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.second.md b/api-reference copy/series/series.dt.second.md deleted file mode 100644 index 43330be..0000000 --- a/api-reference copy/series/series.dt.second.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the seconds in Date series ---- - -# Series.dt.seconds - -> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] - -**Parameters**: None - -**Returns:** Series (Int elements) - -**Example** - -Obtain the seconds of the datetime - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) -let sf = new dfd.Series(data) -//print the series frame -sf.print() - -//print the seconds obtained -sf.dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:00:01 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:00:02 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 0 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.dt.weekdays.md b/api-reference copy/series/series.dt.weekdays.md deleted file mode 100644 index 04dbe18..0000000 --- a/api-reference copy/series/series.dt.weekdays.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -description: Obtain the days of the weeks ---- - -# Series.dt.weekdays - -> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] - -**Parameters**: None - -**Returns:** Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print days of the week -sf.dt.weekdays().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════════════════════════╗ -║ 0 │ 12/31/2016, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 9 │ 1/9/2017, 1:00:00 AM ║ -╚═══╧════════════════════════╝ - -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ -``` diff --git a/api-reference copy/series/series.dt.year.md b/api-reference copy/series/series.dt.year.md deleted file mode 100644 index ed1117f..0000000 --- a/api-reference copy/series/series.dt.year.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Obtain the year in a date time series ---- - -# Series.dt.year - -> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) -let sf = new dfd.Series(data) -sf.print() -sf.dt.year().print() -``` -{% endtab %} -{% endtabs %} - -``` -//print date time series -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2001, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2002, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤══════╗ -║ 0 │ 2000 ║ -╟───┼──────╢ -║ 1 │ 2001 ║ -╟───┼──────╢ -║ 2 │ 2002 ║ -╚═══╧══════╝ -``` diff --git a/api-reference copy/series/series.dtype.md b/api-reference copy/series/series.dtype.md deleted file mode 100644 index 75b4614..0000000 --- a/api-reference copy/series/series.dtype.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dtype of a series ---- - -# Series.dtype - -> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] - -**Parameters**: None - -**Returns:** String - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.dtype) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.eq.md b/api-reference copy/series/series.eq.md deleted file mode 100644 index 43a3ece..0000000 --- a/api-reference copy/series/series.eq.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check all the values in a series is equal to another value ---- - -# Series.eq - -> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Examples** - -Compare all the values in a series to another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.eq(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check it all the values are equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.eq(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.fillna.md b/api-reference copy/series/series.fillna.md deleted file mode 100644 index a1db3a8..0000000 --- a/api-reference copy/series/series.fillna.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Replace all NaN value with specified value ---- - -# Series.fillna - -> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| - -**Examples** - -### Fill nan value and then return new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) - -let sf_rep = sf.fillna({ value: -999}) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill nan value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) -sf.fillna({ value: -999, inplace: true }) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.ge.md b/api-reference copy/series/series.ge.md deleted file mode 100644 index 0fb1aeb..0000000 --- a/api-reference copy/series/series.ge.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the values in a series is greater than or equal a value ---- - -# Series.ge - -> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns:** Series (Boolean element) - -**Example** - -Compare all the value in a Series to the values in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ge(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check if all the value in a Series is greater than or equal a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ge(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.gt.md b/api-reference copy/series/series.gt.md deleted file mode 100644 index 184ca28..0000000 --- a/api-reference copy/series/series.gt.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the value in a series is greater than a value ---- - -# Series.gt - -> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are greater than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.gt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are greater than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.gt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.head.md b/api-reference copy/series/series.head.md deleted file mode 100644 index 2892263..0000000 --- a/api-reference copy/series/series.head.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Obtain the first n rows for the object based on position. ---- - -# Series.head - -> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of first n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.head().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference copy/series/series.iloc.md b/api-reference copy/series/series.iloc.md deleted file mode 100644 index ab7d1f3..0000000 --- a/api-reference copy/series/series.iloc.md +++ /dev/null @@ -1,158 +0,0 @@ -# Series.iloc - -danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `"1:7"` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc([0,5]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["0:5"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 2.2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["5:"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╟───┼──────────────────────╢ -║ 6 │ 2.1 ║ -╟───┼──────────────────────╢ -║ 7 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference copy/series/series.index.md b/api-reference copy/series/series.index.md deleted file mode 100644 index 1cc95da..0000000 --- a/api-reference copy/series/series.index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -description: Obtain the index of a Series ---- - -# Series.index - -> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.index) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 0, 1, 2, 3 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.isna.md b/api-reference copy/series/series.isna.md deleted file mode 100644 index cdf6343..0000000 --- a/api-reference copy/series/series.isna.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Detect Missing values ---- - -# Series.isna - -> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] - -**Parameters**: None - -**Returns**: Series \(Boolean element\) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, undefined, "girl", "Man"] -let sf = new dfd.Series(data1) - -sf.isna().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.le.md b/api-reference copy/series/series.le.md deleted file mode 100644 index 44006e2..0000000 --- a/api-reference copy/series/series.le.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all the values in a series is less than or equal to a value ---- - -# Series.le - -> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns:** Series (Boolean Element) - -**Example** - -Check if all the values in a series is less than or equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.le(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than equal to values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.le(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.loc.md b/api-reference copy/series/series.loc.md deleted file mode 100644 index 13772ab..0000000 --- a/api-reference copy/series/series.loc.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -description: Access a group of rows by label(s) or a boolean array. ---- - -# Series.loc - -danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** - -## **Examples** - -`.loc()` is label position based (from `0` to `length-1` of the row axis). - -Allowed inputs are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Indexing by specific row index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc(["a", "g"]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╟───┼─────╢ -║ e │ 30 ║ -╟───┼─────╢ -║ f │ 30 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╟───┼─────╢ -║ h │ 7 ║ -╚═══╧═════╝ - -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc([`"a":"e"`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -`s.loc([a:e]).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -`s.loc(["a":"e"]).print()`\ -\ -_**Inner quotes are not needed for numeric indices!**_ -{% endhint %} - -### By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -let s = new dfd.Series(data) - -s.loc([`1:`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 1 │ 34 ║ -╟───┼─────╢ -║ 2 │ 2.2 ║ -╟───┼─────╢ -║ 3 │ 2 ║ -╟───┼─────╢ -║ 4 │ 30 ║ -╟───┼─────╢ -║ 5 │ 30 ║ -╟───┼─────╢ -║ 6 │ 2.1 ║ -╟───┼─────╢ -║ 7 │ 7 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.loc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference copy/series/series.lt.md b/api-reference copy/series/series.lt.md deleted file mode 100644 index 7af18bc..0000000 --- a/api-reference copy/series/series.lt.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all values in a Series are less than a value. ---- - -# Series.lt - -> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are less than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.lt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.lt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.map.md b/api-reference copy/series/series.map.md deleted file mode 100644 index 0e0850a..0000000 --- a/api-reference copy/series/series.map.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -description: Map the value of a series to a function or Object ---- - -# Series.map - -> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] - -| Parameter | Type | Description | Default | -| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function or Object | A function or object({}) | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Example** - -Mapping the element in a Series words in an Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ ok ║ -╟───┼──────────────────────╢ -║ 1 │ okie ║ -╟───┼──────────────────────╢ -║ 2 │ frit ║ -╟───┼──────────────────────╢ -║ 3 │ gop ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Mapping values in a Series to a representation using functions. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ I have 1 cat(s) ║ -╟───┼──────────────────────╢ -║ 1 │ I have 2 cat(s) ║ -╟───┼──────────────────────╢ -║ 2 │ I have 3 cat(s) ║ -╟───┼──────────────────────╢ -║ 3 │ I have 4 cat(s) ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.max.md b/api-reference copy/series/series.max.md deleted file mode 100644 index 4f7193a..0000000 --- a/api-reference copy/series/series.max.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the maximum value in a Series ---- - -# Series.max - -> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.max()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -89 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.maximum.md b/api-reference copy/series/series.maximum.md deleted file mode 100644 index afc5a48..0000000 --- a/api-reference copy/series/series.maximum.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Obtain the maximum number between two series ---- - -# Series.maximum - -> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.maximum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 41 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference copy/series/series.mean.md b/api-reference copy/series/series.mean.md deleted file mode 100644 index 17d97e6..0000000 --- a/api-reference copy/series/series.mean.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the mean of a series ---- - -# Series.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mean()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -23.000001907348633 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.median.md b/api-reference copy/series/series.median.md deleted file mode 100644 index d1cde75..0000000 --- a/api-reference copy/series/series.median.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the median of a series ---- - -# Series.median - -> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.median()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -4 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.min.md b/api-reference copy/series/series.min.md deleted file mode 100644 index 6e11a67..0000000 --- a/api-reference copy/series/series.min.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the minimum value in a series ---- - -# Series.min - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.min()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -0 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.minimum.md b/api-reference copy/series/series.minimum.md deleted file mode 100644 index a06ba69..0000000 --- a/api-reference copy/series/series.minimum.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Obtain the minimum value between two series (element wise) ---- - -# Series.minimum - -> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.minimum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 40 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.mod.md b/api-reference copy/series/series.mod.md deleted file mode 100644 index fdf0555..0000000 --- a/api-reference copy/series/series.mod.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -description: Return Modulo of series and other, element-wise (binary operator mod). ---- - -# Series.mod - -> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\|float | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Modulus with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mod(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.8999999761581421 ║ -╟───┼──────────────────────╢ -║ 1 │ 1.3999993801116943 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.7000000476837158 ║ -╟───┼──────────────────────╢ -║ 3 │ 0.19999980926513672 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Modulo with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mod(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.mode.md b/api-reference copy/series/series.mode.md deleted file mode 100644 index 6077686..0000000 --- a/api-reference copy/series/series.mode.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the center value in a series ---- - -# Series.mode - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mode()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 4 ] -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.mul.md b/api-reference copy/series/series.mul.md deleted file mode 100644 index d5d33de..0000000 --- a/api-reference copy/series/series.mul.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Multiplication of series and other, element-wise (binary operator mul). ---- - -# Series.mul - -> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -multiplication with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mul(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 80 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -multiply with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mul(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.ndim.md b/api-reference copy/series/series.ndim.md deleted file mode 100644 index 8623e80..0000000 --- a/api-reference copy/series/series.ndim.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dimension of a series ---- - -# Series.ndim - -> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] - -**Parameters:** None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.ndim) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -1 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.ne.md b/api-reference copy/series/series.ne.md deleted file mode 100644 index 16cf1dc..0000000 --- a/api-reference copy/series/series.ne.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all values in a series is not equal to a value(s) ---- - -# Series.ne - -> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Example** - -Compare all the values in a series to that in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ne(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Compare all the values in a Series to a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ne(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.nunique.md b/api-reference copy/series/series.nunique.md deleted file mode 100644 index 092a2eb..0000000 --- a/api-reference copy/series/series.nunique.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Returns the number of unique values in a series ---- - -# Series.nunique - -> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters**: None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -console.log(sf.nunique()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Ouptut" %} -``` -9 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.or.md b/api-reference copy/series/series.or.md deleted file mode 100644 index 948c61d..0000000 --- a/api-reference copy/series/series.or.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical OR between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.or - -> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical OR between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.or(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.pow.md b/api-reference copy/series/series.pow.md deleted file mode 100644 index 2fbe542..0000000 --- a/api-reference copy/series/series.pow.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# Series.pow - -> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Exponential power with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.pow(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 9 ║ -╟───┼──────────────────────╢ -║ 2 │ 64 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Exponential value with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.pow(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 16 ║ -╟───┼──────────────────────╢ -║ 4 │ 25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.replace.md b/api-reference copy/series/series.replace.md deleted file mode 100644 index 8a1f48b..0000000 --- a/api-reference copy/series/series.replace.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -description: Replace values given in replace param with value ---- - -# Series.replace - -> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Replace a value in a series and return a new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Replace a value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` diff --git a/api-reference copy/series/series.reset_index.md b/api-reference copy/series/series.reset_index.md deleted file mode 100644 index c51497a..0000000 --- a/api-reference copy/series/series.reset_index.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -description: Reset the index of a series. ---- - -# Series.reset\_index - -> danfo.series.reset\_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | - -**Returns :** Series - -`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. - -### **Reset index to default values** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [20, 30, 40] -let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) -sf.print() - -let sf_reset = sf.reset_index() -sf_reset.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ a │ 20 ║ -╟───┼────╢ -║ b │ 30 ║ -╟───┼────╢ -║ c │ 40 ║ -╚═══╧════╝ - -╔═══╤════╗ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 2 │ 40 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Reset index to new values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) -sf.print() - -sf.reset_index({ inplace: true }) -sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╟───┼───╢ -║ f │ 6 ║ -╚═══╧═══╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 4 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 6 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.round.md b/api-reference copy/series/series.round.md deleted file mode 100644 index b6f0d82..0000000 --- a/api-reference copy/series/series.round.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: round off floating values in series ---- - -# Series.round - -> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| dp | int | decimal place to round off to | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -sf1.round(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.19 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.56 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.02 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.sample.md b/api-reference copy/series/series.sample.md deleted file mode 100644 index a28298d..0000000 --- a/api-reference copy/series/series.sample.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# Series.sample - -> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| num | Int | The number of rows to return. | | -| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| - -**Returns:** - - **** return **{Promies} resolves to Series** - -**Example** - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5) - sample.print() - -} -load_data() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤════╗ -║ 2 │ 3 ║ -╟───┼────╢ -║ 4 │ 5 ║ -╟───┼────╢ -║ 0 │ 1 ║ -╟───┼────╢ -║ 7 │ 40 ║ -╟───┼────╢ -║ 6 │ 30 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Specify a seed when sampling - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5, { seed: 2 }) - sample.print() - -} -load_data() - -``` diff --git a/api-reference copy/series/series.set_index.md b/api-reference copy/series/series.set_index.md deleted file mode 100644 index 3de352f..0000000 --- a/api-reference copy/series/series.set_index.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# Series.set\_index - -> danfo.series.**set\_index(**options**)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] - -| Parameter | Type | Description | Default | -| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| index | Array | new index values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let sf = new dfd.Series(data) -sf.print() - -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════════════════════════╗ -║ 0 │ {"alpha":"A","count":1} ║ -╟───┼─────────────────────────╢ -║ 1 │ {"alpha":"B","count":2} ║ -╟───┼─────────────────────────╢ -║ 2 │ {"alpha":"C","count":3} ║ -╚═══╧═════════════════════════╝ - -╔═══════╤═════════════════════════╗ -║ one │ {"alpha":"A","count":1} ║ -╟───────┼─────────────────────────╢ -║ two │ {"alpha":"B","count":2} ║ -╟───────┼─────────────────────────╢ -║ three │ {"alpha":"C","count":3} ║ -╚═══════╧═════════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ H │ Humans ║ -╟───┼──────────────────────╢ -║ L │ Life ║ -╟───┼──────────────────────╢ -║ M │ Meaning ║ -╟───┼──────────────────────╢ -║ F │ Fact ║ -╟───┼──────────────────────╢ -║ T │ Truth ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Set index in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data) -sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) -sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤═══╗ -║ one │ 1 ║ -╟───────┼───╢ -║ two │ 2 ║ -╟───────┼───╢ -║ three │ 3 ║ -╟───────┼───╢ -║ four │ 4 ║ -╟───────┼───╢ -║ five │ 5 ║ -╟───────┼───╢ -║ six │ 6 ║ -╚═══════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.shape.md b/api-reference copy/series/series.shape.md deleted file mode 100644 index 9eb5031..0000000 --- a/api-reference copy/series/series.shape.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the shape of a Series ---- - -# Series.shape - -> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] - -**Parameters**: None - -**Returns**: Array \[int, int\] - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.shape) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 4, 1 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.size.md b/api-reference copy/series/series.size.md deleted file mode 100644 index 9665b65..0000000 --- a/api-reference copy/series/series.size.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Obtain the size of a series ---- - -# Series.size - -> danfo.Series.size \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] - -**Parameters**: None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.size) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -4 -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference copy/series/series.sort_values.md b/api-reference copy/series/series.sort_values.md deleted file mode 100644 index 5c7e5fa..0000000 --- a/api-reference copy/series/series.sort_values.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Sorts a Series in ascending or descending order ---- - -# Series.sort_values - -> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| - - **Return:** Series - -### Sort values in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.sort_values() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Sort Series in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ inplace: true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ - -``` -{% endtab %} -{% endtabs %} - -Sort Series values in descending order - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ "ascending": false, "inplace": true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 6 │ 89 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 7 │ 0 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.std.md b/api-reference copy/series/series.std.md deleted file mode 100644 index aa05018..0000000 --- a/api-reference copy/series/series.std.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Obtain the standard deviation for a series ---- - -# Series.std - -> danfo.Series.std() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.std()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -31.11671576500322 -``` -{% endtab %} -{% endtabs %} - - **** - diff --git a/api-reference copy/series/series.str.capitalize.md b/api-reference copy/series/series.str.capitalize.md deleted file mode 100644 index aea9e91..0000000 --- a/api-reference copy/series/series.str.capitalize.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Capitalize the first character of each string ---- - -# Series.str.capitalize - -> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert the first character of a string to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'capitals', 'sentence', 'swApCaSe'] -let sf = new dfd.Series(data) -sf.str.capitalize().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ Capitals ║ -╟───┼──────────────────────╢ -║ 2 │ Sentence ║ -╟───┼──────────────────────╢ -║ 3 │ Swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.charat.md b/api-reference copy/series/series.str.charat.md deleted file mode 100644 index 931bb48..0000000 --- a/api-reference copy/series/series.str.charat.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Obtain the character at the specified index (position) ---- - -# Series.str.charAt - -> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| index | int | the index at which to obtain the character | 0 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Character element) - -**Example** - -Obtain the character at index 2 of all string elements in the series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.charAt(2).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ w ║ -╟───┼──────────────────────╢ -║ 1 │ P ║ -╟───┼──────────────────────╢ -║ 2 │ n ║ -╟───┼──────────────────────╢ -║ 3 │ A ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.concat.md b/api-reference copy/series/series.str.concat.md deleted file mode 100644 index e3abe54..0000000 --- a/api-reference copy/series/series.str.concat.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -description: Joins two or more strings/arrays ---- - -# Series.str.concat - -> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other** (string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series (String element) - -**Examples** - -Add the strings from an Array to the start of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ XXlower boy ║ -╟───┼──────────────────────╢ -║ 1 │ YYCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ BBsentence ║ -╟───┼──────────────────────╢ -║ 3 │ 01SwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add the strings from an Array to the end of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boyXX ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSYY ║ -╟───┼──────────────────────╢ -║ 2 │ sentenceBB ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSe01 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the start of each string element in a Series - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("pre",0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ prelower boy ║ -╟───┼──────────────────────╢ -║ 1 │ preCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ presentence ║ -╟───┼──────────────────────╢ -║ 3 │ preSwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the end of each string element in a series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("post",1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boypost ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSpost ║ -╟───┼──────────────────────╢ -║ 2 │ sentencepost ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSepost ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference copy/series/series.str.endswith.md b/api-reference copy/series/series.str.endswith.md deleted file mode 100644 index 2fb44cc..0000000 --- a/api-reference copy/series/series.str.endswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string ends with specified characters ---- - -# Series.str.endsWith - -> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.endsWith("e").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.includes.md b/api-reference copy/series/series.str.includes.md deleted file mode 100644 index 8918773..0000000 --- a/api-reference copy/series/series.str.includes.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string contains the specified string/characters ---- - -# Series.str.includes - -> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.includes("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.indexof.md b/api-reference copy/series/series.str.indexof.md deleted file mode 100644 index 1d9e64f..0000000 --- a/api-reference copy/series/series.str.indexof.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: the position of the first found occurrence of a specified value in a string ---- - -# Series.str.indexOf - -> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to obtain its index | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.indexOf("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.join.md b/api-reference copy/series/series.str.join.md deleted file mode 100644 index 5bb77fe..0000000 --- a/api-reference copy/series/series.str.join.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Join a new string value to all string elements in a Series. ---- - -# Series.str.join - -> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return **Series** - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part', 'CAPITALS city', 'this is a sentence', 'SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.join("new", "_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════════════════════════╗ -║ 0 │ lower part_new ║ -╟───┼────────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼────────────────────────╢ -║ 2 │ this is a sentence_new ║ -╟───┼────────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧════════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.lastindexof.md b/api-reference copy/series/series.str.lastindexof.md deleted file mode 100644 index 889a1f4..0000000 --- a/api-reference copy/series/series.str.lastindexof.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Obtain the position of the last found occurrence of a specified value in a - string ---- - -# Series.str.lastIndexOf - -danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.lastIndexOf("r").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.str.len.md b/api-reference copy/series/series.str.len.md deleted file mode 100644 index 0ef06b2..0000000 --- a/api-reference copy/series/series.str.len.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the length of each string element in a Series ---- - -# Series.str.len - -> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Examples** - -Returns the length (number of character) of a string, and also return the length (number of elements) of Array - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["dog", 5,"cat","fog","mug","animals"] -let sf = new dfd.Series(data) -sf.str.len().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.repeat.md b/api-reference copy/series/series.str.repeat.md deleted file mode 100644 index 703be26..0000000 --- a/api-reference copy/series/series.str.repeat.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Repeat the the character(s) in a string for a specified number of time ---- - -# Series.str.repeat - -> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] - -| Parameters | Type | Description | Default | -| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | -| num | integer | the string to search for | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['a', 'b', 'c', 'd'] -let sf = new dfd.Series(data) -sf.str.repeat(4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ aaaa ║ -╟───┼──────────────────────╢ -║ 1 │ bbbb ║ -╟───┼──────────────────────╢ -║ 2 │ cccc ║ -╟───┼──────────────────────╢ -║ 3 │ dddd ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.replace.md b/api-reference copy/series/series.str.replace.md deleted file mode 100644 index 2b06b1f..0000000 --- a/api-reference copy/series/series.str.replace.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Replace a word or character(s) in a String element ---- - -# Series.str.replace - -> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] - -| Parameters | Type | Description | Default | -| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| searchValue | string | String \| Character value to replace. Supports regex. | "" | -| replaceValue | String | string to replace the searched string | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.replace("A", "XXX").print() -``` -{% endtab %} - -{% tab title="Browse" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower ║ -╟───┼──────────────────────╢ -║ 1 │ CXXXPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwXXXpCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.search.md b/api-reference copy/series/series.str.search.md deleted file mode 100644 index 99fc428..0000000 --- a/api-reference copy/series/series.str.search.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Obtain the index position of a searched character in a String ---- - -# Series.str.search - -> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] - - - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | String | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series: Series of index position - -**Example** - -obtain the index position for a character - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 8 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Obtain the index position for a searched word - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower city ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("city").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.slice.md b/api-reference copy/series/series.str.slice.md deleted file mode 100644 index cef7a86..0000000 --- a/api-reference copy/series/series.str.slice.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.slice - -> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series. - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.slice(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.split.md b/api-reference copy/series/series.str.split.md deleted file mode 100644 index 006795d..0000000 --- a/api-reference copy/series/series.str.split.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: >- - Split string around a given separator/delimiter. The array of strings are then - converted to a string. ---- - -# Series.str.split - -> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | -| splitVal | String | separator or delimiter used to split the string | " " | -| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| - -**Returns** - - return **Series** - -**Examples** - -Split the string value in the Series by space and obtain the Series values - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king of the music","the lamba queen","I love the hat"] -let sf = new dfd.Series(data) -console.log(sf.str.split().values) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king_of_the_music","the_lamba_queen","I_love_the_hat"] -let sf = new dfd.Series(data) -sf.str.split("_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ king,of,the,music ║ -╟───┼──────────────────────╢ -║ 1 │ the,lamba,queen ║ -╟───┼──────────────────────╢ -║ 2 │ I,love,the,hat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.startswith.md b/api-reference copy/series/series.str.startswith.md deleted file mode 100644 index 835809e..0000000 --- a/api-reference copy/series/series.str.startswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Test whether a string begins with specified characters ---- - -# Series.str.startsWith - -> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series (Boolean element) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.startsWith("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.substr.md b/api-reference copy/series/series.str.substr.md deleted file mode 100644 index 0a391bb..0000000 --- a/api-reference copy/series/series.str.substr.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: >- - Obtain the substring from a String element in a Series, by specifying the - number of string to obtain starting from a specific index. ---- - -# Series.str.substr - -> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series - -**Example** - -Obtain substring( containing 4 characters) starting from the third character (2nd index). - -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substr(2, 4).print() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ wer ║ -╟───┼──────────────────────╢ -║ 1 │ APIT ║ -╟───┼──────────────────────╢ -║ 2 │ his ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.substring.md b/api-reference copy/series/series.str.substring.md deleted file mode 100644 index b54702e..0000000 --- a/api-reference copy/series/series.str.substring.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.substring - -> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns** - - **** return **Series** - -**Example** - -Obtain the substring from index 2 to index 4 of the string elements in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substring(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.tolowercase.md b/api-reference copy/series/series.str.tolowercase.md deleted file mode 100644 index 9abe0f5..0000000 --- a/api-reference copy/series/series.str.tolowercase.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Converts all characters to lower case. ---- - -# Series.str.toLowerCase - -> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -Convert all characters in each string element to small letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['LOWER BOY', 'CAPITALS', 'SENTENCE', 'SWAPCASE'] -let sf = new dfd.Series(data) -sf.str.toLowerCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ capitals ║ -╟───┼──────────────────────╢ -║ 2 │ sentence ║ -╟───┼──────────────────────╢ -║ 3 │ swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.touppercase.md b/api-reference copy/series/series.str.touppercase.md deleted file mode 100644 index f484390..0000000 --- a/api-reference copy/series/series.str.touppercase.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Converts all characters to uppercase. ---- - -# Series.str.toUpperCase - -> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert all characters in each string element to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.toUpperCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ LOWER BOY ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ SENTENCE ║ -╟───┼──────────────────────╢ -║ 3 │ SWAPCASE ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.str.trim.md b/api-reference copy/series/series.str.trim.md deleted file mode 100644 index 58b7b16..0000000 --- a/api-reference copy/series/series.str.trim.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Remove leading and trailing Whitespace from a String element ---- - -# Series.str.trim - -> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.trim().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.sub.md b/api-reference copy/series/series.sub.md deleted file mode 100644 index e281d06..0000000 --- a/api-reference copy/series/series.sub.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Subtraction of series and other, element-wise (binary operator sub). ---- - -# Series.sub - -> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.sub(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 29 ║ -╟───┼──────────────────────╢ -║ 1 │ 38 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.sub(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.sum.md b/api-reference copy/series/series.sum.md deleted file mode 100644 index fabcba7..0000000 --- a/api-reference copy/series/series.sum.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# Series.sum - -> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.sum()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -207 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference copy/series/series.tail.md b/api-reference copy/series/series.tail.md deleted file mode 100644 index 7f986a1..0000000 --- a/api-reference copy/series/series.tail.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# Series.tail - -> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of last n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.tail().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 6 │ 30 ║ -╟────┼──────────────────────╢ -║ 7 │ 40 ║ -╟────┼──────────────────────╢ -║ 8 │ 39 ║ -╟────┼──────────────────────╢ -║ 9 │ 89 ║ -╟────┼──────────────────────╢ -║ 10 │ 78 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.tensor.md b/api-reference copy/series/series.tensor.md deleted file mode 100644 index a5c112c..0000000 --- a/api-reference copy/series/series.tensor.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: Obtain the tensor representation of the values in a Series ---- - -# Series.tensor - -> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] - -**Parameters**: None - -**Returns**: Tensorflow tensor - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.tensor) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 4 ], - dtype: 'float32', - size: 4, - strides: [], - dataId: {}, - id: 2, - rankType: '1', - scopeId: 0 -} -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.unique.md b/api-reference copy/series/series.unique.md deleted file mode 100644 index c89d187..0000000 --- a/api-reference copy/series/series.unique.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the unique value in a Series ---- - -# Series.unique - -> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] - -**Parameters**: None - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.unique().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╟───┼──────────────────────╢ -║ 6 │ 7 ║ -╟───┼──────────────────────╢ -║ 7 │ 8 ║ -╟───┼──────────────────────╢ -║ 8 │ 22 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.value_counts.md b/api-reference copy/series/series.value_counts.md deleted file mode 100644 index 338064f..0000000 --- a/api-reference copy/series/series.value_counts.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Count the number of occurrence for each element in a Series ---- - -# Series.value\_counts - -> danfo.Series.value\_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters:** None - -**Returns:** Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.value_counts().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 1 │ 3 ║ -╟────┼──────────────────────╢ -║ 2 │ 1 ║ -╟────┼──────────────────────╢ -║ 3 │ 1 ║ -╟────┼──────────────────────╢ -║ 4 │ 1 ║ -╟────┼──────────────────────╢ -║ 5 │ 4 ║ -╟────┼──────────────────────╢ -║ 6 │ 1 ║ -╟────┼──────────────────────╢ -║ 7 │ 1 ║ -╟────┼──────────────────────╢ -║ 8 │ 2 ║ -╟────┼──────────────────────╢ -║ 22 │ 1 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference copy/series/series.values.md b/api-reference copy/series/series.values.md deleted file mode 100644 index 4857487..0000000 --- a/api-reference copy/series/series.values.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the values in a series ---- - -# Series.values - -> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] - -**Parameters:** None - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.values) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 30.21091, 40.190901, 3.564, 5.0212 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference copy/series/series.var.md b/api-reference copy/series/series.var.md deleted file mode 100644 index 4fdcbc2..0000000 --- a/api-reference copy/series/series.var.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Calculate the variance of a Series ---- - -# Series.var - -> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.var()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -968.25 -``` -{% endtab %} -{% endtabs %} - From 558b3f4f15e3c0d7192e75846cdc57c8c8c30050 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Jan 2022 15:21:54 +0000 Subject: [PATCH 160/202] GitBook: [#213] Update doc guide for new TS version --- README.md | 13 +- SUMMARY.md | 105 ++-- api-reference/README.md | 13 +- api-reference/configuration-options.md | 14 +- api-reference/dataframe/README.md | 74 ++- .../dataframe/creating-a-dataframe.md | 69 +-- .../dataframe/danfo.dataframe.abs.md | 6 +- .../dataframe/danfo.dataframe.add.md | 24 +- .../dataframe/danfo.dataframe.addcolumn.md | 39 +- .../dataframe/danfo.dataframe.apply.md | 28 +- .../dataframe/danfo.dataframe.column.md | 10 +- .../dataframe/danfo.dataframe.copy.md | 11 +- .../dataframe/danfo.dataframe.count.md | 43 +- .../dataframe/danfo.dataframe.cummax.md | 26 +- .../dataframe/danfo.dataframe.cummin.md | 28 +- .../dataframe/danfo.dataframe.cumprod.md | 72 ++- .../dataframe/danfo.dataframe.cumsum.md | 20 +- .../dataframe/danfo.dataframe.describe.md | 9 +- .../dataframe/danfo.dataframe.div.md | 31 +- .../dataframe/danfo.dataframe.dropna.md | 84 +-- api-reference/dataframe/danfo.dataframe.eq.md | 13 +- .../dataframe/danfo.dataframe.fillna.md | 82 ++- api-reference/dataframe/danfo.dataframe.ge.md | 16 +- .../dataframe/danfo.dataframe.groupby.md | 51 +- api-reference/dataframe/danfo.dataframe.gt.md | 28 +- .../dataframe/danfo.dataframe.head.md | 7 +- .../dataframe/danfo.dataframe.iloc.md | 23 +- .../dataframe/danfo.dataframe.isna.md | 17 +- api-reference/dataframe/danfo.dataframe.it.md | 27 +- api-reference/dataframe/danfo.dataframe.le.md | 15 +- .../dataframe/danfo.dataframe.loc.md | 31 +- .../dataframe/danfo.dataframe.max.md | 59 +- .../dataframe/danfo.dataframe.mean.md | 71 ++- .../dataframe/danfo.dataframe.median.md | 106 ++-- .../dataframe/danfo.dataframe.min.md | 57 +- .../dataframe/danfo.dataframe.mod.md | 27 +- .../dataframe/danfo.dataframe.mul.md | 28 +- api-reference/dataframe/danfo.dataframe.ne.md | 16 +- .../dataframe/danfo.dataframe.pow.md | 27 +- .../dataframe/danfo.dataframe.query.md | 170 ++---- .../dataframe/danfo.dataframe.replace.md | 22 +- .../dataframe/danfo.dataframe.round.md | 10 +- .../dataframe/danfo.dataframe.sample.md | 43 +- .../dataframe/danfo.dataframe.std.md | 31 +- .../dataframe/danfo.dataframe.sub.md | 28 +- .../dataframe/danfo.dataframe.sum.md | 42 +- .../dataframe/danfo.dataframe.tail.md | 7 +- .../dataframe/danfo.dataframe.var.md | 91 +-- api-reference/dataframe/dataframe.append.md | 21 +- .../dataframe/dataframe.apply_map.md | 12 +- api-reference/dataframe/dataframe.astype.md | 64 +-- api-reference/dataframe/dataframe.axes.md | 12 +- api-reference/dataframe/dataframe.drop.md | 14 +- api-reference/dataframe/dataframe.dtypes.md | 11 +- api-reference/dataframe/dataframe.index.md | 6 +- api-reference/dataframe/dataframe.ndim.md | 11 +- .../dataframe/dataframe.nunique-1.md | 51 +- api-reference/dataframe/dataframe.print.md | 22 +- api-reference/dataframe/dataframe.rename.md | 56 +- .../dataframe/dataframe.reset_index.md | 20 +- .../dataframe/dataframe.select_dtypes.md | 22 +- .../dataframe/dataframe.set_index.md | 20 +- api-reference/dataframe/dataframe.shape.md | 7 +- .../dataframe/dataframe.sort_index.md | 16 +- .../dataframe/dataframe.sort_values.md | 30 +- api-reference/dataframe/dataframe.tensor.md | 27 +- api-reference/dataframe/dataframe.to_csv.md | 27 +- api-reference/dataframe/dataframe.to_excel.md | 18 +- api-reference/dataframe/dataframe.to_json.md | 28 +- api-reference/dataframe/dataframe.values.md | 9 +- api-reference/general-functions/README.md | 44 +- .../danfo.-convertfunctiontotransformer.md | 103 ++++ .../general-functions/danfo.concat.md | 28 +- .../general-functions/danfo.date_range.md | 21 +- api-reference/general-functions/danfo.dt.md | 49 ++ .../general-functions/danfo.get_dummies.md | 23 +- .../general-functions/danfo.labelencoder.md | 84 +-- .../general-functions/danfo.merge.md | 24 +- .../general-functions/danfo.minmaxscaler.md | 10 +- .../general-functions/danfo.onehotencoder.md | 126 +---- .../general-functions/danfo.standardscaler.md | 99 ++-- api-reference/general-functions/danfo.str.md | 67 +++ .../general-functions/danfo.streamcsv.md | 104 ++++ .../danfo.streamcsvtransformer.md | 181 ++++++ .../general-functions/danfo.streamjson.md | 101 ++++ .../general-functions/danfo.tensorflow.md | 70 +++ .../general-functions/danfo.to_datetime.md | 209 ++++--- .../general-functions/danfo.utils.md | 25 + api-reference/input-output/danfo.read_csv.md | 28 +- .../input-output/danfo.read_excel.md | 61 ++- api-reference/input-output/danfo.read_json.md | 18 +- api-reference/input-output/danfo.to_csv.md | 24 +- api-reference/input-output/danfo.to_excel.md | 26 +- api-reference/input-output/danfo.to_json.md | 17 +- api-reference/plotting/bar-charts.md | 10 +- api-reference/plotting/box-plots.md | 231 ++++++-- .../plotting/configuring-your-plots.md | 182 ++++-- api-reference/plotting/histograms.md | 179 ++++-- api-reference/plotting/line-charts.md | 25 +- api-reference/plotting/pie-charts.md | 109 ++-- api-reference/plotting/scatter-plots.md | 38 +- api-reference/plotting/tables.md | 212 +++++-- api-reference/plotting/timeseries-plots.md | 121 ++-- api-reference/plotting/violin-plots.md | 163 +++++- api-reference/series/README.md | 111 ++-- api-reference/series/creating-a-series.md | 54 +- api-reference/series/series.abs.md | 40 +- api-reference/series/series.add.md | 3 +- api-reference/series/series.and.md | 17 +- api-reference/series/series.append.md | 12 +- api-reference/series/series.apply.md | 103 ++-- api-reference/series/series.argmax.md | 9 +- api-reference/series/series.argmin.md | 9 +- api-reference/series/series.argsort.md | 52 +- api-reference/series/series.copy.md | 4 +- api-reference/series/series.count.md | 6 +- api-reference/series/series.cummax.md | 44 +- api-reference/series/series.cummin.md | 44 +- api-reference/series/series.cumprod.md | 44 +- api-reference/series/series.cumsum.md | 44 +- api-reference/series/series.describe.md | 34 +- api-reference/series/series.div.md | 2 +- .../series/series.drop_duplicates.md | 84 ++- api-reference/series/series.dropna.md | 78 ++- api-reference/series/series.dt.day.md | 34 +- api-reference/series/series.dt.hour.md | 7 +- api-reference/series/series.dt.minute.md | 4 +- api-reference/series/series.dt.month.md | 4 +- api-reference/series/series.dt.month_name.md | 6 +- api-reference/series/series.dt.monthday.md | 8 +- api-reference/series/series.dt.second.md | 6 +- api-reference/series/series.dt.weekdays.md | 50 +- api-reference/series/series.dt.year.md | 4 +- api-reference/series/series.eq.md | 72 ++- api-reference/series/series.fillna.md | 107 ++-- api-reference/series/series.ge.md | 70 ++- api-reference/series/series.gt.md | 66 ++- api-reference/series/series.head.md | 15 +- api-reference/series/series.iloc.md | 76 ++- api-reference/series/series.index.md | 5 +- api-reference/series/series.isna.md | 31 +- api-reference/series/series.le.md | 69 ++- api-reference/series/series.loc.md | 26 +- api-reference/series/series.lt.md | 67 ++- api-reference/series/series.map.md | 46 +- api-reference/series/series.max.md | 4 +- api-reference/series/series.maximum.md | 34 +- api-reference/series/series.mean.md | 6 +- api-reference/series/series.median.md | 6 +- api-reference/series/series.min.md | 4 +- api-reference/series/series.minimum.md | 33 +- api-reference/series/series.mod.md | 48 +- api-reference/series/series.mode.md | 6 +- api-reference/series/series.mul.md | 3 +- api-reference/series/series.ndim.md | 2 +- api-reference/series/series.ne.md | 72 ++- api-reference/series/series.nunique.md | 6 +- api-reference/series/series.or.md | 17 +- api-reference/series/series.pow.md | 6 +- api-reference/series/series.replace.md | 16 +- api-reference/series/series.reset_index.md | 19 +- api-reference/series/series.round.md | 23 +- api-reference/series/series.sample.md | 35 +- api-reference/series/series.set_index.md | 36 +- api-reference/series/series.shape.md | 7 +- api-reference/series/series.sort_values.md | 15 +- api-reference/series/series.std.md | 5 +- api-reference/series/series.str.split.md | 8 +- api-reference/series/series.sub.md | 3 +- api-reference/series/series.sum.md | 4 +- api-reference/series/series.tail.md | 13 +- api-reference/series/series.tensor.md | 5 +- api-reference/series/series.unique.md | 45 +- api-reference/series/series.value_counts.md | 46 +- api-reference/series/series.values.md | 7 +- api-reference/series/series.var.md | 5 +- contributing-guide.md | 83 +-- ...ating-to-the-stable-version-of-danfo.js.md | 92 ++++ ...iction-using-danfo.js-and-tensorflow.js.md | 50 +- examples/using-danfojs-in-react.md | 13 +- getting-started.md | 518 +++++++++--------- release-notes.md | 32 +- 182 files changed, 4378 insertions(+), 3696 deletions(-) create mode 100644 api-reference/general-functions/danfo.-convertfunctiontotransformer.md create mode 100644 api-reference/general-functions/danfo.dt.md create mode 100644 api-reference/general-functions/danfo.str.md create mode 100644 api-reference/general-functions/danfo.streamcsv.md create mode 100644 api-reference/general-functions/danfo.streamcsvtransformer.md create mode 100644 api-reference/general-functions/danfo.streamjson.md create mode 100644 api-reference/general-functions/danfo.tensorflow.md create mode 100644 api-reference/general-functions/danfo.utils.md create mode 100644 examples/migrating-to-the-stable-version-of-danfo.js.md diff --git a/README.md b/README.md index 1d1d31c..d5001e5 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ description: >- # Danfo.js Documentation -D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js.** +D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/pandas-docs/stable/index.html) library and provides a similar interface and API. This means users familiar with the [Pandas ](https://pandas.pydata.org/pandas-docs/stable/index.html)API can easily use D**anfo.js.** ## Main Features -* Danfo.js is fast and supports[ Tensorflow.js](https://js.tensorflow.org)'s tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. -* Easy handling of missing **** data (represented as `NaN`) in floating point as well as non-floating point data +* Danfo.js is fast and supports[ Tensorflow.js](https://js.tensorflow.org)'s tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. +* Easy handling of missing data (represented as `NaN, undefined, or null`) in data * Size mutability: columns can be inserted/deleted from DataFrame * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations * Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data @@ -26,7 +26,7 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda ## Getting Started -New to Danfo? Check out the getting started guides. It contains a quick introduction to D_anfo's_ main concepts and links to additional content. +New to Danfo? Check out the getting started guides. It contains a quick introduction to D\_anfo's\_ main concepts and links to additional content. {% content-ref url="getting-started.md" %} [getting-started.md](getting-started.md) @@ -34,7 +34,7 @@ New to Danfo? Check out the getting started guides. It contains a quick introduc ## **API Reference** -The reference guide contains a detailed description of the **danfo** API. The reference describes how each function works and which parameters can be used. +The reference guide contains a detailed description of the **danfo** API. The reference describes how each function works and which parameters can be used. {% content-ref url="api-reference/" %} [api-reference](api-reference/) @@ -54,7 +54,7 @@ The reference guide contains a detailed description of the **danfo** API. The re ## Contributing Guide -Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. +Want to help improve our documentation and existing functionalities? The contributing guidelines will guide you through the process. {% content-ref url="contributing-guide.md" %} [contributing-guide.md](contributing-guide.md) @@ -65,4 +65,3 @@ Want to help improve our documentation and existing functionalities? The contrib {% content-ref url="release-notes.md" %} [release-notes.md](release-notes.md) {% endcontent-ref %} - diff --git a/SUMMARY.md b/SUMMARY.md index 43e65db..d9a3ae2 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -4,29 +4,37 @@ * [Getting Started](getting-started.md) * [API reference](api-reference/README.md) * [General Functions](api-reference/general-functions/README.md) - * [danfo.date\_range](api-reference/general-functions/danfo.date\_range.md) + * [danfo.tensorflow](api-reference/general-functions/danfo.tensorflow.md) + * [danfo. convertFunctionTotransformer](api-reference/general-functions/danfo.-convertfunctiontotransformer.md) + * [danfo.streamCsvTransformer](api-reference/general-functions/danfo.streamcsvtransformer.md) + * [danfo.streamJSON](api-reference/general-functions/danfo.streamjson.md) + * [danfo.streamCSV](api-reference/general-functions/danfo.streamcsv.md) + * [danfo.Utils](api-reference/general-functions/danfo.utils.md) + * [danfo.Str](api-reference/general-functions/danfo.str.md) + * [danfo.Dt](api-reference/general-functions/danfo.dt.md) + * [danfo.dateRange](api-reference/general-functions/danfo.date\_range.md) * [danfo.OneHotEncoder](api-reference/general-functions/danfo.onehotencoder.md) * [danfo.StandardScaler](api-reference/general-functions/danfo.standardscaler.md) * [danfo.MinMaxScaler](api-reference/general-functions/danfo.minmaxscaler.md) * [danfo.LabelEncoder](api-reference/general-functions/danfo.labelencoder.md) * [danfo.toDateTime](api-reference/general-functions/danfo.to\_datetime.md) - * [danfo.get\_dummies](api-reference/general-functions/danfo.get\_dummies.md) + * [danfo.getDummies](api-reference/general-functions/danfo.get\_dummies.md) * [danfo.concat](api-reference/general-functions/danfo.concat.md) * [danfo.merge](api-reference/general-functions/danfo.merge.md) * [Input/Output](api-reference/input-output/README.md) - * [danfo.read\_excel](api-reference/input-output/danfo.read\_excel.md) - * [danfo.read\_json](api-reference/input-output/danfo.read\_json.md) - * [danfo.read\_csv](api-reference/input-output/danfo.read\_csv.md) - * [danfo.to\_csv](api-reference/input-output/danfo.to\_csv.md) - * [danfo.to\_excel](api-reference/input-output/danfo.to\_excel.md) - * [danfo.to\_json](api-reference/input-output/danfo.to\_json.md) + * [danfo.readExcel](api-reference/input-output/danfo.read\_excel.md) + * [danfo.toExcel](api-reference/input-output/danfo.to\_excel.md) + * [danfo.readJSON](api-reference/input-output/danfo.read\_json.md) + * [danfo.toJSON](api-reference/input-output/danfo.to\_json.md) + * [danfo.readCSV](api-reference/input-output/danfo.read\_csv.md) + * [danfo.toCSV](api-reference/input-output/danfo.to\_csv.md) * [Series](api-reference/series/README.md) * [Creating a Series](api-reference/series/creating-a-series.md) * [Series.append](api-reference/series/series.append.md) - * [Series.cumsum](api-reference/series/series.cumsum.md) - * [Series.cummax](api-reference/series/series.cummax.md) - * [Series.cumprod](api-reference/series/series.cumprod.md) - * [Series.cummin](api-reference/series/series.cummin.md) + * [Series.cumSum](api-reference/series/series.cumsum.md) + * [Series.cumMax](api-reference/series/series.cummax.md) + * [Series.cumProd](api-reference/series/series.cumprod.md) + * [Series.cumMin](api-reference/series/series.cummin.md) * [Series.str.split](api-reference/series/series.str.split.md) * [Series.str.len](api-reference/series/series.str.len.md) * [Series.str.join](api-reference/series/series.str.join.md) @@ -49,23 +57,23 @@ * [Series.str.capitalize](api-reference/series/series.str.capitalize.md) * [Series.dt.seconds](api-reference/series/series.dt.second.md) * [Series.dt.minutes](api-reference/series/series.dt.minute.md) - * [Series.dt.monthday](api-reference/series/series.dt.monthday.md) - * [Series.dt.month\_name](api-reference/series/series.dt.month\_name.md) - * [Series.dt.hour](api-reference/series/series.dt.hour.md) - * [Series.dt.weekdays](api-reference/series/series.dt.weekdays.md) - * [Series.dt.day](api-reference/series/series.dt.day.md) + * [Series.dt.dayOfMonth](api-reference/series/series.dt.monthday.md) + * [Series.dt.monthName](api-reference/series/series.dt.month\_name.md) + * [Series.dt.hours](api-reference/series/series.dt.hour.md) + * [Series.dt.dayOfWeek](api-reference/series/series.dt.weekdays.md) + * [Series.dt.dayOfWeek](api-reference/series/series.dt.day.md) * [Series.dt.month](api-reference/series/series.dt.month.md) * [Series.dt.year](api-reference/series/series.dt.year.md) - * [Series.argmax](api-reference/series/series.argmax.md) - * [Series.argmin](api-reference/series/series.argmin.md) - * [Series.argsort](api-reference/series/series.argsort.md) + * [Series.argMax](api-reference/series/series.argmax.md) + * [Series.argMin](api-reference/series/series.argmin.md) + * [Series.argSort](api-reference/series/series.argsort.md) * [Series.replace](api-reference/series/series.replace.md) - * [Series.isna](api-reference/series/series.isna.md) - * [Series.fillna](api-reference/series/series.fillna.md) - * [Series.dropna](api-reference/series/series.dropna.md) - * [Series.drop\_duplicates](api-reference/series/series.drop\_duplicates.md) - * [Series.value\_counts](api-reference/series/series.value\_counts.md) - * [Series.nunique](api-reference/series/series.nunique.md) + * [Series.isNa](api-reference/series/series.isna.md) + * [Series.fillNa](api-reference/series/series.fillna.md) + * [Series.dropNa](api-reference/series/series.dropna.md) + * [Series.dropDuplicates](api-reference/series/series.drop\_duplicates.md) + * [Series.valueCounts](api-reference/series/series.value\_counts.md) + * [Series.nUnique](api-reference/series/series.nunique.md) * [Series.unique](api-reference/series/series.unique.md) * [Series.abs](api-reference/series/series.abs.md) * [Series.ne](api-reference/series/series.ne.md) @@ -84,11 +92,11 @@ * [Series.index](api-reference/series/series.index.md) * [Series.apply](api-reference/series/series.apply.md) * [Series.map](api-reference/series/series.map.md) - * [Series.set\_index](api-reference/series/series.set\_index.md) - * [Series.reset\_index](api-reference/series/series.reset\_index.md) + * [Series.setIndex](api-reference/series/series.set\_index.md) + * [Series.resetIndex](api-reference/series/series.reset\_index.md) * [Series.describe](api-reference/series/series.describe.md) * [Series.copy](api-reference/series/series.copy.md) - * [Series.sort\_values](api-reference/series/series.sort\_values.md) + * [Series.sortValues](api-reference/series/series.sort\_values.md) * [Series.var](api-reference/series/series.var.md) * [Series.std](api-reference/series/series.std.md) * [Series.round](api-reference/series/series.round.md) @@ -114,25 +122,25 @@ * [Series.or](api-reference/series/series.or.md) * [Dataframe](api-reference/dataframe/README.md) * [Creating a DataFrame](api-reference/dataframe/creating-a-dataframe.md) - * [DataFrame.sort\_index](api-reference/dataframe/dataframe.sort\_index.md) + * [DataFrame.sortIndex](api-reference/dataframe/dataframe.sort\_index.md) * [DataFrame.append](api-reference/dataframe/dataframe.append.md) - * [DataFrame.nunique](api-reference/dataframe/dataframe.nunique-1.md) + * [DataFrame.nUnique](api-reference/dataframe/dataframe.nunique-1.md) * [DataFrame.tensor](api-reference/dataframe/dataframe.tensor.md) * [DataFrame.print](api-reference/dataframe/dataframe.print.md) - * [DataFrame.to\_csv](api-reference/dataframe/dataframe.to\_csv.md) - * [DataFrame.to\_json](api-reference/dataframe/dataframe.to\_json.md) - * [DataFrame.to\_excel](api-reference/dataframe/dataframe.to\_excel.md) - * [DataFrame.sort\_values](api-reference/dataframe/dataframe.sort\_values.md) - * [DataFrame.set\_index](api-reference/dataframe/dataframe.set\_index.md) - * [DataFrame.reset\_index](api-reference/dataframe/dataframe.reset\_index.md) + * [DataFrame.toCSV](api-reference/dataframe/dataframe.to\_csv.md) + * [DataFrame.toJSON](api-reference/dataframe/dataframe.to\_json.md) + * [DataFrame.toExcel](api-reference/dataframe/dataframe.to\_excel.md) + * [DataFrame.sortValues](api-reference/dataframe/dataframe.sort\_values.md) + * [DataFrame.setIndex](api-reference/dataframe/dataframe.set\_index.md) + * [DataFrame.resetIndex](api-reference/dataframe/dataframe.reset\_index.md) * [DataFrame.rename](api-reference/dataframe/dataframe.rename.md) * [DataFrame.drop](api-reference/dataframe/dataframe.drop.md) - * [DataFrame.astype](api-reference/dataframe/dataframe.astype.md) + * [DataFrame.asType](api-reference/dataframe/dataframe.astype.md) * [DataFrame.shape](api-reference/dataframe/dataframe.shape.md) * [DataFrame.axis](api-reference/dataframe/dataframe.axes.md) * [DataFrame.ndim](api-reference/dataframe/dataframe.ndim.md) * [DataFrame.values](api-reference/dataframe/dataframe.values.md) - * [DataFrame.select\_dtypes](api-reference/dataframe/dataframe.select\_dtypes.md) + * [DataFrame.selectDtypes](api-reference/dataframe/dataframe.select\_dtypes.md) * [DataFrame.ctypes](api-reference/dataframe/dataframe.dtypes.md) * [DataFrame.index](api-reference/dataframe/dataframe.index.md) * [DataFrame.loc](api-reference/dataframe/danfo.dataframe.loc.md) @@ -154,10 +162,10 @@ * [DataFrame.var](api-reference/dataframe/danfo.dataframe.var.md) * [DataFrame.count](api-reference/dataframe/danfo.dataframe.count.md) * [DataFrame.round](api-reference/dataframe/danfo.dataframe.round.md) - * [DataFrame.cumsum](api-reference/dataframe/danfo.dataframe.cumsum.md) - * [DataFrame.cummin](api-reference/dataframe/danfo.dataframe.cummin.md) - * [DataFrame.cummax](api-reference/dataframe/danfo.dataframe.cummax.md) - * [DataFrame.cumprod](api-reference/dataframe/danfo.dataframe.cumprod.md) + * [DataFrame.cumSum](api-reference/dataframe/danfo.dataframe.cumsum.md) + * [DataFrame.cumMin](api-reference/dataframe/danfo.dataframe.cummin.md) + * [DataFrame.cumMax](api-reference/dataframe/danfo.dataframe.cummax.md) + * [DataFrame.cumProd](api-reference/dataframe/danfo.dataframe.cumprod.md) * [DataFrame.copy](api-reference/dataframe/danfo.dataframe.copy.md) * [DataFrame.describe](api-reference/dataframe/danfo.dataframe.describe.md) * [DataFrame.sum](api-reference/dataframe/danfo.dataframe.sum.md) @@ -166,11 +174,11 @@ * [DataFrame.addColumn](api-reference/dataframe/danfo.dataframe.addcolumn.md) * [DataFrame.groupby](api-reference/dataframe/danfo.dataframe.groupby.md) * [DataFrame.column](api-reference/dataframe/danfo.dataframe.column.md) - * [DataFrame.fillna](api-reference/dataframe/danfo.dataframe.fillna.md) - * [DataFrame.isna](api-reference/dataframe/danfo.dataframe.isna.md) - * [DataFrame.dropna](api-reference/dataframe/danfo.dataframe.dropna.md) + * [DataFrame.fillNa](api-reference/dataframe/danfo.dataframe.fillna.md) + * [DataFrame.isNa](api-reference/dataframe/danfo.dataframe.isna.md) + * [DataFrame.dropNa](api-reference/dataframe/danfo.dataframe.dropna.md) * [DataFrame.apply](api-reference/dataframe/danfo.dataframe.apply.md) - * [DataFrame.apply\_map](api-reference/dataframe/dataframe.apply\_map.md) + * [DataFrame.applyMap](api-reference/dataframe/dataframe.apply\_map.md) * [DataFrame.It](api-reference/dataframe/danfo.dataframe.it.md) * [DataFrame.gt](api-reference/dataframe/danfo.dataframe.gt.md) * [DataFrame.le](api-reference/dataframe/danfo.dataframe.le.md) @@ -189,7 +197,7 @@ * [Scatter Plots](api-reference/plotting/scatter-plots.md) * [Bar Charts](api-reference/plotting/bar-charts.md) * [Line Charts](api-reference/plotting/line-charts.md) - * [Configuring your plots](api-reference/plotting/configuring-your-plots.md) + * [Customizing your plots](api-reference/plotting/configuring-your-plots.md) * [Groupby](api-reference/groupby/README.md) * [Groupby.get\_groups](api-reference/groupby/groupby.get\_groups.md) * [Groupby.col](api-reference/groupby/groupby.col.md) @@ -206,6 +214,7 @@ * [Groupby.cumprod](api-reference/groupby/groupby.cumprod.md) * [Groupby.agg](api-reference/groupby/groupby.agg.md) * [User Guides](examples/README.md) + * [Migrating to the stable version of Danfo.js](examples/migrating-to-the-stable-version-of-danfo.js.md) * [Using Danfojs in React](examples/using-danfojs-in-react.md) * [Titanic Survival Prediction using Danfo.js and Tensorflow.js](examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md) * [Building Data Driven Applications with Danfo.js - Book](building-data-driven-applications-with-danfo.js-book.md) diff --git a/api-reference/README.md b/api-reference/README.md index b5d5d28..9e79ca8 100644 --- a/api-reference/README.md +++ b/api-reference/README.md @@ -1,11 +1,17 @@ --- description: >- - This page gives an overview of all public danfo objects, functions and - methods. All classes and functions exposed in danfo.* namespace are public. + List of all public Danfo objects, functions and methods. All classes and + functions exposed in danfo.* namespace is public. --- # API reference +{% hint style="info" %} +A stable version of Danfojs (v1), has been released, and it comes with full Typescript support, new features, and many bug fixes. See release note [here](../release-notes.md#latest-release-node-v1.0.0-browser-v1.0.0). + +There are a couple of breaking changes, so we have prepared a short migration [guide](../examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1 users. +{% endhint %} + * [General Functions](general-functions/) * [Data manipulations](general-functions/#data-manipulations) * [Data Processing/Normalization](general-functions/#data-processing-normalization) @@ -26,7 +32,7 @@ description: >- * [Accessors](series/#accessors) * [Serialization / IO / conversion](series/#serialization-io-conversion) * [DataFrame](dataframe/) - * [Attributes ](dataframe/#attributes) + * [Attributes](dataframe/#attributes) * [Conversion](dataframe/#conversion) * [Indexing, iteration](dataframe/#indexing-iteration) * [Binary operator functions](dataframe/#binary-operator-functions) @@ -51,4 +57,3 @@ description: >- * [Indexing, iteration](groupby/#indexing-iteration) * [Function application](groupby/#function-application) * [Computations / descriptive stats](groupby/#computations-descriptive-stats) - diff --git a/api-reference/configuration-options.md b/api-reference/configuration-options.md index f4c2136..d2fa5d7 100644 --- a/api-reference/configuration-options.md +++ b/api-reference/configuration-options.md @@ -6,14 +6,14 @@ description: >- # Configuration Options -On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. +On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. -| Parameter | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | -| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | -| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | -| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| +| Parameter | Description | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | +| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | +| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 20 | +| lowMemoryMode |

Boolean, whether to use minimal memory space or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| > See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) diff --git a/api-reference/dataframe/README.md b/api-reference/dataframe/README.md index d48a28d..f1f7322 100644 --- a/api-reference/dataframe/README.md +++ b/api-reference/dataframe/README.md @@ -4,30 +4,23 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da # Dataframe -> `DataFrame`(data, {\ -> **columns:** \[ Array ],\ -> **dtypes:** \[ Array ], **** \ -> **index:** \[Array], \ -> **options**: Object}) - ### Attributes | [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | | ------------------------------------------------ | ---------------------------------------- | | [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| -------------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.select_dtypes`](dataframe.select\_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | +| [`DataFrame.ctypes`](dataframe.dtypes.md) | | +| ----------------------------------------- | - | +| [`DataFrame.values`](dataframe.values.md) | | +| [`DataFrame.axis`](dataframe.axes.md) | | +| [`DataFrame.ndim`](dataframe.ndim.md) | | +| [`DataFrame.size`](broken-reference/) | | +| [`DataFrame.shape`](dataframe.shape.md) | | ### Conversion -| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | +| [`DataFrame.asType`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | | ------------------------------------------- | -------------------------------------------------- | | [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | @@ -49,10 +42,10 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da | [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | | [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | | [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | -| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | +| [`DataFrame.lt`](broken-reference/) | Get Less than of dataframe and other, element-wise (binary operator lt). | | [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | | [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | -| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | +| [`DataFrame.ge`](broken-reference/) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | | [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | | [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | @@ -67,12 +60,12 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da | [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | | --------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | +| [`DataFrame.corr`](broken-reference/) | Compute pairwise correlation of columns, excluding NA/null values. | | [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | -| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`DataFrame.cumMax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`DataFrame.cumMin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`DataFrame.cumProd`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`DataFrame.cumSum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | | [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | | [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | | [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | @@ -83,34 +76,34 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da | [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | | [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | | [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | -| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | +| [`DataFrame.nUnique`](broken-reference/) | Count distinct observations over requested axis. | ### Reindexing / selection / label manipulation -| | | -| ---------------------------------------------------- | ------------------------------------------------------- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset\_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| | | +| --------------------------------------------------- | ------------------------------------------------------- | +| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | +| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | +| [`DataFrame.resetIndex`](dataframe.reset\_index.md) | Reset the index of a DataFrame | +| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | +| [`DataFrame.setIndex`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | ### Missing data handling | | | | ------------------------------------------------- | ------------------------------------------- | -| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | -| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | -| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | +| [`DataFrame.dropNa`](danfo.dataframe.dropna.md) | Remove missing values. | +| [`DataFrame.fillNa`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | +| [`DataFrame.isNa`](danfo.dataframe.isna.md) | Detect missing values. | | [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | ### Sorting & transposing | | | | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| [`DataFrame.sort_values`](dataframe.sort\_values.md) | Sort by the values along either axis. | +| [`DataFrame.sortVlues`](dataframe.sort\_values.md) | Sort by the values along either axis. | | [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | ### Combining / comparing / joining / merging @@ -139,7 +132,8 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da ### Serialization / IO / conversion -| | | -| -------------------------------------------- | ---------------------------------------------------- | -| [`DataFrame.to_csv`](dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`DataFrame.to_json`](dataframe.to\_json.md) | Convert the object to a JSON string. | +| | | +| ------------------------------------------------------------- | -------------------------------- | +| [`DataFrame.toCSV`](dataframe.to\_csv.md) | Convert DataFrame to a CSV file. | +| [`DataFrame.toJSON`](dataframe.to\_json.md) | Convert the object to a JSON. | +| ``[`DataFrame.toExcel`](../input-output/danfo.to\_excel.md)`` | Convert DataFrame to Excel file | diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index 0228131..2103b9d 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -4,49 +4,14 @@ description: Creates a DataFrame object from flat structure # Creating a DataFrame -new danfo.**DataFrame**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

columns: Array of column names. If not specified, column names are - auto generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. +danfo.**DataFrame**(data, options) + +| Parameters | Type | Description | +| ---------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| data | 2D Array, 2D Tensor, JSON object. | Flat data structure to load into DataFrame | +| options | Object |

Optional configuration object. Supported properties are:

index: Array of numeric or string names for subseting array. If not specified, indexes are auto-generated.

columns: Array of column names. If not specified, column names are auto generated.

dtypes: Array of data types for each the column. If not specified, dtypes are/is inferred.

config: General configuration object for extending or setting NDframe behavior. See full options here

| + +In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. ### Creating a `DataFrame` from a JSON object: @@ -143,7 +108,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -159,8 +124,7 @@ df.print() {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -const tf = require("@tensorflow/tfjs-node") - +const tf = dfd.tensorflow let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) @@ -201,7 +165,7 @@ df.ctypes.print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -231,7 +195,7 @@ df.ctypes.print() const dfd = require("danfojs-node") -dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) +dates = new dfd.dateRange({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) console.log(dates); @@ -285,7 +249,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` //output in console ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D │ E ║ @@ -302,7 +266,7 @@ df.print() ### Creating a `DataFrame` and specifying index, dtypes, columns -You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. +You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. > Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. @@ -322,7 +286,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -348,8 +312,7 @@ df.print() ``` {% hint style="info" %} -**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. +**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. {% endhint %} For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) - diff --git a/api-reference/dataframe/danfo.dataframe.abs.md b/api-reference/dataframe/danfo.dataframe.abs.md index 8504222..bac894a 100644 --- a/api-reference/dataframe/danfo.dataframe.abs.md +++ b/api-reference/dataframe/danfo.dataframe.abs.md @@ -4,16 +4,12 @@ description: Return a DataFrame with the absolute numeric value of each element. # DataFrame.abs -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**sum**(options) | Parameters | Type | Description | Default | | ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | | options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | -**Returns:** - - **** return **Series** - ## **Examples** The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index 925a3cd..3ee1719 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -4,16 +4,12 @@ description: Get Addition of DataFrame and other, element-wise (binary operator # DataFrame.add -danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.**add**(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | - | +| other | DataFrame, Series, Array or Scalar | Object to add with | | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

|

{

axis: 1,

inplace: false

}

| | ## **Examples** @@ -60,7 +56,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of **Series to** DataFrame along axis 0 +### Addition of **Series to** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -105,7 +101,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of **** DataFrame to a DataFrame +### Addition of DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -124,7 +120,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.add(df2) df_new.print() - ``` {% endtab %} @@ -152,7 +147,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of **** Array to DataFrame along axis 0 +### Addition of Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -193,7 +188,6 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 12 │ 26 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -239,8 +233,6 @@ df.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 12 │ 26 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.addcolumn.md b/api-reference/dataframe/danfo.dataframe.addcolumn.md index ef0ecc9..422cd9c 100644 --- a/api-reference/dataframe/danfo.dataframe.addcolumn.md +++ b/api-reference/dataframe/danfo.dataframe.addcolumn.md @@ -4,11 +4,13 @@ description: Add new column to a DataFrame # DataFrame.addColumn -danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] +danfo.DataFrame.**addColumn**(column**,** values**,** options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | +| Parameters | Type | Description | Default | +| ----------- | ------------------ | ------------------------------------------------------------- | ----------------- | +| **column** | String | Name of the column to add. | | +| **values** | Series**,** Array | New values to add | | +| **options** | Object | **inplace**: Whether to perform the operation inplace or not. | Default to false. | **Returns:** @@ -16,21 +18,24 @@ danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9 ## **Add Array as a new column to DataFrame** -New columns get added at the end of the DataFrame, and this happens so returns nothing, +New columns get added at the end of the DataFrame. {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} + +let data = { + "A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); +df.addColumn("D", new_col, { inplace: true }); df.print() ``` @@ -57,9 +62,6 @@ df.print() ║ 3 │ 3 │ 6 │ 40 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - Shape: (4,3) - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -81,13 +83,18 @@ df.print() {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} + +let data = { + "A": [30, 1, 2, 3], + "B": [34, 4, 5, 6], + "C": [20, 20, 30, 40] +} let df = new dfd.DataFrame(data) +df.print() + let s = new dfd.Series([1, 2, 3, 4]) -df.addColumn({ "column": "D", "values": s, inplace: true }); +df.addColumn("D", s, { inplace: true }); df.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.apply.md b/api-reference/dataframe/danfo.dataframe.apply.md index de42294..15ab9fc 100644 --- a/api-reference/dataframe/danfo.dataframe.apply.md +++ b/api-reference/dataframe/danfo.dataframe.apply.md @@ -4,20 +4,16 @@ description: Apply a function to each element or along a specified axis of a Dat # DataFrame.apply -danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.**apply**(callable, options) | Parameters | Type | Description | Default | | ---------- | -------- | --------------------------------------------------------------------- | --------- | | callable | Function | Function to apply to each column or row | | | options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | -**Returns:** - - **** return **DataFrame** - ## **Examples** -### Apply a function along default axis 1 (columns) +### Apply a function along default axis 1 (columns) {% hint style="info" %} Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. @@ -51,17 +47,19 @@ df_new.print() {% tab title="Output" %} ``` ╔═══╤═════╗ -║ A │ 64 ║ +║ 0 │ 6 ║ ╟───┼─────╢ -║ B │ 126 ║ +║ 1 │ 15 ║ ╟───┼─────╢ -║ C │ 127 ║ +║ 2 │ 90 ║ +╟───┼─────╢ +║ 3 │ 206 ║ ╚═══╧═════╝ ``` {% endtab %} {% endtabs %} -### Apply a function along axis 0 (row) +### Apply a function along axis 0 (row) {% tabs %} {% tab title="Node" %} @@ -78,7 +76,6 @@ function sum_vals(col) { let df_new = df.apply(sum_vals, { axis: 0 }) df_new.print() - ``` {% endtab %} @@ -92,15 +89,12 @@ df_new.print() {% tab title="Output" %} ``` ╔═══╤═════╗ -║ 0 │ 6 ║ -╟───┼─────╢ -║ 1 │ 15 ║ +║ A │ 64 ║ ╟───┼─────╢ -║ 2 │ 90 ║ +║ B │ 126 ║ ╟───┼─────╢ -║ 3 │ 206 ║ +║ C │ 127 ║ ╚═══╧═════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.column.md b/api-reference/dataframe/danfo.dataframe.column.md index 7d963a2..61eccba 100644 --- a/api-reference/dataframe/danfo.dataframe.column.md +++ b/api-reference/dataframe/danfo.dataframe.column.md @@ -1,19 +1,15 @@ --- -description: Return the elements of the specified column in the DataFrame +description: Return the elements of the specified column as a Series --- # DataFrame.column -danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] +danfo.DataFrame.**column**(column) | Parameters | Type | Description | Default | | ---------- | ------ | ------------------------------------- | ------- | | column | String | The name of a column in the DataFrame | | -**Returns:** - - **** return **Series** - ## **Examples** ## **Select a single column from a DataFrame** @@ -32,7 +28,6 @@ df.column("Name").print() //Alternatively, you can retrieve columns by using the object property df['Name'].print() //produces the same result as above - ``` {% endtab %} @@ -64,7 +59,6 @@ df['Name'].print() //produces the same result as above ╟───┼───────────╢ ║ 3 │ undefined ║ ╚═══╧═══════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.copy.md b/api-reference/dataframe/danfo.dataframe.copy.md index 188179d..1920e8d 100644 --- a/api-reference/dataframe/danfo.dataframe.copy.md +++ b/api-reference/dataframe/danfo.dataframe.copy.md @@ -1,14 +1,10 @@ --- -description: Makes a new copy of the DataFrame +description: Makes a deep copy of the DataFrame --- # DataFrame.copy -danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -**Returns:** - - **** return **new DataFrame** +danfo.DataFrame.**copy**() ## **Examples** @@ -34,7 +30,6 @@ new_df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -46,8 +41,6 @@ new_df.print() ╟───┼───────────────────┼───────────────────┼───────────────────╢ ║ 3 │ -20 │ 6 │ -40 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.count.md b/api-reference/dataframe/danfo.dataframe.count.md index 637cbf4..6bd35e2 100644 --- a/api-reference/dataframe/danfo.dataframe.count.md +++ b/api-reference/dataframe/danfo.dataframe.count.md @@ -6,16 +6,12 @@ description: >- # DataFrame.count -danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**count**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** ## Count Non-NaN values along default axis 1 (column) @@ -43,15 +39,15 @@ df.count().print() {% tabs %} {% tab title="Output" %} ``` -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ Name │ 3 ║ -╟───────┼──────────────────────╢ -║ Count │ 2 ║ -╟───────┼──────────────────────╢ -║ Price │ 4 ║ -╚═══════╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 2 ║ +╟───┼───╢ +║ 1 │ 3 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} @@ -81,20 +77,15 @@ df.count({axis: 0}).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══════╤═══╗ +║ Name │ 3 ║ +╟───────┼───╢ +║ Count │ 2 ║ +╟───────┼───╢ +║ Price │ 4 ║ +╚═══════╧═══╝ ``` {% endtab %} {% endtabs %} ## - diff --git a/api-reference/dataframe/danfo.dataframe.cummax.md b/api-reference/dataframe/danfo.dataframe.cummax.md index fb69bb5..a04bb20 100644 --- a/api-reference/dataframe/danfo.dataframe.cummax.md +++ b/api-reference/dataframe/danfo.dataframe.cummax.md @@ -2,32 +2,32 @@ description: Return cumulative maximum over a DataFrame or Series axis. --- -# DataFrame.cummax +# DataFrame.cumMax -danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] +danfo.DataFrame.cumMax(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | **Returns:** - **** return **DataFrame** +\*\*\*\* return **DataFrame** ## **Examples** -## Cumulative maximum of elements along default axis (row) +## Cumulative maximum of elements along axis (row) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 0 }) +let new_df = df.cumMax({ axis: 0 }) new_df.print() ``` @@ -64,11 +64,11 @@ new_df.print() ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 1 }) +let new_df = df.cumMax({ axis: 1 }) new_df.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.cummin.md b/api-reference/dataframe/danfo.dataframe.cummin.md index be026a6..4cd3d05 100644 --- a/api-reference/dataframe/danfo.dataframe.cummin.md +++ b/api-reference/dataframe/danfo.dataframe.cummin.md @@ -2,32 +2,28 @@ description: Return cumulative minimum over a DataFrame or Series axis. --- -# DataFrame.cummin +# DataFrame.cumMin -danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] +danfo.DataFrame.**cumMin**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | ## **Examples** -## Cumulative minimum of elements along default axis (row) +## Cumulative minimum of elements along axis 0 (row) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 0 }) +let new_df = df.cumMin({ axis: 0 }) new_df.print() ``` @@ -64,11 +60,11 @@ new_df.print() ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 1 }) +let new_df = df.cumMin({ axis: 1 }) new_df.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.cumprod.md b/api-reference/dataframe/danfo.dataframe.cumprod.md index 06ad53a..5dba3cf 100644 --- a/api-reference/dataframe/danfo.dataframe.cumprod.md +++ b/api-reference/dataframe/danfo.dataframe.cumprod.md @@ -2,32 +2,28 @@ description: Return cumulative product over a DataFrame or Series axis. --- -# DataFrame.cumprod +# DataFrame.cumProd -danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] +danfo.DataFrame.**cumProd**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | ## **Examples** -## Cumulative product of elements along default axis (row) +## Cumulative product of elements along default axis 1 (column) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod() +let new_df = df.cumProd() new_df.print() ``` @@ -42,17 +38,17 @@ new_df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 10 │ 18 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 300 │ 720 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 26700 │ 56160 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 220 │ 660 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 90 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 60 │ 2400 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 178 │ 13884 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -64,11 +60,11 @@ new_df.print() ```javascript const dfd = require("danfojs-node") -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod({axis: 1}) +let new_df = df.cumProd({ axis: 1 }) new_df.print() ``` @@ -83,17 +79,17 @@ new_df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 60 │ 2400 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 178 │ 13884 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 220 │ 660 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 90 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 60 │ 2400 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 178 │ 13884 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.cumsum.md b/api-reference/dataframe/danfo.dataframe.cumsum.md index 07be896..a2585fe 100644 --- a/api-reference/dataframe/danfo.dataframe.cumsum.md +++ b/api-reference/dataframe/danfo.dataframe.cumsum.md @@ -2,17 +2,13 @@ description: Return cumulative sum over a DataFrame or Series axis. --- -# DataFrame.cumsum +# DataFrame.cumSum -danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] +danfo.DataFrame.cumSum(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | ## **Examples** @@ -23,11 +19,11 @@ danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/ ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 0 }) +let new_df = df.cumSum({ axis: 0 }) new_df.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.describe.md b/api-reference/dataframe/danfo.dataframe.describe.md index 0540873..2bff123 100644 --- a/api-reference/dataframe/danfo.dataframe.describe.md +++ b/api-reference/dataframe/danfo.dataframe.describe.md @@ -6,20 +6,17 @@ description: >- # DataFrame.describe -danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] - -**Returns:** - - **** return **DataFrame** +danfo.DataFrame.**describe**() ## **Examples** -Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. +Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") + let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] let col_names = ["col1", "col2", "col3", "col4"] let df = new dfd.DataFrame(data, {columns: col_names}) diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index c98c66e..64929e0 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -1,21 +1,15 @@ --- -description: >- - Get Float division of DataFrame and other, element-wise (binary operator - truediv). +description: Get division of DataFrame and other, element-wise --- # DataFrame.div -danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.div(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to divide with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | ## **Examples** @@ -58,12 +52,11 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Division of **Series with** DataFrame along axis 0 +### Division of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -105,12 +98,11 @@ df_new.print() ║ 3 │ 0.25 │ 0.8000000119209… ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Division of **** DataFrame **with** a DataFrame +### Division of DataFrame **with** another DataFrame {% tabs %} {% tab title="Node" %} @@ -129,7 +121,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.div(df2) df_new.print() - ``` {% endtab %} @@ -154,12 +145,11 @@ df_new.print() ║ 3 │ 0 │ 2 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Division of **** Array **with** DataFrame along axis 0 +### Division of Array **with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -200,7 +190,6 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -247,8 +236,6 @@ df.print() ║ 3 │ 5 │ 12 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.dropna.md b/api-reference/dataframe/danfo.dataframe.dropna.md index 429bcbe..85a3c42 100644 --- a/api-reference/dataframe/danfo.dataframe.dropna.md +++ b/api-reference/dataframe/danfo.dataframe.dropna.md @@ -2,35 +2,31 @@ description: Remove missing values (NaNs, undefined, null) for DataFrame --- -# DataFrame.dropna +# DataFrame.dropNa -danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] +danfo.DataFrame.**dropNa**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | -| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace:** false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | -------------------- | +| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | +| options | Object | **inplace**: Boolean indicating whether to perform the operation inplace or not. Defaults to false | {**inplace:** false} | ## **Examples** -### Drop rows (axis=0) with missing values +### Drop rows (axis=0) with missing values {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, NaN, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropNa({ axis: 0 }) df_drop.print() ``` {% endtab %} @@ -44,29 +40,47 @@ df_drop.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╗ +║ │ C ║ +╟────────────┼───────────────────╢ +║ 0 │ 3 ║ +╟────────────┼───────────────────╢ +║ 1 │ 6 ║ +╟────────────┼───────────────────╢ +║ 2 │ 40 ║ +╟────────────┼───────────────────╢ +║ 3 │ 78 ║ +╚════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Drop columns (axis=1) with missing values +### Drop columns (axis=1) with missing values {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, NaN, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -df.dropna({axis: 1, inplace: true}) +df.dropNa({ axis: 1, inplace: true }) df.print() ``` {% endtab %} @@ -80,17 +94,23 @@ df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ NaN │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ NaN │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.eq.md b/api-reference/dataframe/danfo.dataframe.eq.md index 5f3cf2a..4fdbc19 100644 --- a/api-reference/dataframe/danfo.dataframe.eq.md +++ b/api-reference/dataframe/danfo.dataframe.eq.md @@ -4,7 +4,7 @@ description: Get Equal to of DataFrame and other, element-wise (binary operator # DataFrame.eq -danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.eq(other, option) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | @@ -13,11 +13,11 @@ danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/da **Returns:** -**** +*** ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -74,7 +74,6 @@ let df_rep = df.eq(sf, {axis:1}) df_rep.print() - ``` {% endtab %} @@ -102,7 +101,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -147,7 +146,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a JavaScript Array +### Comparing a DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.fillna.md b/api-reference/dataframe/danfo.dataframe.fillna.md index 2ddb860..8279d2e 100644 --- a/api-reference/dataframe/danfo.dataframe.fillna.md +++ b/api-reference/dataframe/danfo.dataframe.fillna.md @@ -4,22 +4,18 @@ description: >- for an array-like object. --- -# DataFrame.fillna +# DataFrame.fillNa -danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] +danfo.DataFrame.fillNa(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| values | Array \| Scalar | The list of value(s) to use for replacement. | | -| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| values | Array \| Scalar | The list of value(s) to use for replacement. | | +| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | ## **Examples** -### Fill missing values in specified columns with specified values +### Fill missing values in specified columns with specified values Missing values are NaN, undefined or null values @@ -38,9 +34,8 @@ let df = new dfd.DataFrame(data) df.print() let values = ["Apples", df["Count"].mean()] -let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) +let df_filled = df.fillNa(values, { columns: ["Name", "Count"] }) df_filled.print() - ``` {% endtab %} @@ -53,38 +48,34 @@ df_filled.print() {% tabs %} {% tab title="Output" %} ``` -//Before filling -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ NaN │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ NaN │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After filling - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 7.5 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 7.5 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ NaN │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ NaN │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ undefined │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Name │ Count │ Price ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Apples │ 7.5 │ 200 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Mango │ 5 │ 300 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Banana │ 7.5 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Apples │ 10 │ 250 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -### Fill all columns with NaNs with a specified value +### Fill all columns with NaNs with a specified value {% tabs %} {% tab title="Node" %} @@ -98,10 +89,9 @@ let data = { } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillNa("Apples") df_filled.print() - ``` {% endtab %} @@ -114,7 +104,6 @@ df_filled.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -130,7 +119,7 @@ df_filled.print() {% endtab %} {% endtabs %} -### Fill NaNs inplace +### Fill NaNs inplace {% tabs %} {% tab title="Node" %} @@ -144,7 +133,7 @@ let data = { let df = new dfd.DataFrame(data) let values = ["Apples", df["Count"].mean()] -df.fillna(values, { +df.fillNa(values, { columns: ["Name", "Count"], inplace: true }) @@ -161,7 +150,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/danfo.dataframe.ge.md b/api-reference/dataframe/danfo.dataframe.ge.md index 8e5401b..40a4316 100644 --- a/api-reference/dataframe/danfo.dataframe.ge.md +++ b/api-reference/dataframe/danfo.dataframe.ge.md @@ -6,20 +6,16 @@ description: >- # DataFrame.ge -danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.ge(other, option) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | | other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | | option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | -**Returns:** - - **DataFrame** - ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -61,7 +57,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -78,7 +74,6 @@ let df_rep = df.ge(sf, {axis:1}) df_rep.print() - ``` {% endtab %} @@ -106,7 +101,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -124,7 +119,6 @@ let df2 = new dfd.DataFrame(data2) let df_rep = df.ge(df2) df_rep.print() - ``` {% endtab %} @@ -152,7 +146,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a JavaScript Array +### Comparing a DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.groupby.md b/api-reference/dataframe/danfo.dataframe.groupby.md index e7d084f..b0adffc 100644 --- a/api-reference/dataframe/danfo.dataframe.groupby.md +++ b/api-reference/dataframe/danfo.dataframe.groupby.md @@ -4,16 +4,12 @@ description: Group DataFrame using a mapper or by a Series of columns. # DataFrame.groupby -danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] +danfo.DataFrame.**groupby**(columns) | Parameters | Type | Description | Default | | ---------- | ----- | ----------------------------------------------------- | ------- | | columns | Array | The names of a column(s) in the DataFrame to group by | | -**Returns:** - - **** return **DataFrame.groups** - ## **Examples** ## **Groupby a single column from a DataFrame** @@ -29,38 +25,26 @@ let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) let group_df = df.groupby(["A"]) console.log(group_df) +``` -//GroupBy Object -GroupBy { - key_col: [ 'A' ], - col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, +``` +// ouput +Groupby { + colDict: { + Pear: { A: [Array], B: [Array], C: [Array] }, + Apple: { A: [Array], B: [Array], C: [Array] } + }, + keyToValue: { Pear: [ 'Pear' ], Apple: [ 'Apple' ] }, + keyCol: [ 'A' ], data: [ [ 'Pear', 2, 3 ], [ 'Pear', 5, 6 ], [ 'Apple', 30, 40 ], [ 'Apple', 89, 78 ] ], - column_name: [ 'A', 'B', 'C' ], - data_tensors: { - Pear: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - '$index': [Array], - '$dtypes': [Array], - '$columns': [Array] - }, - Apple: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - ... - '$columns': [Array] - } - }, - col_dtype: [ 'string' ] + columnName: [ 'A', 'B', 'C' ], + colDtype: [ 'string' ], + colIndex: [ 0 ] } ``` {% endtab %} @@ -78,9 +62,9 @@ A groupby operation will return a GroupBy class object. You can apply any of the 3. [std](danfo.dataframe.std.md) 4. [var](danfo.dataframe.var.md) 5. [mean](danfo.dataframe.mean.md) -6. [cumsum](danfo.dataframe.cumsum.md) -7. [cummax](danfo.dataframe.cummax.md) -8. [cumprod](danfo.dataframe.cumprod.md) +6. [cumSum](danfo.dataframe.cumsum.md) +7. [cumMax](danfo.dataframe.cummax.md) +8. [cumProd](danfo.dataframe.cumprod.md) 9. [cummin](danfo.dataframe.cummin.md) 10. [max](danfo.dataframe.max.md) 11. [min](danfo.dataframe.min.md) @@ -98,7 +82,6 @@ let df = new dfd.DataFrame(data, { columns: cols }) let group_df = df.groupby(["A"]).sum() group_df.print() - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.gt.md b/api-reference/dataframe/danfo.dataframe.gt.md index ec3f7ba..f27ae72 100644 --- a/api-reference/dataframe/danfo.dataframe.gt.md +++ b/api-reference/dataframe/danfo.dataframe.gt.md @@ -4,20 +4,16 @@ description: Get Greater than of DataFrame and other, element-wise (binary opera # DataFrame.gt -danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.g**t**(other, option) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | | other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | | option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | -**Returns:** - - **** return **DataFrame** - ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value {% tabs %} {% tab title="Node" %} @@ -58,7 +54,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -74,7 +70,6 @@ let df_rep = df.gt(sf, {axis:1}) df_rep.print() - ``` {% endtab %} @@ -102,7 +97,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with another DataFrame {% tabs %} {% tab title="Node" %} @@ -120,7 +115,6 @@ let df2 = new dfd.DataFrame(data2) let df_rep = df.gt(df2) df_rep.print() - ``` {% endtab %} @@ -148,19 +142,21 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a JavaScript Array +### Comparing a DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] -let df_rep = df.gt(val, axis=1) +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} +let df = new dfd.DataFrame(data) +let val = [10, 40] +let df_rep = df.gt(val, { axis: 1 }) df_rep.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.head.md b/api-reference/dataframe/danfo.dataframe.head.md index 3fe62c4..31c72c0 100644 --- a/api-reference/dataframe/danfo.dataframe.head.md +++ b/api-reference/dataframe/danfo.dataframe.head.md @@ -4,16 +4,12 @@ description: Returns the first n rows of the DataFrame based on position. # DataFrame.head -danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] +danfo.DataFrame.**head**(rows) | Parameters | Type | Description | Default | | ---------- | ---- | ---------------------------- | ------- | | rows | Int | The number of rows to return | 5 | -**Returns:** - - **** return **DataFrame** - ## **Examples** {% tabs %} @@ -28,7 +24,6 @@ let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], let df = new dfd.DataFrame(data) let s_df = df.head(2) s_df.print() - ``` {% endtab %} diff --git a/api-reference/dataframe/danfo.dataframe.iloc.md b/api-reference/dataframe/danfo.dataframe.iloc.md index ffd7e25..9cd794c 100644 --- a/api-reference/dataframe/danfo.dataframe.iloc.md +++ b/api-reference/dataframe/danfo.dataframe.iloc.md @@ -4,15 +4,11 @@ description: Purely integer-location based indexing for selection by position. # DataFrame.iloc -danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.DataFrame.**iloc**(args) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | ## **Examples** @@ -72,7 +68,7 @@ sub_df.print() ### **Index by a slice of row and return all columns** -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. +The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. {% tabs %} {% tab title="Node" %} @@ -125,7 +121,6 @@ df.print() let sub_df = df.iloc({columns: ["1:"]}) sub_df.print() - ``` {% endtab %} @@ -168,7 +163,7 @@ sub_df.print() {% endtab %} {% endtabs %} -### Indexing both axes by the specified index +### Indexing both axis by the specified index {% tabs %} {% tab title="Node" %} @@ -194,7 +189,6 @@ sub_df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -221,7 +215,7 @@ sub_df.print() {% endtab %} {% endtabs %} -### Indexing both axes by slices +### Indexing both axis by slices {% tabs %} {% tab title="Node" %} @@ -237,7 +231,6 @@ df.print() let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) sub_df.print() - ``` {% endtab %} @@ -290,7 +283,6 @@ df.print() let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) sub_df.print() - ``` {% endtab %} @@ -328,4 +320,3 @@ sub_df.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.isna.md b/api-reference/dataframe/danfo.dataframe.isna.md index 830bda5..34b3f8c 100644 --- a/api-reference/dataframe/danfo.dataframe.isna.md +++ b/api-reference/dataframe/danfo.dataframe.isna.md @@ -1,17 +1,13 @@ --- description: >- - Return a boolean same-sized object indicating if the values are NaN. - NaN/undefined values gets mapped to true values, and everything else gets - mapped to false values. + Return a boolean same-sized object indicating if the values are missing. NaN. + null and undefined values get mapped to true, and everything else gets mapped + to false. --- -# DataFrame.isna +# DataFrame.isNa -danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] - -**Returns:** - - **** return **DataFrame** +danfo.DataFrame.**isNa**(kwargs) ## **Examples** @@ -24,8 +20,7 @@ let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) -df.isna().print() - +df.isNa().print() ``` {% endtab %} diff --git a/api-reference/dataframe/danfo.dataframe.it.md b/api-reference/dataframe/danfo.dataframe.it.md index 3759197..86ba58a 100644 --- a/api-reference/dataframe/danfo.dataframe.it.md +++ b/api-reference/dataframe/danfo.dataframe.it.md @@ -4,20 +4,16 @@ description: Get Less than of DataFrame and other, element-wise (binary operator # DataFrame.It -danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.l**t**(other, option) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | | other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | | option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | -**Returns:** - - **** return **DataFrame** - ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +54,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -76,7 +72,6 @@ let df_rep = df.lt(sf, { axis: 1 }) df_rep.print() - ``` {% endtab %} @@ -104,7 +99,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with another DataFrame {% tabs %} {% tab title="Node" %} @@ -122,7 +117,6 @@ let df2 = new dfd.DataFrame(data2) let df_rep = df.lt(df2) df_rep.print() - ``` {% endtab %} @@ -150,20 +144,21 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with an Array +### Comparing a DataFrame with an Array {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - +let data = { + "Col1": [10, 45, 56, 10], + "Col2": [23, 20, 10, 24] +} let df = new dfd.DataFrame(data) -let val = [10,40] +let val = [10, 40] -let df_rep = df.lt(val, axis=1) +let df_rep = df.lt(val, { axis: 1 }) df_rep.print() ``` diff --git a/api-reference/dataframe/danfo.dataframe.le.md b/api-reference/dataframe/danfo.dataframe.le.md index 31ce3f7..559fecd 100644 --- a/api-reference/dataframe/danfo.dataframe.le.md +++ b/api-reference/dataframe/danfo.dataframe.le.md @@ -6,20 +6,16 @@ description: >- # DataFrame.le -danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.le(other, option) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | | other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | | option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | -**Returns:** - - **** return **DataFrame** - ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -61,7 +57,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -78,7 +74,6 @@ let df_rep = df.le(sf, {axis:1}) df_rep.print() - ``` {% endtab %} @@ -106,7 +101,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with another DataFrame {% tabs %} {% tab title="Node" %} @@ -151,7 +146,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with an Array +### Comparing a DataFrame with an Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.loc.md b/api-reference/dataframe/danfo.dataframe.loc.md index abdcdd9..5fa3188 100644 --- a/api-reference/dataframe/danfo.dataframe.loc.md +++ b/api-reference/dataframe/danfo.dataframe.loc.md @@ -4,19 +4,15 @@ description: Access a group of rows and columns by label(s) # DataFrame.loc -danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**loc**(args) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | ## **Examples** -`.loc()` is label position based-from `0` to `length-1` of the row axis. +`.loc()` is label position based-from `0` to `length-1` of the row axis. Allowed inputs for are: @@ -25,7 +21,7 @@ Allowed inputs for are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` -_**Note:** only **** the start label is included, and the end label is ignored._ +_**Note:** only \*\*\*\* the start label is included, and the end label is ignored._ `.loc` will raise a `ValueEror` if a requested label is not found. @@ -58,7 +54,6 @@ sub_df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -169,7 +164,6 @@ sub_df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Name │ Count │ Price ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -198,7 +192,7 @@ sub_df.print() ## **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. {% tabs %} {% tab title="Node" %} @@ -250,14 +244,14 @@ sub_df.print() {% hint style="info" %} Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -df`.loc({ row: [a:e]}).print()`\ +df`.loc({ row: ["a:e"]}).print()`\ For the slice above to work, you must quote each slice, e.g:\ df``.loc({ row: [`"a":"e"`]}).print()``\ \ _**Inner**_ _**quotes are not needed for numeric indices!**_ {% endhint %} -### Slice DataFrame rows by boolean condition +### Slice DataFrame rows by boolean condition {% tabs %} {% tab title="Node" %} @@ -288,13 +282,12 @@ sub_df.print() ║ d │ Pear │ 10 │ 250 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` ### Slice DataFrame rows by multiple boolean conditions {% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame._ +_By design, you can chain as many boolean logic as required, as long as they resolve to a Boolean array of the same length as the DataFrame._ {% endhint %} {% tabs %} @@ -324,13 +317,12 @@ sub_df.print() ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ c │ Banana │ 30 │ 40 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` ### Slice DataFrame with boolean mask {% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ +_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ {% endhint %} {% tabs %} @@ -363,5 +355,4 @@ sub_df.print() ║ d │ Pear │ 10 │ 250 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` diff --git a/api-reference/dataframe/danfo.dataframe.max.md b/api-reference/dataframe/danfo.dataframe.max.md index a5c2119..abb2b0a 100644 --- a/api-reference/dataframe/danfo.dataframe.max.md +++ b/api-reference/dataframe/danfo.dataframe.max.md @@ -4,16 +4,12 @@ description: Return the maximum of the values for the requested axis. # DataFrame.max -danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**max**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** ## Return the maximum value along default axis 1 (column) @@ -22,12 +18,12 @@ danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/dan {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] -df.print() +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() df.max().print() ``` {% endtab %} @@ -53,15 +49,16 @@ df.max().print() ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 11 ║ -╟───┼──────────────────────╢ -║ B │ 89 ║ -╟───┼──────────────────────╢ -║ C │ 78 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 20 ║ +╟───┼────╢ +║ 1 │ 15 ║ +╟───┼────╢ +║ 2 │ 40 ║ +╟───┼────╢ +║ 3 │ 89 ║ +╚═══╧════╝ + ``` {% endtab %} {% endtabs %} @@ -72,12 +69,12 @@ df.max().print() {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df = new dfd.DataFrame(data) -df.max({axis:0}).print() +df.max({ axis: 0 }).print() ``` {% endtab %} @@ -102,17 +99,13 @@ df.max({axis:0}).print() ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 15 ║ -╟───┼──────────────────────╢ -║ 2 │ 40 ║ -╟───┼──────────────────────╢ -║ 3 │ 89 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ A │ 11 ║ +╟───┼────╢ +║ B │ 89 ║ +╟───┼────╢ +║ C │ 78 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.mean.md b/api-reference/dataframe/danfo.dataframe.mean.md index 172cff5..7cff35a 100644 --- a/api-reference/dataframe/danfo.dataframe.mean.md +++ b/api-reference/dataframe/danfo.dataframe.mean.md @@ -1,10 +1,10 @@ --- -description: Return the mean of the values for the requested axis. +description: Returns the mean of the values for the requested axis. --- # DataFrame.mean -danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**mean**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | @@ -12,7 +12,7 @@ danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/da **Returns:** - **** return **Series** +\*\*\*\* return **Series** ## **Examples** @@ -26,9 +26,8 @@ const dfd = require("danfojs-node") data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -df.print() - let df = new dfd.DataFrame(data) +df.print() df.mean().print() ``` {% endtab %} @@ -54,15 +53,15 @@ df.mean().print() ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 4 ║ -╟───┼──────────────────────╢ -║ B │ 38.5 ║ -╟───┼──────────────────────╢ -║ C │ 31.75 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════╗ +║ 0 │ 11.333333333333334 ║ +╟───┼────────────────────╢ +║ 1 │ 7.333333333333333 ║ +╟───┼────────────────────╢ +║ 2 │ 24 ║ +╟───┼────────────────────╢ +║ 3 │ 56.333333333333336 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -77,8 +76,8 @@ const dfd = require("danfojs-node") let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] let cols = ["A", "B", "C"] -df.print() let df = new dfd.DataFrame(data) +df.print() df.mean({ axis: 0 }).print() ``` {% endtab %} @@ -92,29 +91,25 @@ df.mean({ axis: 0 }).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11.333333015441895 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.333333492279053 ║ -╟───┼──────────────────────╢ -║ 2 │ 24 ║ -╟───┼──────────────────────╢ -║ 3 │ 56.33333206176758 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════╗ +║ A │ 4 ║ +╟───┼───────╢ +║ B │ 38.5 ║ +╟───┼───────╢ +║ C │ 31.75 ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.median.md b/api-reference/dataframe/danfo.dataframe.median.md index 3e33583..f94fd72 100644 --- a/api-reference/dataframe/danfo.dataframe.median.md +++ b/api-reference/dataframe/danfo.dataframe.median.md @@ -4,19 +4,15 @@ description: Return the median of the values for the requested axis. # DataFrame.median -danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**median**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** -## Calculates the median of values along default axis 1 (column) +## Computes the median of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -26,9 +22,8 @@ const dfd = require("danfojs-node") data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] cols = ["A", "B", "C"] -df.print() - let df = new dfd.DataFrame(data) +df.print() df.median().print() ``` {% endtab %} @@ -42,44 +37,45 @@ df.median().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 2 ║ -╟───┼──────────────────────╢ -║ B │ 25 ║ -╟───┼──────────────────────╢ -║ C │ 23 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════╗ +║ 0 │ 11 ║ +╟───┼────╢ +║ 1 │ 6 ║ +╟───┼────╢ +║ 2 │ 30 ║ +╟───┼────╢ +║ 3 │ 78 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} -## Calculates the median of values along row axis (0) +## Computes the median of values along row axis (0) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df = new dfd.DataFrame(data) -df.median({axis:0}).print() +df.median({ axis: 0 }).print() ``` {% endtab %} @@ -92,29 +88,25 @@ df.median({axis:0}).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 30 ║ -╟───┼──────────────────────╢ -║ 3 │ 78 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════╗ +║ A │ 2 ║ +╟───┼────╢ +║ B │ 25 ║ +╟───┼────╢ +║ C │ 23 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.min.md b/api-reference/dataframe/danfo.dataframe.min.md index 49a13d6..668c2af 100644 --- a/api-reference/dataframe/danfo.dataframe.min.md +++ b/api-reference/dataframe/danfo.dataframe.min.md @@ -4,16 +4,12 @@ description: Return the minimum of the values for the requested axis. # DataFrame.min -danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**min**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** ## Returns the minimum value along default axis 1 (column) @@ -23,12 +19,11 @@ danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/dan ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) df.print() - -let df = new dfd.DataFrame(data) df.min().print() ``` {% endtab %} @@ -54,15 +49,15 @@ df.min().print() ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 1 ║ -╟───┼──────────────────────╢ -║ B │ 15 ║ -╟───┼──────────────────────╢ -║ C │ 3 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 2 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} @@ -74,12 +69,12 @@ df.min().print() ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] +let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df = new dfd.DataFrame(data) -df.min({axis: 0}).print() +df.min({ axis: 0 }).print() ``` {% endtab %} @@ -104,17 +99,13 @@ df.min({axis: 0}).print() ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ A │ 1 ║ +╟───┼────╢ +║ B │ 15 ║ +╟───┼────╢ +║ C │ 3 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index 18558e6..f3cda7c 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -4,16 +4,12 @@ description: Get Modulo of DataFrame and other, element-wise (binary operator mo # DataFrame.mod -danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.mod(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to modulo with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | ## **Examples** @@ -58,12 +54,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Modulo of **Series with** DataFrame along axis 0 +### Modulo of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -106,12 +101,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Modulo of **** DataFrame with a DataFrame +### Modulo of DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -130,7 +124,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.mod(df2) df_new.print() - ``` {% endtab %} @@ -156,12 +149,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Modulo of **** Array with DataFrame along axis 0 +### Modulo of Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -203,7 +195,6 @@ df_new.print() ║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -251,8 +242,6 @@ df.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 3303d77..41b2baf 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -4,20 +4,16 @@ description: Get Multiplication of dataframe and other, element-wise (binary ope # DataFrame.mul -danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.mul(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to multiply with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | ## **Examples** -### Multiplication of **scalar to** DataFrame along default axis 1 +### Multiplication of **scalar with** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -60,7 +56,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Multiplication of **Series to** DataFrame along axis 0 +### Multiplication of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -101,12 +97,11 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 4 │ 20 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Multiplication of **** DataFrame to a DataFrame +### Multiplication of DataFrame **with** another DataFrame {% tabs %} {% tab title="Node" %} @@ -125,7 +120,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.mul(df2) df_new.print() - ``` {% endtab %} @@ -150,12 +144,11 @@ df_new.print() ║ 3 │ 0 │ 8 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Multiplication of **** Array to DataFrame along axis 0 +### Multiplication of Array **with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -198,7 +191,6 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -245,8 +237,6 @@ df.print() ║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.ne.md b/api-reference/dataframe/danfo.dataframe.ne.md index dd45cf0..36ab6e2 100644 --- a/api-reference/dataframe/danfo.dataframe.ne.md +++ b/api-reference/dataframe/danfo.dataframe.ne.md @@ -4,20 +4,20 @@ description: Get Not Equal to of DataFrame and other, element-wise (binary opera # DataFrame.ne -danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.ne(other, options) | Parameters | Type | Description | Default | | ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | | other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | +| options | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | **Returns:** -**** +*** ## **Examples** -### Comparing **** DataFrame with a scalar value: +### Comparing a DataFrame with a scalar value: {% tabs %} {% tab title="Node" %} @@ -58,7 +58,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a Series along the column axis: +### Comparing a DataFrame with a Series along the column axis: {% tabs %} {% tab title="Node" %} @@ -74,7 +74,6 @@ let df_rep = df.ne(sf, {axis:1}) df_rep.print() - ``` {% endtab %} @@ -102,7 +101,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a DataFrame +### Comparing a DataFrame with a DataFrame {% tabs %} {% tab title="Node" %} @@ -120,7 +119,6 @@ let df2 = new dfd.DataFrame(data2) let df_rep = df.ne(df2) df_rep.print() - ``` {% endtab %} @@ -148,7 +146,7 @@ df_rep.print() {% endtab %} {% endtabs %} -### Comparing **** DataFrame with a JavaScript Array +### Comparing a DataFrame with a JavaScript Array {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index e6f1e6c..8a1bae7 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -6,16 +6,12 @@ description: >- # DataFrame.pow -danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.pow(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to raised to power with | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | ## **Examples** @@ -60,12 +56,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Exponential of **Series with** DataFrame along axis 0 +### Exponential of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -108,12 +103,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Exponential of **** DataFrame with a DataFrame +### Exponential of DataFrame with another DataFrame {% tabs %} {% tab title="Node" %} @@ -132,7 +126,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.pow(df2) df_new.print() - ``` {% endtab %} @@ -158,12 +151,11 @@ df_new.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Exponential of **** Array with DataFrame along axis 0 +### Exponential of Array with DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -205,7 +197,6 @@ df_new.print() ║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -253,8 +244,6 @@ df.print() ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.query.md b/api-reference/dataframe/danfo.dataframe.query.md index 129c8e7..2d43b1e 100644 --- a/api-reference/dataframe/danfo.dataframe.query.md +++ b/api-reference/dataframe/danfo.dataframe.query.md @@ -1,20 +1,14 @@ --- -description: >- - Query the DataFrame by the result of a logical comparison or boolean mask. - Supports logical operations like (">", "<", ">=", "<=", and. "==") +description: Query the DataFrame by the result of a logical comparison or boolean mask. --- # DataFrame.query -danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] +danfo.DataFrame.**query**(kwargs) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | - -**Returns:** - - **** return **new DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true

|

false. Whether to perform operation to the original Object or create a new one.

}

| ## **Examples** @@ -25,14 +19,16 @@ Querying by a boolean condition is supported from v0.3.0 and above. {% endhint %} ```javascript +const dfd = require("danfojs-node") + let data = { "A": ["Ng", "Yu", "Mo", "Ng"], "B": [34, 4, 5, 6], "C": [20, 20, 30, 40] } let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5) }) +df.print() +let query_df = df.query(df["B"].gt(5)) query_df.print() //after query ``` @@ -40,38 +36,69 @@ query_df.print() //after query ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ +║ 0 │ Ng │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ +║ 3 │ Ng │ 6 │ 40 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: +It also supports condition chaining as long as the final boolean mask is the same length as the DataFrame rows. For example in the following code, we use multiple chaining conditions: ```javascript +const dfd = require("danfojs-node") + let data = { "A": ["Ng", "Yu", "Mo", "Ng"], "B": [34, 4, 5, 6], "C": [20, 20, 30, 40] } let df = new dfd.DataFrame(data) +df.print() -let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) +let query_df = df.query(df["B"].gt(5).and(df["C"].lt(40))) query_df.print() //after query +``` -//output +``` +// output ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 0 │ Ng │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ Yu │ 4 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ Mo │ 5 │ 30 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ Ng │ 6 │ 40 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ Ng │ 34 │ 20 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` ## **Query a DataFrame using logical operators** -To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. +{% hint style="info" %} +This is only supported in older versions. That is versions lower than v1.0.0 +{% endhint %} + +To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. {% tabs %} {% tab title="Node" %} @@ -125,59 +152,13 @@ query_df.print() //after query {% endtab %} {% endtabs %} -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - ## **Query by a string column in a DataFrame** -The query method also works on string columns. +{% hint style="info" %} +This is only supported in older versions. That is versions lower than v1.0.0 +{% endhint %} + +The query method also works on string columns. {% tabs %} {% tab title="Node" %} @@ -193,7 +174,6 @@ df.print() let query_df = df.query({ column: "A", is: "==", to: "Ng"}) query_df.print() //after query - ``` {% endtab %} @@ -206,7 +186,6 @@ query_df.print() //after query {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -231,48 +210,3 @@ query_df.print() //after query ``` {% endtab %} {% endtabs %} - -## **Query a DataFrame inplace** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.query({ - column: "B", - is: ">", - to: 5, - inplace: true -}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.replace.md b/api-reference/dataframe/danfo.dataframe.replace.md index 82fa16d..ff4b3db 100644 --- a/api-reference/dataframe/danfo.dataframe.replace.md +++ b/api-reference/dataframe/danfo.dataframe.replace.md @@ -4,19 +4,13 @@ description: Replaces values in a DataFrame with specified values # DataFrame.replace -> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] +> danfo.DataFrame.**replace**(oldValue, newValue, options) -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| oldValue | String, boolean, Number | The value you want to replace | | -| newValue | String, boolean, Number | The new value you want to replace the old value with | | -| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -**** +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| oldValue | String, boolean, Number | The value you want to replace | | +| newValue | String, boolean, Number | The new value you want to replace the old value with | | +| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | ## **Examples** @@ -63,7 +57,7 @@ df_rep.print() {% endtab %} {% endtabs %} -By not specifying a **** column**,** the **** replace works on all columns **** +If a column name is not specified, **replace** works on all columns: {% tabs %} {% tab title="Node" %} @@ -76,7 +70,6 @@ let df = new dfd.DataFrame(data) let df_rep = df.replace("A", "BOY") df_rep.print() - ``` {% endtab %} @@ -89,7 +82,6 @@ df_rep.print() {% tabs %} {% tab title="Output" %} ```javascript - ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/danfo.dataframe.round.md b/api-reference/dataframe/danfo.dataframe.round.md index e12cb52..43a0222 100644 --- a/api-reference/dataframe/danfo.dataframe.round.md +++ b/api-reference/dataframe/danfo.dataframe.round.md @@ -4,17 +4,13 @@ description: Round elements in a DataFrame to a specified number of decimal plac # DataFrame.round -danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**round**(options) | Parameters | Type | Description | Default | | ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | | dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | | options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | -**Returns:** - - **** return **DataFrame** - ## **Examples** ## Round elements to 1dp (Default) @@ -24,8 +20,8 @@ danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/d ```javascript const dfd = require("danfojs-node") -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] +let data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] +let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() diff --git a/api-reference/dataframe/danfo.dataframe.sample.md b/api-reference/dataframe/danfo.dataframe.sample.md index b8a4c96..a7e8869 100644 --- a/api-reference/dataframe/danfo.dataframe.sample.md +++ b/api-reference/dataframe/danfo.dataframe.sample.md @@ -4,18 +4,12 @@ description: Return a random sample of rows from DataFrame. # DataFrame.sample -danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] +danfo.DataFrame.**sample**(num, options) -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | - -**Returns:** - - **** return **{Promies} resolves to DataFrame** - -**** +| Parameters | Type | Description | Default | +| ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| num | Integer | The number of rows to return. Defaults to 5, which shuffles and return all rows. | 5 | +| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | { seed: 1 } | ## Sample a DataFrame randomly @@ -24,20 +18,20 @@ danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9j ```javascript const dfd = require("danfojs-node") -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(2); - s_df.print(); - +async function sample_data() { + let data = { + Name: ["Apples", "Mango", "Banana", "Pear"], + Count: [21, 5, 30, 10], + Price: [200, 300, 40, 250], + }; + + let df = new dfd.DataFrame(data); + let s_df = await df.sample(2); + s_df.print(); + } -load_data() +sample_data() ``` {% endtab %} @@ -63,7 +57,7 @@ load_data() ## Sample a DataFrame randomly with seed -By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. +By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. {% tabs %} {% tab title="Node" %} @@ -106,7 +100,6 @@ load_data() ║ 0 │ Apples │ 21 │ 200 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.std.md b/api-reference/dataframe/danfo.dataframe.std.md index 1a37e2e..47169a5 100644 --- a/api-reference/dataframe/danfo.dataframe.std.md +++ b/api-reference/dataframe/danfo.dataframe.std.md @@ -4,16 +4,12 @@ description: Return sample standard deviation over requested axis. # DataFrame.std -danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**std**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** ## Calculates the standard deviation of values along default axis 1 (column) @@ -22,10 +18,10 @@ danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/dan {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let df = new dfd.DataFrame(data, { columns: cols }) df.std().print() ``` {% endtab %} @@ -39,15 +35,15 @@ df.std().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4.69041575982343 ║ -╟───┼──────────────────────╢ -║ 1 │ 34.23935357645254 ║ -╟───┼──────────────────────╢ -║ 2 │ 35.103418636936205 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════╗ +║ 0 │ 8.504900548115383 ║ +╟───┼────────────────────╢ +║ 1 │ 7.094598884597588 ║ +╟───┼────────────────────╢ +║ 2 │ 19.697715603592208 ║ +╟───┼────────────────────╢ +║ 3 │ 47.37439533475159 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -91,4 +87,3 @@ df.std({axis:0}).print() {% endtabs %} ## - diff --git a/api-reference/dataframe/danfo.dataframe.sub.md b/api-reference/dataframe/danfo.dataframe.sub.md index e36ddcc..9f53957 100644 --- a/api-reference/dataframe/danfo.dataframe.sub.md +++ b/api-reference/dataframe/danfo.dataframe.sub.md @@ -4,20 +4,16 @@ description: Get Subtraction of dataframe and other, element-wise (binary operat # DataFrame.sub -danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] +danfo.DataFrame.sub(other, option) -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to subtract | | +| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | ## **Examples** -### Subtraction of **scalar to** DataFrame along default axis 1 +### Subtraction of **scalar from** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -60,7 +56,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Subtraction of **Series to** DataFrame along axis 0 +### Subtraction of **Series from** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -101,12 +97,11 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ -3 │ -1 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Subtraction of **** DataFrame to a DataFrame +### Subtraction of DataFrame from another DataFrame {% tabs %} {% tab title="Node" %} @@ -125,7 +120,6 @@ let df2 = new dfd.DataFrame(data2) let df_new = df.sub(df2) df_new.print() - ``` {% endtab %} @@ -149,12 +143,11 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ -10 │ 2 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -### Subtraction of **** Array to DataFrame along axis 0 +### Subtraction of Array from DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -196,7 +189,6 @@ df_new.print() ║ 3 │ 8 │ 22 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -243,8 +235,6 @@ df.print() ║ 3 │ 8 │ 22 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/dataframe/danfo.dataframe.sum.md b/api-reference/dataframe/danfo.dataframe.sum.md index 3937d3f..46ac59f 100644 --- a/api-reference/dataframe/danfo.dataframe.sum.md +++ b/api-reference/dataframe/danfo.dataframe.sum.md @@ -4,19 +4,15 @@ description: Return the sum of the values for the requested axis. # DataFrame.sum -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**sum**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** -## Sum elements along default axis (column) +## Sum elements along default axis 1 (column) {% tabs %} {% tab title="Node" %} @@ -55,13 +51,15 @@ df_sum.print() ║ 3 │ -20 │ 6 │ -40 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤════════════════════╗ -║ A │ 37.199999999999996 ║ -╟───┼────────────────────╢ -║ B │ 41 ║ -╟───┼────────────────────╢ -║ C │ -10 ║ -╚═══╧════════════════════╝ +╔═══╤══════╗ +║ 0 │ 33.9 ║ +╟───┼──────╢ +║ 1 │ 6 ║ +╟───┼──────╢ +║ 2 │ 82.3 ║ +╟───┼──────╢ +║ 3 │ -54 ║ +╚═══╧══════╝ ``` {% endtab %} {% endtabs %} @@ -105,17 +103,13 @@ df_sum.print() ║ 3 │ -20 │ 6 │ -40 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ sum ║ -╟───┼──────────────────────╢ -║ 0 │ 33.9 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 82.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -54 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════╗ +║ A │ 37.199999999999996 ║ +╟───┼────────────────────╢ +║ B │ 41 ║ +╟───┼────────────────────╢ +║ C │ -10 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.tail.md b/api-reference/dataframe/danfo.dataframe.tail.md index 165acac..0913390 100644 --- a/api-reference/dataframe/danfo.dataframe.tail.md +++ b/api-reference/dataframe/danfo.dataframe.tail.md @@ -4,16 +4,12 @@ description: Returns the last n rows from the DataFrame based on position. # DataFrame.tail -danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] +danfo.DataFrame.**tail**(rows) | Parameters | Type | Description | Default | | ---------- | ---- | ---------------------------- | ------- | | rows | Int | The number of rows to return | 5 | -**Returns:** - - **** return **DataFrame** - ## **Examples** {% tabs %} @@ -28,7 +24,6 @@ let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], let df = new dfd.DataFrame(data) let s_df = df.tail(3) s_df.print() - ``` {% endtab %} diff --git a/api-reference/dataframe/danfo.dataframe.var.md b/api-reference/dataframe/danfo.dataframe.var.md index ea0daf2..e84331b 100644 --- a/api-reference/dataframe/danfo.dataframe.var.md +++ b/api-reference/dataframe/danfo.dataframe.var.md @@ -4,28 +4,26 @@ description: Return unbiased variance over requested axis. # DataFrame.var -danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] +danfo.DataFrame.**var**(options) | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | | options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | -**Returns:** - - **** return **Series** - ## **Examples** -## Calculate variance of values along default axis 1 (column) +## Computes the variance of values along default axis 1 (column) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() df.var().print() ``` {% endtab %} @@ -39,30 +37,44 @@ df.var().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 22 ║ -╟───┼──────────────────────╢ -║ 1 │ 1172.3333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 1232.25 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤═══════════════════╗ +║ 0 │ 72.33333333333334 ║ +╟───┼───────────────────╢ +║ 1 │ 50.33333333333333 ║ +╟───┼───────────────────╢ +║ 2 │ 388 ║ +╟───┼───────────────────╢ +║ 3 │ 2244.333333333333 ║ +╚═══╧═══════════════════╝ ``` {% endtab %} {% endtabs %} -## Calculate variance of values along row axis (0) +## Computes the variance of values along row axis (0) {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data) -df.var({axis:0}).print() +let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] +let cols = ["A", "B", "C"] + +let df = new dfd.DataFrame(data, { columns: cols }) +df.print() +df.var({ axis: 0 }).print() ``` {% endtab %} @@ -75,20 +87,25 @@ df.var({axis:0}).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 72.33333333333334 ║ -╟───┼──────────────────────╢ -║ 1 │ 50.33333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 388 ║ -╟───┼──────────────────────╢ -║ 3 │ 2244.333333333333 ║ -╚═══╧══════════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 11 │ 20 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1 │ 15 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 2 │ 89 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔═══╤════════════════════╗ +║ A │ 22 ║ +╟───┼────────────────────╢ +║ B │ 1172.3333333333333 ║ +╟───┼────────────────────╢ +║ C │ 1232.25 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} - - - diff --git a/api-reference/dataframe/dataframe.append.md b/api-reference/dataframe/dataframe.append.md index bc2e29d..b8bc62e 100644 --- a/api-reference/dataframe/dataframe.append.md +++ b/api-reference/dataframe/dataframe.append.md @@ -4,17 +4,13 @@ description: Adds new row to the end of a DataFrame # DataFrame.append -danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] +danfo.DataFrame.**append**(values, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | -| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | +| values | Array, Series or DataFrame | Value to append to the DataFrame | | +| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | +| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| ## **Examples** @@ -32,7 +28,6 @@ df.print() let new_df = df.append([[20, 40, 60, "d"]], [3]) new_df.print() - ``` {% endtab %} @@ -56,8 +51,6 @@ new_df.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - Shape: (4,4) - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -73,4 +66,4 @@ new_df.print() {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/dataframe/dataframe.apply_map.md b/api-reference/dataframe/dataframe.apply_map.md index 3819821..55a622c 100644 --- a/api-reference/dataframe/dataframe.apply_map.md +++ b/api-reference/dataframe/dataframe.apply_map.md @@ -2,25 +2,21 @@ description: Apply a function to a Dataframe values element-wise. --- -# DataFrame.apply\_map +# DataFrame.applyMap -danfo.DataFrame.**apply\_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] +danfo.DataFrame.applyMap(callable, options) | Parameters | Type | Description | Default | | ---------- | -------- | --------------------------------------------------------------------- | --------- | | callable | Function | Function to apply to each column or row | | | options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | -**Returns:** - - **** return **DataFrame** - ## **Examples** -### Apply a function to all values in a DataFrame +### Apply a function to each element in a DataFrame {% hint style="info" %} -Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. +Note that the specified function passed to **applyMap** will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. {% endhint %} {% tabs %} diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index e6434dc..45adf39 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -2,17 +2,13 @@ description: Cast column of a DataFrame to a specified dtype. --- -# DataFrame.astype +# DataFrame.asType -danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.asType(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | ## **Examples** @@ -32,7 +28,7 @@ let df = new dfd.DataFrame(data) df.print() df.ctypes.print() -let df_new = df.astype({column: "A", dtype: "int32"}) +let df_new = df.asType("A", "int32") df_new.print() df.ctypes.print() @@ -116,12 +112,11 @@ let data = { "A": [-20.1, 30, 47.3, -20] , "D": ["20", "13", "45", "90"] } let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) +let df_new = df.asType("D", "int32") df_new.print() df_new.ctypes.print() - ``` {% endtab %} @@ -146,18 +141,15 @@ df_new.ctypes.print() ║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ - +╔═══╤═════════╗ +║ A │ float32 ║ +╟───┼─────────╢ +║ B │ int32 ║ +╟───┼─────────╢ +║ C │ float32 ║ +╟───┼─────────╢ +║ D │ int32 ║ +╚═══╧═════════╝ ``` {% endtab %} {% endtabs %} @@ -175,12 +167,11 @@ let data = { "A": [-20.1, 30, 47.3, -20] , "D": ["a", "b", "c", "c"] } let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) +let df_new = df.asType("D","int32") df_new.print() df_new.ctypes.print() - ``` {% endtab %} @@ -193,7 +184,6 @@ df_new.ctypes.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -206,17 +196,15 @@ df_new.ctypes.print() ║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ A │ float32 ║ +╟───┼─────────╢ +║ B │ int32 ║ +╟───┼─────────╢ +║ C │ float32 ║ +╟───┼─────────╢ +║ D │ int32 ║ +╚═══╧═════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/dataframe.axes.md b/api-reference/dataframe/dataframe.axes.md index 399a0a4..388d0cb 100644 --- a/api-reference/dataframe/dataframe.axes.md +++ b/api-reference/dataframe/dataframe.axes.md @@ -1,17 +1,12 @@ --- description: >- - Return an Object containing the axes of the DataFrame. It has the row axis - labels and column axis labels as the only members. They are returned in that - order. + Return an Object containing the axis of the DataFrame. It has the row axis + labels and column axis labels as the only members. --- # DataFrame.axis -danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Object** +danfo.DataFrame.**axis** ## **Examples** @@ -28,7 +23,6 @@ let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) console.log(df.axis) - ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.drop.md b/api-reference/dataframe/dataframe.drop.md index 0b742aa..3ea14a2 100644 --- a/api-reference/dataframe/dataframe.drop.md +++ b/api-reference/dataframe/dataframe.drop.md @@ -6,21 +6,21 @@ description: >- # DataFrame.drop -danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**drop**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | +| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {\*\*inplace:\*\*false} | **Returns:** - **** return **DataFrame** +\*\*\*\* return **DataFrame** ## **Examples** ### Drop columns by specifying the names -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} @@ -79,7 +79,6 @@ let data = { let df = new dfd.DataFrame(data) df.drop({ index: [0, 2], inplace: true }); df.print() - ``` {% endtab %} @@ -118,7 +117,6 @@ let data = { "A": [-20, 30, 47.3, -20], let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) df.drop({ index: ["a", "c"], inplace: true }); df.print() - ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.dtypes.md b/api-reference/dataframe/dataframe.dtypes.md index 791d296..489e570 100644 --- a/api-reference/dataframe/dataframe.dtypes.md +++ b/api-reference/dataframe/dataframe.dtypes.md @@ -7,15 +7,11 @@ description: >- # DataFrame.ctypes -danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] - -**Returns:** - - **** return **Series** +danfo.DataFrame.**dtypes** ## **Examples** -Returns auto-generated **** index of a **** DataFrame +Returns auto-generated index of a DataFrame {% tabs %} {% tab title="Node" %} @@ -59,7 +55,6 @@ Columns with mixed types are represented as **string.** {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = {"A": [-20.1, 30, 47.3, -20], @@ -97,4 +92,4 @@ df.ctypes.print() {% endtab %} {% endtabs %} -**Note**: To cast a type, use the [astype](dataframe.astype.md) method. +**Note**: To cast a type, use the [asType](dataframe.astype.md) method. diff --git a/api-reference/dataframe/dataframe.index.md b/api-reference/dataframe/dataframe.index.md index a185e63..d38c7b5 100644 --- a/api-reference/dataframe/dataframe.index.md +++ b/api-reference/dataframe/dataframe.index.md @@ -4,11 +4,11 @@ description: The index (row labels) of the DataFrame. # DataFrame.index -danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] +danfo.DataFrame.**index** ## **Examples** -Returns auto-generated **** index of a **** DataFrame +Returns auto-generated index of a DataFrame {% tabs %} {% tab title="Node" %} @@ -38,8 +38,6 @@ console.log(df.index); {% endtab %} {% endtabs %} - - {% tabs %} {% tab title="Node" %} ```javascript diff --git a/api-reference/dataframe/dataframe.ndim.md b/api-reference/dataframe/dataframe.ndim.md index c64dd09..d35bfb9 100644 --- a/api-reference/dataframe/dataframe.ndim.md +++ b/api-reference/dataframe/dataframe.ndim.md @@ -1,16 +1,12 @@ --- description: >- - Return an int representing the number of axes / array dimensions. Returns 1 if - Series. Otherwise return 2 for DataFrame. + Return an integer representing the number of dimensions. Returns 1 if Series. + Otherwise return 2 for DataFrame. --- # DataFrame.ndim -danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** +danfo.DataFrame.**ndim** **Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. @@ -27,7 +23,6 @@ let data = {"A": [-20.1, 30, 47.3, -20], let df = new dfd.DataFrame(data) console.log(df.ndim) - ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.nunique-1.md b/api-reference/dataframe/dataframe.nunique-1.md index 8166904..177b0ec 100644 --- a/api-reference/dataframe/dataframe.nunique-1.md +++ b/api-reference/dataframe/dataframe.nunique-1.md @@ -1,18 +1,18 @@ -# DataFrame.nunique +--- +description: Returns the number of unique elements in a column, across the specified axis. +--- -danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] +# DataFrame.nUnique -| Parameters | Type | Description | Default | -| ---------- | ---- | -------------------------------------- | ------- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | +danfo.DataFrame.nUnique(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] -**Returns:** - - **** return **Series** +| Parameters | Type | Description | Default | +| ---------- | ---- | ------------------------------------- | ------- | +| axis | Int | 0 for row axis, and 1 for column axis | 1 | ## **Examples** -### Return number of unique values along column axis (axis=1) +### Return number of unique values along default axis (axis=1) {% tabs %} {% tab title="Node" %} @@ -26,7 +26,6 @@ let data = { "A": [-20, 30, 47.3, -20] , let df = new dfd.DataFrame(data) df.nunique().print() - ``` {% endtab %} @@ -40,15 +39,14 @@ df.nunique().print() {% tab title="Output" %} ``` ╔═══╤═══╗ -║ 0 │ 3 ║ +║ 0 │ 4 ║ ╟───┼───╢ ║ 1 │ 4 ║ ╟───┼───╢ -║ 2 │ 2 ║ +║ 2 │ 4 ║ ╟───┼───╢ -║ 3 │ 3 ║ +║ 3 │ 4 ║ ╚═══╧═══╝ - ``` {% endtab %} {% endtabs %} @@ -66,8 +64,7 @@ let data = { "A": [-20, 30, 47.3, -20] , "D": ["a", "b", "c", "c"] } let df = new dfd.DataFrame(data) -df.nunique(axis=0).print() - +df.nUnique(axis=0).print() ``` {% endtab %} @@ -80,19 +77,17 @@ df.nunique(axis=0).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ A │ 3 ║ +╟───┼───╢ +║ B │ 4 ║ +╟───┼───╢ +║ C │ 2 ║ +╟───┼───╢ +║ D │ 3 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} -**Note:** To get the unique elements along an axis, use **** [DataFrame.unique.](dataframe.nunique-1.md) +**Note:** To get the unique elements along an axis, see [DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference/dataframe/dataframe.print.md b/api-reference/dataframe/dataframe.print.md index d03232d..be750a9 100644 --- a/api-reference/dataframe/dataframe.print.md +++ b/api-reference/dataframe/dataframe.print.md @@ -6,7 +6,7 @@ description: >- # DataFrame.print -danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] +danfo.DataFrame.**print()** ## **Examples** @@ -34,7 +34,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Abs │ Count │ country code ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -77,28 +76,29 @@ console.log(String(df)); {% tab title="Output" %} ``` DataFrame { + '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 4, 5 ], [ 'NG', 'FR', 'GH' ] ], + '$index': [ 0, 1, 2 ], + '$columns': [ 'Abs', 'Count', 'country code' ], + '$dtypes': [ 'float32', 'int32', 'string' ], '$isSeries': false, '$config': Configs { tableDisplayConfig: {}, tableMaxRow: 10, - tableMaxColInConsole: 21, - dtypeTestLim: 7, + tableMaxColInConsole: 10, + dtypeTestLim: 20, lowMemoryMode: false }, - '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], - '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], - '$index': [ 0, 1, 2 ], - '$dtypes': [ 'float32', 'int32', 'string' ], - '$columns': [ 'Abs', 'Count', 'country code' ] + '$data': [ [ 20.2, 34, 'NG' ], [ 30, 4, 'FR' ], [ 47.3, 5, 'GH' ] ] } + ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Abs │ Count │ country code ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 0 │ 20.2 │ 34 │ NG ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ FR ║ +║ 1 │ 30 │ 4 │ FR ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ GH ║ +║ 2 │ 47.3 │ 5 │ GH ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.rename.md b/api-reference/dataframe/dataframe.rename.md index c33ce99..fae6861 100644 --- a/api-reference/dataframe/dataframe.rename.md +++ b/api-reference/dataframe/dataframe.rename.md @@ -1,40 +1,39 @@ --- description: >- - Change axes labels. Object values must be unique (1-to-1). Labels not + Change axis labels. Object values must be unique (1-to-1). Labels not contained in a dict / Series will be left as-is. Extra labels listed don’t throw an error. --- # DataFrame.rename -danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**rename**(mapper, options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| **mapper** | Object | **L**abels and transformations to apply to that axis’ values. | | +| **options** | Object |

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

axis : 1,

inplace : false

}

| ## **Examples** -### Rename columns +### Rename columns -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. +By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5], - "C": [20, 2, 30] } +let data = { + "A": [-20, 30, 47.3], + "B": [34, -4, 5], + "C": [20, 2, 30] +} let df = new dfd.DataFrame(data) -df.rename({ mapper: {"A": "new_name"},inplace: true }) +df.rename({ "A": "new_name" }, { inplace: true }) df.print() ``` {% endtab %} @@ -48,15 +47,15 @@ df.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ new_name │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -20 │ 34 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 30 │ -4 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 47.3 │ 5 │ 30 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} @@ -74,9 +73,9 @@ let data = { "A": [-20, 30, 47.3], let df = new dfd.DataFrame(data) -df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) -df.print() +df = df.rename({ A: "new_name", C: "new_c" }) +df.print() ``` {% endtab %} @@ -89,7 +88,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ new_name │ B │ new_c ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -118,9 +116,8 @@ let data = { let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df = df.rename({ mapper: { "a": 0 }, axis: 0 }) +df = df.rename({ "a": 0 }, { axis: 0 }) df.print() - ``` {% endtab %} @@ -133,7 +130,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ diff --git a/api-reference/dataframe/dataframe.reset_index.md b/api-reference/dataframe/dataframe.reset_index.md index ddee8e0..410842c 100644 --- a/api-reference/dataframe/dataframe.reset_index.md +++ b/api-reference/dataframe/dataframe.reset_index.md @@ -1,18 +1,18 @@ --- -description: Reset the index of the DataFrame, and use the default one instead. +description: Resets the index of the DataFrame, and use the default one instead. --- -# DataFrame.reset\_index +# DataFrame.resetIndex -danfo.DataFrame.**reset\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.resetIndex(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | +| options | Object |

{

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { **inplace**: false} | **Returns:** - **** return **DataFrame** +\*\*\*\* return **DataFrame** ## **Examples** @@ -31,8 +31,8 @@ let data = { let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) df.print() -df.reset_index({ inplace: true }) //inplace -//df = df.reset_index() //not in inplace +df.resetIndex({ inplace: true }) //inplace +//df = df.resetIndex() //not in inplace df.print() ``` @@ -47,7 +47,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -67,7 +66,6 @@ df.print() ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 2 │ 47.3 │ 6 │ 30 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/dataframe.select_dtypes.md b/api-reference/dataframe/dataframe.select_dtypes.md index ba5044e..0623ca7 100644 --- a/api-reference/dataframe/dataframe.select_dtypes.md +++ b/api-reference/dataframe/dataframe.select_dtypes.md @@ -2,17 +2,13 @@ description: Return a subset of the DataFrame’s columns based on the column dtypes. --- -# DataFrame.select\_dtypes +# DataFrame.selectDtypes -danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] +danfo.DataFrame.selectDtypes() -| Parameters | Type | Description | Default | -| ---------- | ----- | -------------------------------- | ------- | -| include | Array | List of column dtypes to return | | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ----- | ------------------------------- | ------- | +| include | Array | List of column dtypes to return | | ## **Examples** @@ -28,15 +24,15 @@ let data = {"A": [-20.1, 30, 47.3, -20], let df = new dfd.DataFrame(data) -float_df = df.select_dtypes(['float32']) + +float_df = df.selectDtypes(['float32']) float_df.print() -mix_df = df.select_dtypes(include=['float32', "int32"]) +mix_df = df.selectDtypes(['float32', "int32"]) mix_df.print() -str_df = df.select_dtypes(include=['string']) +str_df = df.selectDtypes(['string']) str_df.print() - ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.set_index.md b/api-reference/dataframe/dataframe.set_index.md index e82c213..4ff9b50 100644 --- a/api-reference/dataframe/dataframe.set_index.md +++ b/api-reference/dataframe/dataframe.set_index.md @@ -4,13 +4,13 @@ description: >- length). --- -# DataFrame.set_index +# DataFrame.setIndex -danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.setIndex(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, \*\*inplace:\*\*false} | ## **Examples** @@ -29,7 +29,7 @@ let data = { "A": [-20, 30, 47.3], let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) df.print() -df.set_index({column: "A", inplace: true}) +df.setIndex({column: "A", inplace: true}) df.print() ``` {% endtab %} @@ -66,8 +66,6 @@ df.print() {% endtab %} {% endtabs %} -### **** - ### **Setting index to a column in the DataFrame and dropping the column** {% tabs %} @@ -83,7 +81,7 @@ let data = { "A": [-20, 30, 47.3], let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) df.print() -df.set_index({column: "A", drop: true, inplace: true}) +df.setIndex({column: "A", drop: true, inplace: true}) df.print() ``` {% endtab %} @@ -136,7 +134,7 @@ let df = new dfd.DataFrame(data) df.print() let new_index = ["a", "b", "c"] -df.set_index({index: new_index, inplace: true}) +df.setIndex({index: new_index, inplace: true}) df.print() ``` {% endtab %} @@ -173,4 +171,4 @@ df.print() {% endtab %} {% endtabs %} -**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). +**Note:** To reset an index to the default values, use the [DataFrame.resetIndex](dataframe.reset\_index.md). diff --git a/api-reference/dataframe/dataframe.shape.md b/api-reference/dataframe/dataframe.shape.md index 746491d..e773461 100644 --- a/api-reference/dataframe/dataframe.shape.md +++ b/api-reference/dataframe/dataframe.shape.md @@ -4,11 +4,7 @@ description: Returns an Array representing the dimensionality of the DataFrame. # DataFrame.shape -danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** +danfo.DataFrame.**shape** ## **Examples** @@ -24,7 +20,6 @@ let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) console.log(df.shape) - ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.sort_index.md b/api-reference/dataframe/dataframe.sort_index.md index 81d5b7f..9d867c0 100644 --- a/api-reference/dataframe/dataframe.sort_index.md +++ b/api-reference/dataframe/dataframe.sort_index.md @@ -2,17 +2,17 @@ description: Sort DataFrame by index --- -# DataFrame.sort\_index +# DataFrame.sortIndex -DataFrame.**sort\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] +DataFrame.sortIndex(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, \*\*inplace:\*\*false} | **Returns:** - **** return **DataFrame** +\*\*\*\* return **DataFrame** ## **Examples** @@ -31,7 +31,7 @@ let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], index: ["b", "a", "c"] }) df.print() -let df2 = df.sort_index({ ascending: false }) +let df2 = df.sortIndex({ ascending: false }) df2.print() ``` {% endtab %} @@ -71,4 +71,4 @@ df2.print() {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 54345b1..9aedc7b 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -2,17 +2,14 @@ description: Sort a Dataframe in ascending or descending order by a specified column name. --- -# DataFrame.sort\_values +# DataFrame.sortValues -danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +danfo.DataFrame.**sortValues**(by, options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | +| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| ## **Examples** @@ -23,13 +20,15 @@ danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensourc ```javascript const dfd = require("danfojs-node") -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } +let data = { + "A": [-20, 30, 47.3], + "B": [34, 5, 6], + "C": [20, 3, 30] +} let df = new dfd.DataFrame(data) -df.sort_values({by: "C", inplace: true}) +df.sortValues("C", { inplace: true }) df.print() ``` {% endtab %} @@ -43,7 +42,6 @@ df.print() {% tabs %} {% tab title="Output" %} ``` - ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -62,7 +60,6 @@ df.print() {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") let data = { "A": [-20, 30, 47.3], @@ -70,8 +67,9 @@ let data = { "A": [-20, 30, 47.3], "C": [20, 3, 30] } + let df = new dfd.DataFrame(data) -df.sort_values({by: "B", inplace: true, ascending: false}) +df.sortValues("C", { ascending: false, inplace: true }) df.print() ``` {% endtab %} diff --git a/api-reference/dataframe/dataframe.tensor.md b/api-reference/dataframe/dataframe.tensor.md index 822886e..3a3eea6 100644 --- a/api-reference/dataframe/dataframe.tensor.md +++ b/api-reference/dataframe/dataframe.tensor.md @@ -1,18 +1,14 @@ --- description: >- - Return a Tensorflow tensor representation of the DataFrame. Only the values in - the DataFrame will be returned, the axes labels will be removed. + Return a Tensorflow tensor of the DataFrame. Only the values in the DataFrame + will be returned, the axis labels will be removed. --- # DataFrame.tensor -danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] +danfo.DataFrame.**tensor** -**Returns:** - - **** return **tf.tensor** - -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. +> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. ## **Examples** @@ -46,6 +42,19 @@ tf_tensor.print() {% tab title="Output" %} ``` float32 + +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 4, 3 ], + dtype: 'float32', + size: 12, + strides: [ 3 ], + dataId: {}, + id: 0, + rankType: '2' +} + Tensor [[-20 , 34, 20], [30 , -4, 20], @@ -55,7 +64,7 @@ Tensor {% endtab %} {% endtabs %} -String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. +String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 8e84e9a..504cbcc 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -1,17 +1,17 @@ --- -description: Convert DataFrame data to a comma-separated values (csv) +description: Convert DataFrame to a comma-separated values (CSV) --- -# DataFrame.to\_csv +# DataFrame.toCSV -DataFrame.**to\_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] +DataFrame.toCSV(options) -| | | | | -| -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| +| | | | | +| -------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

|

{
sep: ","
}

| -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. +The **toCSV** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. *** @@ -30,7 +30,7 @@ let data = { let df = new dfd.DataFrame(data); -const csv = df.to_csv({ download: false }); +const csv = df.toCSV(); console.log(csv); //output @@ -75,7 +75,7 @@ Abs,Count,country code {% endtab %} {% endtabs %} -### Convert DataFrame to CSV string and write to file path +### Convert DataFrame to CSV and write to local file path Writing a CSV file to a local file path is only supported in the Nodejs environment @@ -91,13 +91,12 @@ let data = { }; let df = new dfd.DataFrame(data); - -df.to_csv({ filePath: "testOut.csv"}); + df.toCSV({ filePath: "testOut.csv"}); ``` {% endtab %} {% endtabs %} -### Convert DataFrame to CSV string and download file in browser +### Convert DataFrame to CSV and download file in browser You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. @@ -110,5 +109,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_csv({ fileName: "testOut.csv", download: true}); +df.toCSV({ fileName: "testOut.csv", download: true}); ``` diff --git a/api-reference/dataframe/dataframe.to_excel.md b/api-reference/dataframe/dataframe.to_excel.md index 4adf437..38f6abb 100644 --- a/api-reference/dataframe/dataframe.to_excel.md +++ b/api-reference/dataframe/dataframe.to_excel.md @@ -4,15 +4,15 @@ description: >- download in browser. --- -# DataFrame.to_excel +# DataFrame.toExcel -> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] +> DataFrame.toExcel(options) -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| +| **Parameters** | Type | Description | Default | +| -------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in the browser environment.


sheetName: Name to call the excel sheet.

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. +The **toExcel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. ### Convert DataFrame to Excel and write to file path @@ -31,14 +31,14 @@ let data = { let df = new dfd.DataFrame(data); -df.to_excel({ filePath: "testOut.xlsx"}); +df.toExcel({ filePath: "testOut.xlsx"}); ``` {% endtab %} {% endtabs %} ### Convert DataFrame to Excel and download the file in a browser -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. +You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. ```javascript let data = { @@ -49,5 +49,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_excel({ fileName: "testOut.xlsx"}); +df.toExcel({ fileName: "testOut.xlsx", download: true }); ``` diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 326f422..b1f043a 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -2,16 +2,16 @@ description: Convert DataFrame to JSON format --- -# DataFrame.to\_json +# DataFrame.toJSON -> DataFrame.**to\_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] +> DataFrame.toJSON(options) -| | | | | -| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| +| | | | | +| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


format: The format of the JSON. Can be one of row or column.

|

{
format: "column"
}

| -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. +The **toJSON** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. ### Convert DataFrame/Series to JSON and return value @@ -28,7 +28,7 @@ let data = { let df = new dfd.DataFrame(data); -const jsonObj = df.to_json({ download: false }); //column format +const jsonObj = df.toJSON(); //defaults to column format console.log(jsonObj); //output @@ -39,12 +39,12 @@ console.log(jsonObj); ] //row format -const jsonObj = df.to_json({ - download: false, +const jsonObjRow = df.toJSON({ format: "row" }); + -console.log(jsonObj); +console.log(jsonObjRow); //output { Abs: [ 20.2, 30, 47.3 ], @@ -88,7 +88,7 @@ console.log(jsonObj); {% endtab %} {% endtabs %} -### Convert DataFrame/Series to JSON and write to file path +### Convert DataFrame/Series to JSON and write to local file path Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment @@ -105,7 +105,7 @@ let data = { let df = new dfd.DataFrame(data); -df.to_json({ filePath: "./testOutput.json" }); +df.toJSON({ filePath: "./testOutput.json" }); ``` {% endtab %} {% endtabs %} @@ -123,5 +123,5 @@ let data = { let df = new dfd.DataFrame(data); -df.to_json({ fileName: "test_out.json" }); +df.toJSON({ fileName: "test_out.json", download: true }); ``` diff --git a/api-reference/dataframe/dataframe.values.md b/api-reference/dataframe/dataframe.values.md index 598e395..99c6d6b 100644 --- a/api-reference/dataframe/dataframe.values.md +++ b/api-reference/dataframe/dataframe.values.md @@ -4,13 +4,9 @@ description: Return a the JavaScript array representation of the DataFrame. # DataFrame.values -danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] +danfo.DataFrame.**values** -**Returns:** - - **** return **Array** - -**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. +**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor of the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. ## **Examples** @@ -26,7 +22,6 @@ let data = {"A": [-20.1, 30, 47.3, -20], let df = new dfd.DataFrame(data) console.log(df.values) - ``` {% endtab %} diff --git a/api-reference/general-functions/README.md b/api-reference/general-functions/README.md index 07815b0..52a0787 100644 --- a/api-reference/general-functions/README.md +++ b/api-reference/general-functions/README.md @@ -4,24 +4,52 @@ description: Top level functions that can be called from the Danfo namespace # General Functions -### Data manipulations +### Data transformation | | | | ------------------------------------- | ----------------------------------------------------------------------------------------------- | | [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | | [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | -| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | +| [`getDummies`](danfo.get\_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | -### Data Processing/Normalization +### Data Normalization -| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | +| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n\_classes-1. | | ----------------------------------------- | ---------------------------------------------------------------------- | | [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | | [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | | [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | -### Top-level dealing with datetime +### Working with DateTime + +| [`toDateTime`](danfo.to\_datetime.md) | Convert argument to datetime. | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| [`dateRange`](danfo.date\_range.md) | Return a fixed frequency Datetime Index. | +| [Dt](danfo.dt.md) | A class that converts strings of Date Time into a usable format, by exposing various helper methods. | + +### Streaming Functions + +| [streamCSV](danfo.streamcsv.md) | A function that loads a CSV object as a stream, returning intermediate rows as a DataFrame. | +| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| [streamJSON](danfo.streamjson.md) | A function that loads a JSON object as a stream, returning intermediate rows as a DataFrame. | +| [streamCSVTransformer](danfo.streamcsvtransformer.md) | A function that loads a CSV object as a stream, and applies a map-reduce function to intermediate rows. | +| [convertFunctionTotransformer](danfo.-convertfunctiontotransformer.md) | A function to convert any JS function into a Stream transformer. | + + + +### Utility and Configurations + +| [Utils](danfo.utils.md) | A utility class with helper methods mostly used internally. | +| -------------------------- | ------------------------------------------------------------ | +| [Config](broken-reference) | Base configuration class for NDframe objects | + +### Strings + +| [Str](danfo.str.md) | A class that converts strings into a usable format, by exposing various helper methods. | +| ------------------- | --------------------------------------------------------------------------------------- | + +### Internal Libs + +| [tensoflow](danfo.tensorflow.md) | Exported Tensorflow.js library. This helps to avoid duplicated Tensorflow.js library use. | +| -------------------------------- | ------------------------------------------------------------------------------------------ | -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | -| ------------------------------------ | --------------------------------------- | -| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference/general-functions/danfo.-convertfunctiontotransformer.md b/api-reference/general-functions/danfo.-convertfunctiontotransformer.md new file mode 100644 index 0000000..08be24f --- /dev/null +++ b/api-reference/general-functions/danfo.-convertfunctiontotransformer.md @@ -0,0 +1,103 @@ +--- +description: Converts a function to a pipe transformer. Only available in Nodejs version. +--- + +# danfo. convertFunctionTotransformer + +danfo.**convertFunctionTotransformer**(func) + +| Parameters | Type | Description | Default | +| ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------- | +| **func** | Function | A valid JavaScript function to convert to a [pipe transformer.](https://nodejs.org/api/stream.html#implementing-a-transform-stream) | | + +**Returns:** + +> return A [pipe transformer](https://nodejs.org/api/stream.html#implementing-a-transform-stream) that applies the function to each row of object. + +The **convertFunctionTotransformer** takes a function and converts it to a Nodejs stream transformer function which can be used in combination with streamCsvTransformer to incrementally transform large files. + +## **Converting a function to a transformer** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +/* + * A simple function that takes each row of a DataFrame and splits the + * name field. +*/ +const renamer = (dfRow: DataFrame) => { + const dfModified = dfRow["Names"].map((name) => name.split(",")[0]) + return dfModified +} + +const transformer = dfd.convertFunctionTotransformer(renamer) +console.log(transformer) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +Transform { + _readableState: ReadableState { + objectMode: true, + highWaterMark: 16, + buffer: BufferList { head: null, tail: null, length: 0 }, + length: 0, + pipes: [], + flowing: null, + ended: false, + endEmitted: false, + reading: false, + sync: false, + needReadable: false, + emittedReadable: false, + readableListening: false, + resumeScheduled: false, + errorEmitted: false, + emitClose: true, + autoDestroy: true, + destroyed: false, + errored: null, + closed: false, + closeEmitted: false, + defaultEncoding: 'utf8', + awaitDrainWriters: null, + writecb: null, + writechunk: null, + writeencoding: null + } +} +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/general-functions/danfo.concat.md b/api-reference/general-functions/danfo.concat.md index e248f46..cb0cde1 100644 --- a/api-reference/general-functions/danfo.concat.md +++ b/api-reference/general-functions/danfo.concat.md @@ -4,19 +4,15 @@ description: Concatenate DataFrames and Series along an axis # danfo.concat -danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**concat**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| options | Object |

{

dfList: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | ## **Examples** -### **Concatenate two DataFrames along column axis (1)** +### **Concatenate two DataFrames along column axis (1)** {% tabs %} {% tab title="Node" %} @@ -37,7 +33,7 @@ let df1 = new dfd.DataFrame(data, { columns: colum1 }) let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) +let com_df = dfd.concat({ dfList: [df1, df2], axis: 1 }) com_df.print() ``` {% endtab %} @@ -66,7 +62,7 @@ com_df.print() {% endtab %} {% endtabs %} -### **Concatenate two DataFrames along row axis (0)** +### **Concatenate two DataFrames along row axis (0)** {% tabs %} {% tab title="Node" %} @@ -87,7 +83,7 @@ let df1 = new dfd.DataFrame(data, { columns: colum1 }) let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +let com_df = dfd.concat({ dfList: [df1, df2], axis: 0 }) com_df.print(10) ``` {% endtab %} @@ -101,7 +97,6 @@ com_df.print(10) {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -125,7 +120,7 @@ com_df.print(10) {% endtab %} {% endtabs %} -### **Concatenate two Series along row axis (0)** +### **Concatenate two Series along row axis (0)** {% tabs %} {% tab title="Node" %} @@ -146,7 +141,7 @@ let df1 = new dfd.DataFrame(data, { columns: colum1 }) let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) +let com_df = dfd.concat({ dfList: [df1, df2], axis: 0 }) com_df.print(10) ``` {% endtab %} @@ -160,7 +155,6 @@ com_df.print(10) {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B │ D ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -184,4 +178,4 @@ com_df.print(10) {% endtab %} {% endtabs %} -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. +See also [danfo.merge ](danfo.merge.md)for joining objects based SQL-like joins. diff --git a/api-reference/general-functions/danfo.date_range.md b/api-reference/general-functions/danfo.date_range.md index 9c4a337..efcfb4c 100644 --- a/api-reference/general-functions/danfo.date_range.md +++ b/api-reference/general-functions/danfo.date_range.md @@ -2,17 +2,13 @@ description: Return a fixed frequency Dates spread between start and end parameters. --- -# danfo.date\_range +# danfo.dateRange -danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**dateRange**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | +| ----------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **options** | Object |

Includes any of the following:

start: Left bound for generating dates.

end: Right bound for generating dates.

period : Number of periods to generate.

offSet: Date range offset

freq: Date range frequency. One of ["M","D","s","H","m","Y"]

| ## **Examples** @@ -21,7 +17,7 @@ danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfoj ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) +let data = new dfd.dateRange({"start":'1/1/2018', period:5, freq:'M'}) console.log(data); ``` {% endtab %} @@ -50,7 +46,6 @@ console.log(data); - ``` {% endtab %} {% endtabs %} @@ -74,7 +69,7 @@ console.log(data); ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) +let data = new dfd.dateRange({ "start": '1/1/2018', period: 12, freq: 'Y' }) console.log(data); ``` {% endtab %} @@ -107,5 +102,5 @@ console.log(data); {% endtabs %} {% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/general-functions/danfo.dt.md b/api-reference/general-functions/danfo.dt.md new file mode 100644 index 0000000..766aacc --- /dev/null +++ b/api-reference/general-functions/danfo.dt.md @@ -0,0 +1,49 @@ +--- +description: Accessor object for date time properties of the Series values. +--- + +# danfo.Dt + +For example, in the following example, we convert a Series to an `Dt` instance and apply a couple of **DateTime** methods. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Dt, Series } from "danfojs-node-nightly" + +const sf = new Series(["1/1/2000", "1/2/2000", "2/3/2000", "1/4/2000", "4/5/2000"]) +const dtS = new Dt(sf) + +dtS.dayOfWeekName().print() +dtS.monthName().print() +``` +{% endtab %} +{% endtabs %} + +``` +// output +╔═══╤═══════════╗ +║ 0 │ Saturday ║ +╟───┼───────────╢ +║ 1 │ Sunday ║ +╟───┼───────────╢ +║ 2 │ Thursday ║ +╟───┼───────────╢ +║ 3 │ Tuesday ║ +╟───┼───────────╢ +║ 4 │ Wednesday ║ +╚═══╧═══════════╝ + +╔═══╤══════════╗ +║ 0 │ January ║ +╟───┼──────────╢ +║ 1 │ January ║ +╟───┼──────────╢ +║ 2 │ February ║ +╟───┼──────────╢ +║ 3 │ January ║ +╟───┼──────────╢ +║ 4 │ April ║ +╚═══╧══════════╝ + +``` diff --git a/api-reference/general-functions/danfo.get_dummies.md b/api-reference/general-functions/danfo.get_dummies.md index e53fd81..9af101a 100644 --- a/api-reference/general-functions/danfo.get_dummies.md +++ b/api-reference/general-functions/danfo.get_dummies.md @@ -2,18 +2,14 @@ description: Convert categorical variable into dummy/indicator variables. --- -# danfo.get\_dummies +# danfo.getDummies -danfo.**get\_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**getDummies**(kwargs) -| Parameters | Type | Description | Default | -| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| data | Series or Dataframe | The data to dummify | | -| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| data | Series or Dataframe | The data to dummify | | +| **options** | Object |

These includes:

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: Prefix for the new columns

|

{

prefixSeparator: "-"

}

| ## **Examples** @@ -27,7 +23,7 @@ const dfd = require("danfojs-node") let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] let sf1 = new dfd.Series(datasf) -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) +let dum_df = dfd.getDummies(sf1, { prefix: "fruit" }) dum_df.print() ``` {% endtab %} @@ -41,7 +37,6 @@ dum_df.print() {% tabs %} {% tab title="Output" %} ``` - ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -73,7 +68,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df) +let dum_df = dfd.getDummies(df) dum_df.print() ``` {% endtab %} @@ -135,7 +130,7 @@ let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], let df = new dfd.DataFrame(data) df.print() -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) +let dum_df = dfd.getDummies(df, { columns: ['fruits']}) dum_df.print() ``` {% endtab %} diff --git a/api-reference/general-functions/danfo.labelencoder.md b/api-reference/general-functions/danfo.labelencoder.md index b0745a8..9944f53 100644 --- a/api-reference/general-functions/danfo.labelencoder.md +++ b/api-reference/general-functions/danfo.labelencoder.md @@ -4,11 +4,11 @@ description: Encode target labels with value between 0 and n_classes-1. # danfo.LabelEncoder -class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**LabelEncoder** -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. +danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. +The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. ## **Examples** @@ -17,6 +17,8 @@ The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/m {% tabs %} {% tab title="Node" %} ```javascript +const dfd = require('danfojs-node') + let data = ["dog","cat","man","dog","cat","man","man","cat"] let series = new dfd.Series(data) @@ -26,15 +28,10 @@ encode.fit(series) console.log(encode); let sf_enc = encode.transform(series.values) -sf_enc.print() +console.log(sf_enc) let new_sf = encode.transform(["dog","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` +console.log(new_sf) ``` {% endtab %} {% endtabs %} @@ -42,34 +39,12 @@ new_sf.print() {% tabs %} {% tab title="Output" %} ``` -LabelEncoder { label: [ 'dog', 'cat', 'man' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╟───┼──────────────────────╢ -║ 5 │ 2 ║ -╟───┼──────────────────────╢ -║ 6 │ 2 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ +LabelEncoder { '$labels': { dog: 0, cat: 1, man: 2 } } +[ + 0, 1, 2, 0, + 1, 2, 2, 1 +] +[ 0, 2 ] ``` {% endtab %} {% endtabs %} @@ -95,10 +70,10 @@ encode.fit(df['fruits']) console.log(encode); let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() +console.log(sf_enc); -let new_sf = encode.transform(["mango","man"]) -new_sf.print() +let new_sf = encode.transform(["mango","mane"]) +console.log(new_sf); ``` {% endtab %} @@ -111,30 +86,11 @@ new_sf.print() {% tabs %} {% tab title="Output" %} ``` -LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╚═══╧══════════════════════╝ +LabelEncoder { '$labels': { pear: 0, mango: 1, pawpaw: 2, bean: 3 } } +[ 0, 1, 2, 1, 3 ] +[ 1, -1 ] ``` {% endtab %} {% endtabs %} -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) +See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.getDummies](danfo.get\_dummies.md) diff --git a/api-reference/general-functions/danfo.merge.md b/api-reference/general-functions/danfo.merge.md index 0c4b760..63252a3 100644 --- a/api-reference/general-functions/danfo.merge.md +++ b/api-reference/general-functions/danfo.merge.md @@ -6,19 +6,15 @@ description: >- # danfo.merge -danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**merge**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | +| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| options | Object |

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

| ## **Examples** -**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. +**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. @@ -26,7 +22,7 @@ For a more intuitive understanding, this [guide](https://pandas.pydata.org/panda ### **Merging by a single key found in both axis** -By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. +In the following example, we perform an inner join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. {% tabs %} {% tab title="Node" %} @@ -48,7 +44,7 @@ let df2 = new dfd.DataFrame(data2, { columns: colum2 }) df1.print() df2.print() -let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) +let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"], how: "inner"}) merge_df.print() ``` {% endtab %} @@ -62,7 +58,6 @@ merge_df.print() {% tabs %} {% tab title="Output" %} ``` - //first DataFrame ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Key1 │ Key2 │ A │ B ║ @@ -105,7 +100,6 @@ merge_df.print() ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -117,7 +111,6 @@ Merging by two keys takes into consideration the keys appearing in both`left` an {% tabs %} {% tab title="Node" %} ```javascript - const dfd = require("danfojs-node") @@ -190,12 +183,11 @@ merge_df.print() ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} -The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent +The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent ### Outer join/merge on DataFrame diff --git a/api-reference/general-functions/danfo.minmaxscaler.md b/api-reference/general-functions/danfo.minmaxscaler.md index d58af8b..a607336 100644 --- a/api-reference/general-functions/danfo.minmaxscaler.md +++ b/api-reference/general-functions/danfo.minmaxscaler.md @@ -4,13 +4,13 @@ description: Transform features by scaling each feature to a range of max and mi # danfo.MinMaxScaler -class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**MinMaxScaler** danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). -The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. +The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. ## **Examples** @@ -34,7 +34,6 @@ scaler.fit(df) let df_enc = scaler.transform(df) df_enc.print() - ``` {% endtab %} @@ -47,7 +46,6 @@ df_enc.print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ 0 │ 1 │ 2 │ 3 ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -87,13 +85,12 @@ let data = [[100,1000,2000, 3000] , [1, 1, 1, 0]] let df = new dfd.DataFrame(data) -let sf = df.iloc({columns: ["0"]}) +let sf = df.iloc({columns: [0]}) scaler.fit(sf) let df_enc = scaler.transform(sf) df_enc.print() - ``` {% endtab %} @@ -106,7 +103,6 @@ df_enc.print() {% tabs %} {% tab title="Output" %} ``` - Shape: (3,1) ╔═══╤═══════════════════╗ diff --git a/api-reference/general-functions/danfo.onehotencoder.md b/api-reference/general-functions/danfo.onehotencoder.md index 81c913d..8d7c979 100644 --- a/api-reference/general-functions/danfo.onehotencoder.md +++ b/api-reference/general-functions/danfo.onehotencoder.md @@ -4,11 +4,11 @@ description: Encode categorical features as a one-hot numeric array. # danfo.OneHotEncoder -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] +class danfo.**OneHotEncoder** -danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. +danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. +The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. ## **Examples** @@ -19,9 +19,11 @@ The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/st ```javascript const dfd = require("danfojs-node") -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} +let data = { + fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], + Count: [20, 30, 89, 12, 30], + Country: ["NG", "NG", "GH", "RU", "RU"] +} let df = new dfd.DataFrame(data) @@ -31,15 +33,10 @@ encode.fit(df['fruits']) console.log(encode); let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() +console.log(sf_enc) -let new_sf = encode.transform(["mango","bean"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` +let new_sf = encode.transform(["mango", "bean"]) +console.log(new_sf) ``` {% endtab %} {% endtabs %} @@ -47,32 +44,15 @@ new_sf.print() {% tabs %} {% tab title="Output" %} ``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - +OneHotEncoder { '$labels': [ 'pear', 'mango', 'pawpaw', 'bean' ] } +[ + [ 1, 0, 0, 0 ], + [ 0, 1, 0, 0 ], + [ 0, 0, 1, 0 ], + [ 0, 1, 0, 0 ], + [ 0, 0, 0, 1 ] +] +[ [ 0, 1, 0, 0 ], [ 0, 0, 0, 1 ] ] ``` {% endtab %} {% endtabs %} @@ -81,68 +61,4 @@ new_sf.print() **Labels not found in the original data used for fitting are represented with 0s all through** {% endhint %} -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","woman", "cup"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) +See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.getDummies](danfo.get\_dummies.md) diff --git a/api-reference/general-functions/danfo.standardscaler.md b/api-reference/general-functions/danfo.standardscaler.md index 89ce861..323f53d 100644 --- a/api-reference/general-functions/danfo.standardscaler.md +++ b/api-reference/general-functions/danfo.standardscaler.md @@ -4,7 +4,7 @@ description: Standardize features by removing the mean and scaling to unit varia # danfo.StandardScaler -class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +class danfo.**StandScaler** danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: @@ -12,7 +12,7 @@ danfo.js provides the StandardScaler class for the standardization of DataFrame where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. -The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. +The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. ## **Examples** @@ -44,29 +44,25 @@ sf_enc.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 100 ║ -╟───┼──────────────────────╢ -║ 1 │ 1000 ║ -╟───┼──────────────────────╢ -║ 2 │ 2000 ║ -╟───┼──────────────────────╢ -║ 3 │ 3000 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1.1375757455825806 ║ -╟───┼──────────────────────╢ -║ 1 │ -0.4191068708896637 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.37919193506240845 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.1774907112121582 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ 100 ║ +╟───┼──────╢ +║ 1 │ 1000 ║ +╟───┼──────╢ +║ 2 │ 2000 ║ +╟───┼──────╢ +║ 3 │ 3000 ║ +╚═══╧══════╝ + +╔═══╤═════════════════════╗ +║ 0 │ -1.3135592937469482 ║ +╟───┼─────────────────────╢ +║ 1 │ -0.4839428961277008 ║ +╟───┼─────────────────────╢ +║ 2 │ 0.4378530979156494 ║ +╟───┼─────────────────────╢ +║ 3 │ 1.3596490621566772 ║ +╚═══╧═════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -77,20 +73,20 @@ sf_enc.print() {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let scaler = new dfd.StandardScaler() -let data = [[100,1000,2000, 3000] , - [20, 30, 89, 12], - [1, 1, 1, 0]] -let df = new dfd.DataFrame(data) +let data = [[100, 1000, 2000, 3000], + [20, 30, 89, 12], + [1, 1, 1, 0]] + +let df = new dfd.DataFrame(data, { columns: ['a', 'b', 'c', 'd'] }) df.print() +let scaler = new dfd.StandardScaler() scaler.fit(df) let df_enc = scaler.transform(df) df_enc.print() - ``` {% endtab %} @@ -103,28 +99,25 @@ df_enc.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ a │ b │ c │ d ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 20 │ 30 │ 89 │ 12 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1 │ 1 │ 1 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ a │ b │ c │ d ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1.3909024000167… │ 1.4137537479400… │ 1.4131401777267… │ 1.4142049551010… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.473994612693… │ -0.675643563270… │ -0.658863127231… │ -0.702851355075… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -0.916907668113… │ -0.738110065460… │ -0.754277229309… │ -0.711353600025… ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/general-functions/danfo.str.md b/api-reference/general-functions/danfo.str.md new file mode 100644 index 0000000..f12c428 --- /dev/null +++ b/api-reference/general-functions/danfo.str.md @@ -0,0 +1,67 @@ +--- +description: Accessor object for String-like properties of Series values. +--- + +# danfo.Str + +For example, in the following example, we convert a Series to an `Str` instance and apply a couple of **String** methods. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Str, Series } from "danfojs-node" + +const sf = new Series(["Dog", "Cat", "Bird", "Fish", "ShArk", "tiGer"]) +const sfStr = new Str(sf) + +sfStr.toLowerCase().print() +sfStr.toUpperCase().print() +sfStr.join("Added", "-").print() +``` +{% endtab %} +{% endtabs %} + +``` +// output +╔═══╤═══════╗ +║ 0 │ dog ║ +╟───┼───────╢ +║ 1 │ cat ║ +╟───┼───────╢ +║ 2 │ bird ║ +╟───┼───────╢ +║ 3 │ fish ║ +╟───┼───────╢ +║ 4 │ shark ║ +╟───┼───────╢ +║ 5 │ tiger ║ +╚═══╧═══════╝ + +╔═══╤═══════╗ +║ 0 │ DOG ║ +╟───┼───────╢ +║ 1 │ CAT ║ +╟───┼───────╢ +║ 2 │ BIRD ║ +╟───┼───────╢ +║ 3 │ FISH ║ +╟───┼───────╢ +║ 4 │ SHARK ║ +╟───┼───────╢ +║ 5 │ TIGER ║ +╚═══╧═══════╝ +╔═══╤═════════════╗ +║ 0 │ Dog-Added ║ +╟───┼─────────────╢ +║ 1 │ Cat-Added ║ +╟───┼─────────────╢ +║ 2 │ Bird-Added ║ +╟───┼─────────────╢ +║ 3 │ Fish-Added ║ +╟───┼─────────────╢ +║ 4 │ ShArk-Added ║ +╟───┼─────────────╢ +║ 5 │ tiGer-Added ║ +╚═══╧═════════════╝ + +``` diff --git a/api-reference/general-functions/danfo.streamcsv.md b/api-reference/general-functions/danfo.streamcsv.md new file mode 100644 index 0000000..f70b704 --- /dev/null +++ b/api-reference/general-functions/danfo.streamcsv.md @@ -0,0 +1,104 @@ +--- +description: >- + Streams a CSV file from a local or remote location in chunks. Each + intermediate chunk is passed as a DataFrame to the callback function. +--- + +# danfo.streamCSV + +danfo.**streamCSV**(filePath, callback, options) + +| Parameters | Type | Description | +| ---------- | -------- | -------------------------------------------------------------------------------------------------------------- | +| filePath | string | URL or local file path to CSV file. | +| callback | Function | Callback function to be called once the specifed rows are parsed into DataFrame. | +| options | object | Optional configuration object. Supports all [Papaparse](https://www.papaparse.com/docs#config) config options. | + +The **streamCSV** function streams a CSV file from a local or remote location in chunks. Each intermediate chunk is passed as a DataFrame to the callback function. + +## **Stream CSV file from local path** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const path = require("path") + +const filePath = path.join(process.cwd(), "raw_data", "titanic.csv"); + +dfd.streamCSV(filePath, (df) => { + if (df) { + // Do any processing here + df.print(); + } +}); +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Showing few rows +... + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ PassengerId │ Survived │ Pclass │ Name │ ... │ Fare │ Cabin │ Embarked ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 676 │ 687 │ 0 │ 3 │ Panula, Mr. Jaa… │ ... │ 39.6875 │ │ S ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ PassengerId │ Survived │ Pclass │ Name │ ... │ Fare │ Cabin │ Embarked ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 677 │ 688 │ 0 │ 3 │ Dakic, Mr. Bran… │ ... │ 10.1708 │ │ S ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +... +``` +{% endtab %} +{% endtabs %} + +## **Stream CSV file from remote path** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +const remoteFile = "https://raw.githubusercontent.com/opensource9ja/danfojs/dev/danfojs-node/tests/samples/titanic.csv" + +const callback = (df) => { + //Perform any processing here + if (df) { + df.print(); + } +} + +dfd.streamCSV(remoteFile, callback, { header: true }) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Showing a few rows +... + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Survived │ Pclass │ Name │ Sex │ Age │ Siblings/Spouse… │ Parents/Childre… │ Fare ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 523 │ 0 │ 1 │ Mr. John Farthi… │ male │ 49 │ 0 │ 0 │ 221.7792 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Survived │ Pclass │ Name │ Sex │ Age │ Siblings/Spouse… │ Parents/Childre… │ Fare ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 524 │ 0 │ 3 │ Mr. Johan Werne… │ male │ 39 │ 0 │ 0 │ 7.925 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +... +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/general-functions/danfo.streamcsvtransformer.md b/api-reference/general-functions/danfo.streamcsvtransformer.md new file mode 100644 index 0000000..922dd43 --- /dev/null +++ b/api-reference/general-functions/danfo.streamcsvtransformer.md @@ -0,0 +1,181 @@ +--- +description: >- + A pipeline transformer to stream a CSV file from local storage, transform it + with a custom transformer, and write to the output stream. Only available in + Node.js +--- + +# danfo.streamCsvTransformer + +danfo.**streamCsvTransformer**(func) + +| Parameters | Type | Description | +| ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| inputFilePath | Function | The path to the CSV file to stream from. | +| transformer | Function |

The transformer function to apply to each row.

Note that each row of the CSV file is passed as a DataFrame with a single row to the transformer function, and the transformer function is expected to return a transformed DataFrame.

| +| options | object |

Configuration options for the pipeline. These include:

  • outputFilePath The local file path to write the transformed CSV file to.
  • customCSVStreamWriter A custom CSV stream writer function. This is applied at the end of each transform. If not provided, a default CSV stream writer is used, and this writes to local storage.
  • inputStreamOptions Configuration options for the input stream. Supports all Papaparse CSV reader config options.
  • outputStreamOptions Configuration options for the output stream. This is only applied when using the default CSV stream writer. Supports all toCSV options.
| + +**Returns:** + +> return A promise that resolves when the pipeline transformation is complete. + +The streamCsvTransformer can be used to [incrementally transform](https://en.wikipedia.org/wiki/Stream\_processing) a CSV file. This is done by: + +* Streaming a CSV file from a local or **remote** path. +* Passing each corresponding row as a DataFrame to the specified transformer function. +* Writing the result to an output stream. + + + +## **Stream processing a local file** + +In the example below, we stream a local CSV file (titanic.csv), applies a transformer function, and write the output to the `titanicOutLocal` file. + +The transformer takes each `Name` column, splits the person's title, and creates a new column from it. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { DataFrame, Series, streamCsvTransformer } from "danfojs-node"; +import path from "path" + +const inputFilePath = path.join(process.cwd(), "raw_data", "titanic.csv"); +const outputFilePath = path.join(process.cwd(), "raw_data", "titanicOutLocal.csv"); + +/** + * A simple function that takes a DataFrame, and transforms the Name column. +* */ +const transformer = (df) => { + const titles = df["Name"].map((name) => name.split(".")[0]); + const names = df["Name"].map((name) => name.split(".")[1]); + df["Name"] = names + df.addColumn("titles", titles, { inplace: true }) + return df +} + +dfd.streamCsvTransformer(inputFilePath, transformer, { + outputFilePath, + inputStreamOptions: { header: false } +}) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//initial head of titanic.csv before transforming + +PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked +1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S +2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C +3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S + + +//Head of titanicOutLocal.csv after transforming + +PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked,titles +1,0,3, Owen Harris,male,22,1,0,A/5 21171,7.25,,S,Braund, Mr +2,1,1, John Bradley (Florence Briggs Thayer),female,38,1,0,PC 17599,71.2833,C85,C,Cumings, Mrs +3,1,3, Laina,female,26,0,0,STON/O2. 3101282,7.925,,S,Heikkinen, Miss +``` +{% endtab %} +{% endtabs %} + +## **Stream processing of remote file** + +In the example below, we stream a remote CSV file (titanic.csv), applies a transformer function, and write the output to the `titanicOutLocal` file. + +The transformer takes each `Name` column, splits the person's title, and creates a new column from it. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { DataFrame, Series, streamCsvTransformer } from "danfojs-node"; +import path from "path" + +const inputFilePath = "https://raw.githubusercontent.com/opensource9ja/danfojs/dev/danfojs-node/tests/samples/titanic.csv" +const outputFilePath = path.join(process.cwd(), "raw_data", "titanicOutRemote.csv"); + + +/** + * A simple function that takes a DataFrame, and transforms the Name column. +* */ +const transformer = (df) => { + const titles = df["Name"].map((name) => name.split(".")[0]); + const names = df["Name"].map((name) => name.split(".")[1]); + df["Name"] = names + df.addColumn("titles", titles, { inplace: true }) + return df +} + +dfd.streamCsvTransformer(inputFilePath, transformer, { + outputFilePath, + inputStreamOptions: { header: false } +}) +``` +{% endtab %} +{% endtabs %} + +## **Stream processing with a custom writer** + +If you need custom control of the output writer, then you can provide a pipe-able custom writer. See [https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/](https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/) + +In the example below, we add a custom writer that logs each row. You can extend this to upload each chunk to a database, or any other function you need. + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require('danfojs-node-nightly') +const path = require("path") +const stream = require("stream") + +const inputFilePath = "https://raw.githubusercontent.com/opensource9ja/danfojs/dev/danfojs-node/tests/samples/titanic.csv" + +const transformer = (df) => { + const titles = df["Name"].map((name) => name.split(".")[0]); + const names = df["Name"].map((name) => name.split(".")[1]); + df["Name"] = names + df.addColumn("titles", titles, { inplace: true }) + return df +} +let count = 0 + +const customWriter = function () { + const csvOutputStream = new stream.Writable({ objectMode: true }) + csvOutputStream._write = (chunk, encoding, callback) => { + //Do anything here. For example you can write to online storage DB + console.log("Chunk written: " + chunk) // Eah chunk is a row DataFrame + count += 1 + callback() + + } + return csvOutputStream +} + +dfd.streamCsvTransformer( + inputFilePath, + transformer, + { + customCSVStreamWriter: customWriter, + inputStreamOptions: { header: true } + }) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Showing the last log +... + +Chunk written: +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Survived │ Pclass │ Name │ Sex │ Age │ Siblings/Spouse… │ Parents/Childre… │ Fare │ titles ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 884 │ 0 │ 3 │ Patrick Dooley │ male │ 32 │ 0 │ 0 │ 7.75 │ Mr ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/general-functions/danfo.streamjson.md b/api-reference/general-functions/danfo.streamjson.md new file mode 100644 index 0000000..c834210 --- /dev/null +++ b/api-reference/general-functions/danfo.streamjson.md @@ -0,0 +1,101 @@ +--- +description: >- + Streams a JSON file from a local or remote location in chunks. Each + intermediate chunk is passed as a DataFrame to the callback function. +--- + +# danfo.streamJSON + +danfo.**streamJSON**(filePath, callback, options) + +| Parameters | Type | Description | +| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| filePath | string | URL or local file path to CSV file. | +| callback | Function | Callback function to be called once the specifed rows are parsed into DataFrame. | +| options | object | Optional configuration object. We use the `request` library for reading remote json files, Hence all `request` parameters such as `method`, `headers`, are supported. | + +The **streamJSON** function streams a JSON file from a local or remote location in chunks. Each intermediate chunk is passed as a DataFrame to the callback function. + +## **Stream JSON file from local path** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const path = require("path") + +const filePath = path.join(process.cwd(), "raw_data", "book_small.json"); + +dfd.streamJSON(filePath, (df) => { + if (df) { + // Do any processing here + df.print(); + } +}); +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Showing the last rows +... + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ book_id │ title │ image_url │ authors ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 10 │ 32848471 │ Egomaniac │ https://images.… │ Vi Keeland ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ book_id │ title │ image_url │ authors ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ 33288638 │ Wait for It │ https://s.gr-as… │ Mariana Zapata ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} + +## **Stream JSON file from remote path** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const path = require("path") + +const remoteFile = "https://raw.githubusercontent.com/opensource9ja/danfojs/dev/danfojs-node/tests/samples/book.json" + +const callback = (df) => { + //Perform any processing here + if (df) { + df.print(); + } +} + +dfd.streamJSON(remoteFile, callback, { header: true }) +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +//Showing a few rows +... + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ book_id │ title │ image_url │ authors ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 10 │ 32848471 │ Egomaniac │ https://images.… │ Vi Keeland ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ book_id │ title │ image_url │ authors ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ 33288638 │ Wait for It │ https://s.gr-as… │ Mariana Zapata ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/general-functions/danfo.tensorflow.md b/api-reference/general-functions/danfo.tensorflow.md new file mode 100644 index 0000000..727f08c --- /dev/null +++ b/api-reference/general-functions/danfo.tensorflow.md @@ -0,0 +1,70 @@ +--- +description: Exported internal Tensoflow.js library +--- + +# danfo.tensorflow + +danfo.**tensorflow** + +**Returns:** + +> return [Tensorflow.js](https://www.npmjs.com/package/@tensorflow/tfjs) library + +## **Examples** + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") +const tf = dfd.tensorflow + +let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) +console.log(tensor_arr) +``` +{% endtab %} + +{% tab title="Browser" %} +```markup + + + + + + + + + Document + + + + + + + + +``` +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} +``` +Tensor { + kept: false, + isDisposedInternal: false, + shape: [ 2, 4 ], + dtype: 'float32', + size: 8, + strides: [ 4 ], + dataId: {}, + id: 4, + rankType: '2' +} +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/general-functions/danfo.to_datetime.md b/api-reference/general-functions/danfo.to_datetime.md index 7012100..2adb884 100644 --- a/api-reference/general-functions/danfo.to_datetime.md +++ b/api-reference/general-functions/danfo.to_datetime.md @@ -1,37 +1,32 @@ --- -description: Converts an array of Date time string to Date object. +description: Converts an array of Date strings to Date object. --- # danfo.toDateTime -danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.**toDateTime**(data) -| Parameters | Type | Description | Default | -| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | -| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | - -**Returns:** - - **** return **DataFrame** +| Parameters | Type | Description | Default | +| ---------- | ------------- | --------------- | ------------------------------------------------- | +| **data** | Array, Series | **data**: Array | Series with Date strings to convert to Date time. | ## **Examples** -Converts a **Series** of Date strings to Date time and get time properties +In the following example, we convert a **Series** of Date strings to DateTime objects, so we can call various Date methods on them. {% tabs %} {% tab title="Node" %} ```javascript -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) -let sf = new dfd.Series(data) -sf.print() +const dfd = require('danfojs-node') -let dt = dfd.toDateTime(data) +let data = new dateRange({ "start": '1/1/2018', period: 12, freq: 'M' }) +let sf = new Series(data) +sf.print() -dt.month().print() -dt.month_name().print() -dt.weekdays().print() -dt.day().print() -dt.seconds().print() +let dt = toDateTime(data) +dt.dayOfMonth().print() +dt.dayOfWeekName().print() +dt.hours().print() ``` {% endtab %} @@ -44,98 +39,98 @@ dt.seconds().print() {% tabs %} {% tab title="Output" %} ``` - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - -//Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 - -//string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec - -//string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - -//Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 +╔═══╤════════════════════════╗ +║ 0 │ 1/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 2/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 3/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 4/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 5/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 6/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 7/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 8/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 9/1/2018, 12:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 10/1/2018, 12:00:00 AM ║ +╚═══╧════════════════════════╝ + +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 1 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 1 ║ +╟───┼───╢ +║ 4 │ 1 ║ +╟───┼───╢ +║ 5 │ 1 ║ +╟───┼───╢ +║ 6 │ 1 ║ +╟───┼───╢ +║ 7 │ 1 ║ +╟───┼───╢ +║ 8 │ 1 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ + +╔═══╤═══════════╗ +║ 0 │ Monday ║ +╟───┼───────────╢ +║ 1 │ Thursday ║ +╟───┼───────────╢ +║ 2 │ Thursday ║ +╟───┼───────────╢ +║ 3 │ Sunday ║ +╟───┼───────────╢ +║ 4 │ Tuesday ║ +╟───┼───────────╢ +║ 5 │ Friday ║ +╟───┼───────────╢ +║ 6 │ Sunday ║ +╟───┼───────────╢ +║ 7 │ Wednesday ║ +╟───┼───────────╢ +║ 8 │ Saturday ║ +╟───┼───────────╢ +║ 9 │ Monday ║ +╚═══╧═══════════╝ + +╔═══╤═══╗ +║ 0 │ 0 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 0 ║ +╟───┼───╢ +║ 3 │ 0 ║ +╟───┼───╢ +║ 4 │ 0 ║ +╟───┼───╢ +║ 5 │ 0 ║ +╟───┼───╢ +║ 6 │ 0 ║ +╟───┼───╢ +║ 7 │ 0 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 0 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} {% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) +Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) {% endhint %} diff --git a/api-reference/general-functions/danfo.utils.md b/api-reference/general-functions/danfo.utils.md new file mode 100644 index 0000000..c673a1b --- /dev/null +++ b/api-reference/general-functions/danfo.utils.md @@ -0,0 +1,25 @@ +--- +description: Utility class with useful methods +--- + +# danfo.Utils + +The Utils class holds useful utility methods, mostly used internally in the Danfojs library. + +For example, in the following example, we use the `inferDtype` function from the utils class. + +{% tabs %} +{% tab title="Node" %} +```javascript +import { Utils } from "danfojs-node" + +const utils = new Utils() + +const arr = [NaN, 2.1, 3.3, 2.09] +console.log(utils.inferDtype(arr)) + +//output +[ 'float32' ] +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index a291533..870f105 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -4,21 +4,17 @@ description: >- reading of CSV files in chunks. --- -# danfo.read\_csv +# danfo.readCSV -> danfo.**read\_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] +> danfo.**readCSV**(source, options) -| | | | | -| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | -| **configs**: | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

dynamicTyping: true,

header: true

}

| +| | | | | +| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | +| **options** | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

header: true

}

| -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. +The **readCSV** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. ### **Reading files from local disk** @@ -29,7 +25,7 @@ By specifying a valid file path, you can load CSV files from local disk: ```javascript const dfd = require("danfojs-node") -dfd.read_csv("./user_names.csv") //assumes file is in CWD +dfd.readCSV("./user_names.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -50,7 +46,7 @@ By specifying a valid URL, you can load CSV files from any location into Danfo\* ```javascript const dfd = require("danfojs-node") -dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD +dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD .then(df => { df.head().print() @@ -79,7 +75,7 @@ dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-c
+ Document + + + + + + + + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 3c17457..ecf32c7 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -2,9 +2,9 @@ description: Reads a JSON file into DataFrame. --- -# danfo.read\_json +# danfo.readJSON -> danfo.**read\_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] +> danfo.readJSON(source, options) | | | | | | -------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | @@ -12,11 +12,7 @@ description: Reads a JSON file into DataFrame. | _**source**_ | Input file object, string file\*\* \*\*path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | | options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. +The **readJSON** method can read JSON files from a local disk, over the internet, or directly from input file objects. ### **Reading JSON files from local disk** @@ -25,7 +21,7 @@ The **read\_json** method can read JSON files from a local disk, over the intern ```javascript const dfd = require("danfojs-node") -dfd.read_json("./user_names.json") +dfd.readJSON("./user_names.json") .then(df => { df.head().print() @@ -46,7 +42,7 @@ By specifying a valid URL, you can load JSON files from any location: ```javascript const dfd = require("danfojs-node") -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") +dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") .then(df => { df.head().print() @@ -73,7 +69,7 @@ dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple @@ -91,7 +91,7 @@ let data = { let df = new dfd.DataFrame(data); -dfd.to_csv(df, { filePath: "testOut.csv"}); +dfd.toCSV(df, { filePath: "testOut.csv"}); ``` {% endtab %} {% endtabs %} @@ -111,5 +111,5 @@ let data = { let df = new dfd.DataFrame(data); -dfd.to_csv(df, { fileName: "testOut.csv", download: true}); +dfd.toCSV(df, { fileName: "testOut.csv", download: true}); ``` diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index 1fe1adf..511381a 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -1,19 +1,19 @@ --- description: >- - Converts a DataFrame or Series to Excel file and write file to disk or + Converts a DataFrame or Series to Excel file, and write file to disk or download in browser. --- -# danfo.to_excel +# danfo.toExcel -> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] +> danfo.**toExcel**(data, options) -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. +The **toExcel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. ### Convert DataFrame to Excel and write to file path @@ -32,14 +32,14 @@ let data = { let df = new dfd.DataFrame(data); -dfd.to_excel(df, { filePath: "testOut.xlsx"}); +dfd.toExcel(df, { filePath: "testOut.xlsx"}); ``` {% endtab %} {% endtabs %} -### Convert DataFrame to Excel and download the file in Client-side lib +### Convert DataFrame to Excel and download the file in Client-side lib -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. +You can automatically convert and download an Excel file in a browser environment, by specifying a filename and setting download to `true` ```javascript let data = { @@ -48,7 +48,7 @@ let data = { "country code": ["NG", "FR", "GH"], }; -let df = new dfd.DataFrame(data); +let df = new DataFrame(data); -dfd.to_excel(df, { fileName: "testOut.xlsx"}); +dfd.toExcel(df, { fileName: "testOut.xlsx", download: true}); ``` diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index baac615..bdcafc9 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -1,6 +1,6 @@ -# danfo.to\_json +# danfo.toJSON -> danfo.**to\_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] +> danfo.toJSON(data, options) | | | | | | -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | @@ -8,7 +8,7 @@ | _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | | **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. +The **toJSON** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. ### Convert DataFrame/Series to JSON and return value @@ -25,7 +25,7 @@ let data = { let df = new dfd.DataFrame(data); -const jsonObj = dfd.to_json(df, { download: false }); //column format +const jsonObj = dfd.toJSON(df); //column format console.log(jsonObj); //output @@ -36,8 +36,7 @@ console.log(jsonObj); ] //row format -const jsonObj = dfd.to_json(df, { - download: false, +const jsonObj = dfd.toJSON(df, { format: "row" }); @@ -75,7 +74,7 @@ console.log(jsonObj); let df = new dfd.DataFrame(data); - const csv = df.to_csv({ download: false }); + const csv = df.toJSON(); console.log(csv); @@ -102,7 +101,7 @@ let data = { let df = new dfd.DataFrame(data); -dfd.to_json(df, { filePath: "./testOutput.json" }); +dfd.toJSON(df, { filePath: "./testOutput.json" }); ``` {% endtab %} {% endtabs %} @@ -120,5 +119,5 @@ let data = { let df = new dfd.DataFrame(data); -dfd.to_json(df, { fileName: "test_out.json" }); +dfd.toJSON(df, { fileName: "test_out.json", download: true }); ``` diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index 6606bdc..e62390c 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -8,8 +8,6 @@ A bar plot presents categorical data with rectangular bars with lengths proporti ## Examples -The **bar** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. - ### Bar plot on Series ```markup @@ -19,7 +17,6 @@ The **bar** plot is exposed by the .**plot()** function called on a Series or Da - Document @@ -29,7 +26,7 @@ The **bar** plot is exposed by the .**plot()** function called on a Series or Da
@@ -49,7 +46,6 @@ The **bar** plot is exposed by the .**plot()** function called on a Series or Da - @@ -58,7 +54,7 @@ The **bar** plot is exposed by the .**plot()** function called on a Series or Da
- + + + + Document - + - + +
- - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (23).png>) ### Box plots on a DataFrame -```markup - - +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { Series, readCSV } from "danfojs-nightly"; - - - - - - Document - +function App() { - + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { -
- - +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html + + + + + + + Document + + + +
+
+ + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) ### Box plot for selected columns in a DataFrame -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { Series, readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { + + df.plot("plot_div").box({ + config: { + x: "Survived", y: "Age" + }, + layout: { + title: "Box Plot" + } + }) + }).catch(err => { + console.log(err); + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html - - - - - - + + + + Document - + - + +
- - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (24).png>) {% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +To customize your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} diff --git a/api-reference/plotting/configuring-your-plots.md b/api-reference/plotting/configuring-your-plots.md index 4cedbb2..dccfa01 100644 --- a/api-reference/plotting/configuring-your-plots.md +++ b/api-reference/plotting/configuring-your-plots.md @@ -1,68 +1,144 @@ -# Configuring your plots +# Customizing your plots -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. +Danfo.js currently supports [Plotly.js](https://plotly.com/javascript) for plotting. This means you have all the configuration, flexibility, and interactiveness of Plotly. -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. +All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed in the `config` and `layout` parameter. -For example in the following code, we show how to set some basic configuration as well as layout for a line plot. +## Config Parameter -```markup - - +The config parameter extends the [Plotly.js config](https://plotly.com/javascript/configuration-options/) type. That is, all properties available to the Plotly [config](https://plotly.com/javascript/configuration-options/) argument, are available. Alongside those arguments, Danfo.js uses some custom arguments which we list below: - - - +| Argument | Description | Default value | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| **x** | Column name to plot on the x-axis. | DataFrame index if required | +| **y** | Column name to plot on the y-axis. | DataFrame index if required | +| **columns** | Array of column names to plot. | All columns in the DataFrame when applicable | +| **values** | Used to configure a `pie` chart. A column name containing values for the pie. Maps 1-1 with labels. | | +| **labels** | Used to configure a `pie` chart. A column name containing labels for the pie. Maps 1-1 with values. | | +| **rowPositions** | Used to configure a `pie` chart. Pie chart domain row. See [https://plotly.com/javascript/reference/pie/#pie-domain-row](https://plotly.com/javascript/reference/pie/#pie-domain-row) | Range of `0 - DataFrame column length` | +| **columnPositions** | Used to configure a `pie` chart. Pie chart domain column. See [https://plotly.com/javascript/reference/pie/#pie-domain-column](https://plotly.com/javascript/reference/pie/#pie-domain-column) | Range of `0 - DataFrame column length` | +| **grid** |

Used to configure a pie chart. Accepts the following parameter:

row: Integer size
column: Integer size

| | +| **tableHeaderStyle** | Table properties used for configuring table header. See [full list](https://plotly.com/javascript/reference/table/#table-header) of supported arguments. | | +| **tableCellStyle** | Table properties used for configuring table cells. See [full list](https://plotly.com/javascript/reference/table/#table-header) of supported arguments | | - +## Layout Parameter - +The `layout` argument object is used to configure the overall display of a chart. See the full list of supported [arguments](https://plotly.com/javascript/reference/layout/) + +In the following example, we show how to set some basic configuration as well as layout for a line plot. + +{% tabs %} +{% tab title="React" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + + readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") + .then(df => { + + const layout = { + title: { + text: "Time series plot of AAPL open and close points", + x: 0 + }, + legend: { + bgcolor: "#fcba03", + bordercolor: "#444", + borderwidth: 1, + font: { family: "Arial", size: 10, color: "#fff" } + }, + width: 1000, + yaxis: { + title: 'AAPL open points', + }, + xaxis: { + title: 'Date', + }, + } + + const config = { + columns: ["AAPL.Open", "AAPL.Close"], //columns to plot + displayModeBar: true, + displaylogo: false, + } + df.plot("plot_div").line({ layout, config }) + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endtab %} + +{% tab title="Browser" %} +```html + + + + + + + Document + + + +
-
- - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (32).png>) + +## diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index adabd84..8a9a2e1 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -10,52 +10,131 @@ A histogram is a representation of the distribution of data. This function group ### Histogram of a Column in a DataFrame -In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js +In the example below, we make an histogram from the `Age` column in the titanic dataset. + +{% tabs %} +{% tab title="React" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { + + df['Age'].plot("plot_div").hist() + + }).catch(err => { + console.log(err); + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endtab %} -```markup +{% tab title="Browser" %} +```html - - - - - Document + + + + + Document +
-
- + }).catch(err => { + console.log(err); + }) + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (10).png>) ### Customized Histogram plots on DataFrame -```markup +{% tabs %} +{% tab title="React" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { + + const layout = { + bargap: 0, + bargroupgap: 0.1, + title: "Histogram of two columns stacked", + xaxis: { title: "Value" }, + yaxis: { title: "Count" } + } + + const sub_df = df.loc({ columns: ["Fare", "Age"] }) + sub_df.plot("plot_div").hist({ layout }) + + }).catch(err => { + console.log(err); + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; +a +``` +{% endtab %} + +{% tab title="Browser" %} +```tsx - Document @@ -64,54 +143,34 @@ In the example below, we use the titanic dataset, to show a close to a real-worl
``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (20).png>) -### Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: - -```javascript -var layout = { - title: 'A sample plot', - xaxis: { - title: 'X', - }, - yaxis: { - title: 'Y', - } -} - -df.plot("div_tag").histogram({layout: layout}) -``` - {% hint style="info" %} -For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. +For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) doc. {% endhint %} diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 79fe4d3..aa1cd50 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -10,8 +10,6 @@ description: >- ### Basic Line plot on Series -The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. - ```markup @@ -19,7 +17,6 @@ The **line** plot is exposed by the .**plot()** function called on a Series or D - Document @@ -29,7 +26,7 @@ The **line** plot is exposed by the .**plot()** function called on a Series or D
@@ -51,7 +48,6 @@ The example below shows the plot of column values against a common x-axis (index - Document @@ -61,7 +57,7 @@ The example below shows the plot of column values against a common x-axis (index
@@ -105,5 +108,5 @@ The example below shows how to plot two columns in a DataFrame against each othe ![](<../../.gitbook/assets/newplot (3).png>) {% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +To customize your plots, see the [Customize your plot page](configuring-your-plots.md) {% endhint %} diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 6dce73d..8776b7f 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -10,36 +10,70 @@ A pie plot is a proportional representation of the numerical data in a column ### Pie Chart from Columns in a DataFrame -```markup +{% tabs %} +{% tab title="React" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { DataFrame } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + const df = new DataFrame({ + Price: [19, 26, 55], + Location: ["NG", "GH", "SA"], + Type: ["Residential", "Non-Residential", "Utility"], + }); + + df.plot("plot_div").pie({ config: { values: "Price", labels: "Type" } }); + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endtab %} + +{% tab title="Browser" %} +```html + + + + - - - - - Document - + - + +
- - + +e ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (12).png>) @@ -62,14 +96,20 @@ A pie plot is a proportional representation of the numerical data in a column
@@ -81,7 +121,9 @@ A pie plot is a proportional representation of the numerical data in a column ### Configure Position of Pie Charts -If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. +If you have more than one pie chart to display, you can set the grid parameter, and also the position of each pie. + + For example, in the snippet below, we set the `grid` to 2 by 2 and also pass a set of row and column index positions. Each row/column position index corresponds to each pie. ```markup @@ -90,7 +132,6 @@ If you have more than one pie charts displayed, you can set the grid parameter, - Document @@ -106,9 +147,15 @@ If you have more than one pie charts displayed, you can set the grid parameter, Type: ['Residential', 'Non-Residential', 'Utility'] }) - df.plot("plot_div").pie({ labels: "Type", - grid: { rows: 2, columns: 2 }, - row_pos: [0, 1], col_pos: [0, 1] }) + df.plot("plot_div").pie({ + config: { + labels: "Location", + columns: ["Price", "Volume"], + columnPositions: [0, 1], + rowPositions: [0, 1], + grid: { rows: 2, columns: 2 } + } + }); diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 77649d1..92f239b 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,6 @@ In the example below, we use the titanic dataset, to show a close to real-world - Document @@ -29,13 +28,15 @@ In the example below, we use the titanic dataset, to show a close to real-world
@@ -55,7 +56,6 @@ In the example below, we use the titanic dataset, to show a close to real-world - Document @@ -65,15 +65,19 @@ In the example below, we use the titanic dataset, to show a close to real-world
@@ -84,5 +88,5 @@ In the example below, we use the titanic dataset, to show a close to real-world ![](<../../.gitbook/assets/newplot (19).png>) {% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +To customize your plots, see the [Customize your plot page](configuring-your-plots.md) {% endhint %} diff --git a/api-reference/plotting/tables.md b/api-reference/plotting/tables.md index c67f0e2..7dfc1b5 100644 --- a/api-reference/plotting/tables.md +++ b/api-reference/plotting/tables.md @@ -8,40 +8,74 @@ description: Turn DataFrame/Series in D3.js-based tables ### Create Interactive Tables from DataFrame -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { Series, readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { + + df.plot("plot_div").table() + }).catch(err => { + console.log(err); + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html + + + + + Document + - - - - - - Document - - - + +
- - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) @@ -49,47 +83,115 @@ description: Turn DataFrame/Series in D3.js-based tables To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { Series, readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV("https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv") + .then(df => { + + const headerStyle = { + align: "center", + fill: { color: ['gray'] }, + font: { family: "Arial", size: 15, color: "white" }, + + } + const cellStyle = { + align: ["center"], + line: { color: "black", width: 10 } + } + + df.plot("plot_div").table({ + config: { + tableHeaderStyle: headerStyle, + tableCellStyle: cellStyle + }, + layout: { + title: "Table displaying the Titanic dataset", + } + }) + + + }).catch(err => { + console.log(err); + }) + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html + + + + - - - - - Document - + - + +
- - + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 7bbb089..d34888e 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -8,51 +8,110 @@ description: Timeseries plot are based on date index In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV( + "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv" + ) + .then((df) => { + + const layout = { + title: "A financial charts", + xaxis: { + title: "Date", + }, + yaxis: { + title: "Count", + }, + }; + + const config = { + columns: ["AAPL.Open", "AAPL.High"], + }; + + const new_df = df.setIndex({ column: "Date" }); + new_df.plot("plot_div").line({ config, layout }); + }) + .catch((err) => { + console.log(err); + }); + + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html - - - - - - + + + + Document - - - + +
- - - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot-29- (2) (1).png>) {% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +To set customize your charts, see the [Customizing your plot page](configuring-your-plots.md) {% endhint %} diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index a3e6c11..3ea40a8 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -6,14 +6,44 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu ### Boxplot for a Series Object -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { Series } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + const s = new Series([20, 30, 40, 23, 40, 3, 50, 34, 67]) + s.plot("plot_div").violin() + + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html - Document @@ -31,19 +61,59 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (25).png>) ### Box plots on a DataFrame -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV( + "https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv" + ) + .then((df) => { + const sub_df = df.loc({ columns: ["Age", "Fare"] }); + sub_df.plot("plot_div").violin(); + }) + .catch((err) => { + console.log(err); + }); + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html - Document @@ -68,45 +138,86 @@ Make a violin plot from DataFrame columns, optionally grouped by some other colu ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (26).png>) ### Box plot for selected columns in a DataFrame -```markup +{% tabs %} +{% tab title="React" %} +{% code title="App.jsx" %} +```tsx +import { useEffect } from 'react'; +import './App.css'; +import { readCSV } from "danfojs-nightly"; + +function App() { + + useEffect(() => { + readCSV( + "https://raw.githubusercontent.com/pandas-dev/pandas/master/doc/data/titanic.csv" + ) + .then((df) => { + df.plot("plot_div").violin({ config: { x: "Survived", y: "Age" }, layout: { title: "Violin Plot" } }); + }) + .catch((err) => { + console.log(err); + }); + }, []) + + return ( +
+
+
+
+
+ ); +} + +export default App; + +``` +{% endcode %} +{% endtab %} + +{% tab title="Browser" %} +```html - - - - - - + + + + Document - + - + +
- - + + ``` +{% endtab %} +{% endtabs %} ![](<../../.gitbook/assets/newplot (27).png>) {% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) +To customize your plots, see the [Configuring your plot page](configuring-your-plots.md) {% endhint %} diff --git a/api-reference/series/README.md b/api-reference/series/README.md index 421bc63..5666bf8 100644 --- a/api-reference/series/README.md +++ b/api-reference/series/README.md @@ -8,8 +8,8 @@ description: One-dimensional ndarray with axis labels (including time series). ### Attributes -| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | -| --------------------------------- | ------------------------------------------- | +| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | +| --------------------------------- | -------------------------------------- | | [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | | ----------------------------------- | ---------------------------------------------------------------- | @@ -17,20 +17,20 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | | [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | | [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | +| [`Series.size`](broken-reference/) | Return the number of elements in the underlying data. | ### Conversion -| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | +| [`Series.asType`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | | --------------------------------------------------- | ---------------------------------------------- | | [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | ### Indexing, iteration -| | | -| ------------------------------------------------------- | ------------------------------------------------------------------ | -| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | -| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | +| | | +| --------------------------------- | ------------------------------------------------------------------ | +| ``[`Series.loc`](series.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | +| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | ### Binary operator functions @@ -48,9 +48,8 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | | [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | | [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | -| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | -### Function application & GroupBy +### Function application | [`Series.apply`](series.apply.md) | Invoke function on values of Series. | | --------------------------------- | ------------------------------------------------------- | @@ -60,12 +59,12 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | | ----------------------------------------------------------- | ---------------------------------------------------------------- | -| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | +| [`Series.corr`](broken-reference/) | Compute correlation with other Series, excluding missing values. | | [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | -| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | +| [`Series.cumMax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | +| [`Series.cumMin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | +| [`Series.cumProd`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | +| [`Series.cumSum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | | [`Series.describe`](series.describe.md) | Generate descriptive statistics. | | [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | | [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | @@ -76,44 +75,51 @@ description: One-dimensional ndarray with axis labels (including time series). | [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | | [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | | [`Series.unique`](series.unique.md) | Return unique values of Series object. | -| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value\_counts.md) | Return a Series containing counts of unique values. | +| [`Series.nUnique`](series.nunique.md) | Return number of unique elements in the object. | +| [`Series.valueCounts`](series.value\_counts.md) | Return a Series containing counts of unique values. | ### Reindexing / selection / label manipulation -| | | -| ------------------------------------------------------ | -------------------------------------------------------- | -| [`Series.drop_duplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | +| | | +| ----------------------------------------------------- | -------------------------------------------------------- | +| [`Series.dropDuplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | +| [`Series.head`](series.head.md) | Return the first n rows. | +| [`Series.resetIndex`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | +| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | +| [`Series.tail`](series.tail.md) | Return the last n rows. | ### Missing data handling | | | | ------------------------------------- | ------------------------------------------------ | -| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | -| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | -| [`Series.isna`](series.isna.md) | Detect missing values. | +| [`Series.droNa`](series.dropna.md) | Return a new Series with missing values removed. | +| [`Series.fillNa`](series.fillna.md) | Fill NaN values using the specified method. | +| [`Series.isNa`](series.isna.md) | Detect missing values. | | [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | +### Logical Comparison + +| | | +| ----------------------------- | ---------------------------------------------------------------------------------------------------- | +| [`Series.or`](series.or.md) | Returns the logical OR between Series and other. Supports element-wise operations and broadcasting. | +| [`Series.and`](series.and.md) | Returns the logical AND between Series and other. Supports element-wise operations and broadcasting. | + ### Reshaping, sorting -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| ---------------------------------------------- | ------------------------------------------------------------- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort\_values.md) | Sort by the values. | +| [`Series.argSort`](series.argsort.md) | Return the integer indices that would sort the Series values. | +| --------------------------------------------- | ------------------------------------------------------------- | +| [`Series.argMin`](series.argmin.md) | Return int position of the smallest value in the Series. | +| [`Series.argMax`](series.argmax.md) | Return int position of the largest value in the Series. | +| [`Series.sortValues`](series.sort\_values.md) | Sort by the values. | ### Accessors Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. -| Data Type | Accessor | -| --------- | -------- | -| Datetime | dt | -| String | str | +| Data Type | Accessor | +| -------------------------------------------- | -------- | +| [Datetime](../general-functions/danfo.dt.md) | dt | +| [String](../general-functions/danfo.str.md) | str | #### Datetimelike properties @@ -121,16 +127,17 @@ Danfo provides dtype-specific methods under various accessors. These are separat **Datetime methods** -| | | -| -------------------------------------------------- | ------------------------------------------------------------------ | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | -| [`Series.dt.month_name`](series.dt.month\_name.md) | Return the month names of the DateTimeIndex with specified locale. | +| | | +| -------------------------------------------------- | ----------------------------------------------------------------------- | +| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | +| [`Series.dt.month`](series.dt.month.md) | Returns a numeric representation of the month. January=0 - December=11. | +| [Series.dt.monthName](series.dt.month\_name.md) | | +| [`Series.dt.dayOfWeek`](series.dt.day.md) | Returns the day of the week, in local time | +| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | +| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | +| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | +| [`Series.dt.dayOfWeekName`](series.dt.weekdays.md) | Returns the name of the day, of the week, in local time | +| [`Series.dt.dayOfMonth`](series.dt.month\_name.md) | Returns the day of the month, in local time | #### String handling @@ -172,11 +179,13 @@ Danfo provides dtype-specific methods under various accessors. These are separat | [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | | [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | | [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | +| [`Table`](../plotting/tables.md) | Display Series as Interactive table in a Div | ### Serialization / IO / conversion -| | | -| ------------------------------------------------------ | ---------------------------------------------------- | -| [`Series.to_csv`](../dataframe/dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`Series.to_json`](../dataframe/dataframe.to\_json.md) | Convert the object to a JSON string. | +| | | +| ----------------------------------------------------- | -------------------------------------------- | +| [`Series.toCSV`](../dataframe/dataframe.to\_csv.md) | Convert DataFrame or Series to CSV. | +| [`Series.toJSON`](../dataframe/dataframe.to\_json.md) | Convert DataFrame or Series to a JSON. | +| Series.toExcel | Convert DataFrame or Series to an excel file | + diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index 3c8e4ba..b957807 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -1,44 +1,13 @@ # Creating a Series -new danfo.**Series**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. +danfo.**Series**(data, options) + +| Parameters | Type | Description | +| ---------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| data | 1D Array, 1D Tensor, JSON object. | Flat data structure to load into DataFrame | +| options | Object |

Optional configuration object. Supported properties are:

index: Array of numeric or string names for subseting array. If not specified, indexes are auto-generated.

dtypes: Array of data types for each the column. If not specified, dtypes are/is inferred.

config: General configuration object for extending or setting NDframe behavior. See full options here

| + +In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. ### Creating a Series from an object: @@ -142,7 +111,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤═══════╗ ║ 0 │ bval1 ║ ╟───┼───────╢ @@ -156,7 +125,7 @@ df.print() ### Creating a Series and specifying index and dtypes -You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. +You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. > Note: Specifing dtypes, and index on Series creation makes the process slightly faster. @@ -175,7 +144,7 @@ df.print() {% endtab %} {% endtabs %} -```text +``` ╔═══╤═══╗ ║ a │ 1 ║ ╟───┼───╢ @@ -207,4 +176,3 @@ df.print() {% hint style="info" %} **Note**: In low memory mode, less space is used by the Series. {% endhint %} - diff --git a/api-reference/series/series.abs.md b/api-reference/series/series.abs.md index 843dd5e..9f9e155 100644 --- a/api-reference/series/series.abs.md +++ b/api-reference/series/series.abs.md @@ -4,11 +4,11 @@ description: Returns the absolute value in a Series # Series.abs -> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] +> danfo.Series.**abs**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ------------------------------------- | +| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| **Returns:** Series @@ -30,23 +30,21 @@ sf.abs().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ 10 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 45 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 25 ║ +╟───┼────╢ +║ 4 │ 23 ║ +╟───┼────╢ +║ 5 │ 20 ║ +╟───┼────╢ +║ 6 │ 10 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.add.md b/api-reference/series/series.add.md index e55b1b8..5e6c583 100644 --- a/api-reference/series/series.add.md +++ b/api-reference/series/series.add.md @@ -4,7 +4,7 @@ description: Return Addition of series and other, element-wise (binary operator # Series.add -> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] +> danfo.Series.add(other, options) | Parameters | Type | Description | Default | | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -83,4 +83,3 @@ sf1.add(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.and.md b/api-reference/series/series.and.md index 85c22cb..2a7374f 100644 --- a/api-reference/series/series.and.md +++ b/api-reference/series/series.and.md @@ -6,13 +6,13 @@ description: >- # Series.and -> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] +> danfo.Series.and(other) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | -------------------- | ------- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | - **Return:** Series +**Return:** Series ### **Logical AND between two Series object** @@ -34,7 +34,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -73,7 +73,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -110,7 +110,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -129,4 +129,3 @@ res.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.append.md b/api-reference/series/series.append.md index 53e8f03..e734c08 100644 --- a/api-reference/series/series.append.md +++ b/api-reference/series/series.append.md @@ -4,19 +4,13 @@ description: Add a new value or values to the end of a Series. # Series.append -danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] +danfo.Series.**append**(newValue, index, options) | Parameters | Type | Description | Default | | ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | | newValue | Array, Series | Object to append | | | index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | -| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | - -**Returns:** - - **** return **Series** - -**** +| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | ### **Append new Series to the end of a Series** @@ -101,7 +95,6 @@ let sfArr = ["a", "b", "c"] new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) new_sf.print() - ``` {% endtab %} @@ -129,7 +122,6 @@ new_sf.print() ╟────┼───╢ ║ f7 │ c ║ ╚════╧═══╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.apply.md b/api-reference/series/series.apply.md index 7f7050e..f8a01f0 100644 --- a/api-reference/series/series.apply.md +++ b/api-reference/series/series.apply.md @@ -4,7 +4,7 @@ description: Invoke a function on each value in a Series. # Series.apply -> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] +> danfo.series.**apply**(callable, options) | Parameters | Type | Description | Default | | ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -13,9 +13,9 @@ description: Invoke a function on each value in a Series. **Returns:** - **** return **Series** +\*\*\*\* return **Series** -**** +*** **Example** @@ -42,25 +42,23 @@ sf.apply(apply_func).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╟───┼──────────────────────╢ -║ 5 │ 12 ║ -╟───┼──────────────────────╢ -║ 6 │ 14 ║ -╟───┼──────────────────────╢ -║ 7 │ 16 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 2 ║ +╟───┼────╢ +║ 1 │ 4 ║ +╟───┼────╢ +║ 2 │ 6 ║ +╟───┼────╢ +║ 3 │ 8 ║ +╟───┼────╢ +║ 4 │ 10 ║ +╟───┼────╢ +║ 5 │ 12 ║ +╟───┼────╢ +║ 6 │ 14 ║ +╟───┼────╢ +║ 7 │ 16 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} @@ -85,25 +83,23 @@ sf.apply(Math.log).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0.6931471805599453 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.0986122886681096 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.3862943611198906 ║ -╟───┼──────────────────────╢ -║ 4 │ 1.6094379124341003 ║ -╟───┼──────────────────────╢ -║ 5 │ 1.791759469228055 ║ -╟───┼──────────────────────╢ -║ 6 │ 1.9459101490553132 ║ -╟───┼──────────────────────╢ -║ 7 │ 2.0794415416798357 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════╗ +║ 0 │ 0 ║ +╟───┼────────────────────╢ +║ 1 │ 0.6931471805599453 ║ +╟───┼────────────────────╢ +║ 2 │ 1.0986122886681096 ║ +╟───┼────────────────────╢ +║ 3 │ 1.3862943611198906 ║ +╟───┼────────────────────╢ +║ 4 │ 1.6094379124341003 ║ +╟───┼────────────────────╢ +║ 5 │ 1.791759469228055 ║ +╟───┼────────────────────╢ +║ 6 │ 1.9459101490553132 ║ +╟───┼────────────────────╢ +║ 7 │ 2.0794415416798357 ║ +╚═══╧════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -130,20 +126,17 @@ sf.apply((x)=>{ {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ rice ║ -╟───┼──────────────────────╢ -║ 1 │ beans ║ -╟───┼──────────────────────╢ -║ 2 │ yam ║ -╟───┼──────────────────────╢ -║ 3 │ banana ║ -╟───┼──────────────────────╢ -║ 4 │ wheat ║ -╚═══╧══════════════════════╝ +╔═══╤════════╗ +║ 0 │ rice ║ +╟───┼────────╢ +║ 1 │ beans ║ +╟───┼────────╢ +║ 2 │ yam ║ +╟───┼────────╢ +║ 3 │ banana ║ +╟───┼────────╢ +║ 4 │ wheat ║ +╚═══╧════════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.argmax.md b/api-reference/series/series.argmax.md index d7927d2..add684d 100644 --- a/api-reference/series/series.argmax.md +++ b/api-reference/series/series.argmax.md @@ -2,9 +2,9 @@ description: Returns the int position of the largest value in the series --- -# Series.argmax +# Series.argMax -> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] +> danfo.Series.argMax() **Parameters**: None @@ -20,16 +20,15 @@ const dfd = require("danfojs-node") let data = [1,30,20,40,50,70,90,200,10,20,12] let sf = new dfd.Series(data) -sf.argmax() +sf.argMax() ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` 7 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.argmin.md b/api-reference/series/series.argmin.md index dfc661f..72fabdb 100644 --- a/api-reference/series/series.argmin.md +++ b/api-reference/series/series.argmin.md @@ -2,9 +2,9 @@ description: Returns the int position of the smallest value in the series --- -# Series.argmin +# Series.argMin -> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] +> danfo.Series.argMin() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)] **Parameters**: None @@ -20,16 +20,15 @@ const dfd = require("danfojs-node") let data = [1,30,20,40,50,70,90,200,10,20,12] let sf = new dfd.Series(data) -sf.argmin() +sf.argMin() ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text +``` 0 ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.argsort.md b/api-reference/series/series.argsort.md index b4608a4..51377f4 100644 --- a/api-reference/series/series.argsort.md +++ b/api-reference/series/series.argsort.md @@ -2,13 +2,13 @@ description: Return the integer indices that would sort the Series values --- -# Series.argsort +# Series.argSort -> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] +> danfo.Series.argSort(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | -| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------- | ---------------------------------------------------- | +| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| **Returns:** Series (int element) @@ -22,9 +22,8 @@ const dfd = require("danfojs-node") let data = [10, 45, 20, 10, 23, 20, 30, 11] let sf = new dfd.Series(data) -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - +sf.argSort().print() //defaults to ascending order +sf.argSort({ ascending: false }).print() ``` {% endtab %} {% endtabs %} @@ -32,27 +31,24 @@ sf.argsort({ ascending: false }).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 7 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 6 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 3 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 7 ║ +╟───┼───╢ +║ 3 │ 5 ║ +╟───┼───╢ +║ 4 │ 2 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 6 ║ +╟───┼───╢ +║ 7 │ 1 ║ +╚═══╧═══╝ -//sorted in descending order ╔═══╤═══╗ ║ 0 │ 1 ║ ╟───┼───╢ diff --git a/api-reference/series/series.copy.md b/api-reference/series/series.copy.md index 9bbdb47..31c7a3f 100644 --- a/api-reference/series/series.copy.md +++ b/api-reference/series/series.copy.md @@ -4,9 +4,9 @@ description: Makes a deep copy of a Series # Series.copy -> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] +> danfo.Series.copy() -**parameter:** +**parameter:** **Return:** Series diff --git a/api-reference/series/series.count.md b/api-reference/series/series.count.md index 832c794..f3ace91 100644 --- a/api-reference/series/series.count.md +++ b/api-reference/series/series.count.md @@ -1,10 +1,10 @@ --- -description: Obtain the total number of values in a series +description: Returns the total number of non-null elements in a series --- # Series.count -> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] +> danfo.Series.count() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.count()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.cummax.md b/api-reference/series/series.cummax.md index 8aded1a..3f03986 100644 --- a/api-reference/series/series.cummax.md +++ b/api-reference/series/series.cummax.md @@ -2,13 +2,13 @@ description: Returns cumulative maximum over a series --- -# Series.cummax +# Series.cumMax -> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] +> danfo.Series.**cumMax**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -21,7 +21,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf1 = new dfd.Series(data1) -sf1.cummax().print() +sf1.cumMax().print() ``` {% endtab %} {% endtabs %} @@ -29,23 +29,21 @@ sf1.cummax().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 56 ║ -╟───┼──────────────────────╢ -║ 5 │ 56 ║ -╟───┼──────────────────────╢ -║ 6 │ 56 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 45 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 3 │ 56 ║ +╟───┼────╢ +║ 4 │ 56 ║ +╟───┼────╢ +║ 5 │ 56 ║ +╟───┼────╢ +║ 6 │ 56 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.cummin.md b/api-reference/series/series.cummin.md index 736cee5..0027054 100644 --- a/api-reference/series/series.cummin.md +++ b/api-reference/series/series.cummin.md @@ -2,13 +2,13 @@ description: Returns the cumulative min of a Series --- -# Series.cummin +# Series.cumMin -> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] +> danfo.Series.**cumMin**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -21,7 +21,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 5, 23, 20, 10] let sf1 = new dfd.Series(data1) -sf1.cummin().print() +sf1.cumMin().print() ``` {% endtab %} {% endtabs %} @@ -29,23 +29,21 @@ sf1.cummin().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ 10 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 5 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 10 ║ +╟───┼────╢ +║ 2 │ 10 ║ +╟───┼────╢ +║ 3 │ 5 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 5 │ 5 ║ +╟───┼────╢ +║ 6 │ 5 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.cumprod.md b/api-reference/series/series.cumprod.md index 84ec0e7..48cf852 100644 --- a/api-reference/series/series.cumprod.md +++ b/api-reference/series/series.cumprod.md @@ -2,13 +2,13 @@ description: Return the cumulative product of a series --- -# Series.cumprod +# Series.cumProd -> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] +> danfo.Series.**cumProd**() -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -21,7 +21,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf1 = new dfd.Series(data1) -sf1.cumprod().print() +sf1.cumProd().print() ``` {% endtab %} {% endtabs %} @@ -29,23 +29,21 @@ sf1.cumprod().print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 450 ║ -╟───┼──────────────────────╢ -║ 2 │ 25200 ║ -╟───┼──────────────────────╢ -║ 3 │ 630000 ║ -╟───┼──────────────────────╢ -║ 4 │ 14490000 ║ -╟───┼──────────────────────╢ -║ 5 │ 289800000 ║ -╟───┼──────────────────────╢ -║ 6 │ 2898000000 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════╗ +║ 0 │ 10 ║ +╟───┼────────────╢ +║ 1 │ 450 ║ +╟───┼────────────╢ +║ 2 │ 25200 ║ +╟───┼────────────╢ +║ 3 │ 630000 ║ +╟───┼────────────╢ +║ 4 │ 14490000 ║ +╟───┼────────────╢ +║ 5 │ 289800000 ║ +╟───┼────────────╢ +║ 6 │ 2898000000 ║ +╚═══╧════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.cumsum.md b/api-reference/series/series.cumsum.md index 7b7a19a..32db0d0 100644 --- a/api-reference/series/series.cumsum.md +++ b/api-reference/series/series.cumsum.md @@ -2,13 +2,13 @@ description: Return a cumulative sum of a series --- -# Series.cumsum +# Series.cumSum -> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] +> danfo.Series.**cumSum**(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------- | ------------------------------------------------------ | +| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| **Example** @@ -21,7 +21,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf1 = new dfd.Series(data1) -sf1.cumsum().print() +sf1.cumSum().print() ``` {% endtab %} @@ -54,21 +54,19 @@ sf1.cumsum().print() {% endtabs %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 55 ║ -╟───┼──────────────────────╢ -║ 2 │ 111 ║ -╟───┼──────────────────────╢ -║ 3 │ 136 ║ -╟───┼──────────────────────╢ -║ 4 │ 159 ║ -╟───┼──────────────────────╢ -║ 5 │ 179 ║ -╟───┼──────────────────────╢ -║ 6 │ 189 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ 10 ║ +╟───┼─────╢ +║ 1 │ 55 ║ +╟───┼─────╢ +║ 2 │ 111 ║ +╟───┼─────╢ +║ 3 │ 136 ║ +╟───┼─────╢ +║ 4 │ 159 ║ +╟───┼─────╢ +║ 5 │ 179 ║ +╟───┼─────╢ +║ 6 │ 189 ║ +╚═══╧═════╝ ``` diff --git a/api-reference/series/series.describe.md b/api-reference/series/series.describe.md index ce52246..56472d3 100644 --- a/api-reference/series/series.describe.md +++ b/api-reference/series/series.describe.md @@ -7,7 +7,7 @@ description: >- # Series.describe -> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] +> danfo.Series.describe() **Parameters:** No parameter @@ -35,23 +35,21 @@ sf.describe().print() {% tabs %} {% tab title="Output" %} ``` -╔══════════╤══════════════════════╗ -║ │ 0 ║ -╟──────────┼──────────────────────╢ -║ count │ 6 ║ -╟──────────┼──────────────────────╢ -║ mean │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ std │ 1.8708286933869707 ║ -╟──────────┼──────────────────────╢ -║ min │ 1 ║ -╟──────────┼──────────────────────╢ -║ median │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ max │ 6 ║ -╟──────────┼──────────────────────╢ -║ variance │ 3.5 ║ -╚══════════╧══════════════════════╝ +╔══════════╤════════════════════╗ +║ count │ 6 ║ +╟──────────┼────────────────────╢ +║ mean │ 3.5 ║ +╟──────────┼────────────────────╢ +║ std │ 1.8708286933869707 ║ +╟──────────┼────────────────────╢ +║ min │ 1 ║ +╟──────────┼────────────────────╢ +║ median │ 3.5 ║ +╟──────────┼────────────────────╢ +║ max │ 6 ║ +╟──────────┼────────────────────╢ +║ variance │ 3.5 ║ +╚══════════╧════════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.div.md b/api-reference/series/series.div.md index 656a796..4bbdae8 100644 --- a/api-reference/series/series.div.md +++ b/api-reference/series/series.div.md @@ -6,7 +6,7 @@ description: >- # Series.div -> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] +> danfo.Series.div(other, options) | Parameters | Type | Description | Default | | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | diff --git a/api-reference/series/series.drop_duplicates.md b/api-reference/series/series.drop_duplicates.md index 08edf09..7023f2c 100644 --- a/api-reference/series/series.drop_duplicates.md +++ b/api-reference/series/series.drop_duplicates.md @@ -2,13 +2,13 @@ description: Remove duplicate rows --- -# Series.drop\_duplicates +# Series.dropDuplicates -> danfo.Series.**drop\_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] +> danfo.Series.dropDuplicates(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | -| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| options | Object | **keep**: "first" |

"last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

| **Returns:** Series @@ -23,7 +23,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 10, 23, 20, 10, 10] let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates() +let sf_drop = sf.dropDuplicates() sf_drop.print() ``` @@ -33,19 +33,17 @@ sf_drop.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 45 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 4 │ 23 ║ +╟───┼────╢ +║ 5 │ 20 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} @@ -59,7 +57,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 10, 23, 20, 10, 10] let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates({keep:"last"}) +let sf_drop = sf.dropDuplicates({ keep: "last" }) sf_drop.print() ``` @@ -69,19 +67,17 @@ sf_drop.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 1 │ 45 ║ +╟───┼────╢ +║ 2 │ 56 ║ +╟───┼────╢ +║ 4 │ 23 ║ +╟───┼────╢ +║ 5 │ 20 ║ +╟───┼────╢ +║ 7 │ 10 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} @@ -95,7 +91,7 @@ const dfd = require("danfojs-node") let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] let sf = new dfd.Series(data1) -sf.drop_duplicates({inplace:true}) +sf.dropDuplicates({ inplace: true }) sf.print() ``` @@ -105,17 +101,15 @@ sf.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ A ║ -╟───┼──────────────────────╢ -║ 3 │ B ║ -╟───┼──────────────────────╢ -║ 5 │ C ║ -╟───┼──────────────────────╢ -║ 7 │ D ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ A ║ +╟───┼───╢ +║ 3 │ B ║ +╟───┼───╢ +║ 5 │ C ║ +╟───┼───╢ +║ 7 │ D ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dropna.md b/api-reference/series/series.dropna.md index 2fab716..6786478 100644 --- a/api-reference/series/series.dropna.md +++ b/api-reference/series/series.dropna.md @@ -2,28 +2,24 @@ description: Remove missing values from Series --- -# Series.dropna +# Series.dropNa -> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] +> danfo.Series.dropNa(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ---------------------------------- | +| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| -**Returns**: Series - -**Examples** - -### Drop all nan value and then return New Series. +### Drop all missing values and then return New Series. {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] +let data1 = [10, 45, undefined, 10, 23, 20, null, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.dropna() +let sf_rep = sf.dropNa() sf_rep.print() ``` @@ -33,21 +29,19 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 45 ║ +╟───┼────╢ +║ 3 │ 10 ║ +╟───┼────╢ +║ 4 │ 23 ║ +╟───┼────╢ +║ 5 │ 20 ║ +╟───┼────╢ +║ 7 │ 10 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} @@ -61,7 +55,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] let sf = new dfd.Series(data1) -sf.dropna({inplace:true}) +sf.dropNa({inplace:true}) sf.print() ``` @@ -71,21 +65,19 @@ sf.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 45 ║ +╟───┼────╢ +║ 3 │ 10 ║ +╟───┼────╢ +║ 4 │ 23 ║ +╟───┼────╢ +║ 5 │ 20 ║ +╟───┼────╢ +║ 7 │ 10 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.day.md b/api-reference/series/series.dt.day.md index 6461fa5..827fd29 100644 --- a/api-reference/series/series.dt.day.md +++ b/api-reference/series/series.dt.day.md @@ -2,9 +2,9 @@ description: Obtain the numerical representation of the week day. --- -# Series.dt.day +# Series.dt.dayOfWeek -> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] +> danfo.Series.dt.dayOfWeek() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] **Parameters**: None @@ -17,10 +17,12 @@ description: Obtain the numerical representation of the week day. ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) +let data = new dfd.dateRange({"start":'2016-12-31', "end":'2018-01-08'}) let sf = new dfd.Series(data) - -sf.dt.day().print() +//print series +sf.print() +//print days of the week +sf.dt.dayOfWeek().print() ``` {% endtab %} @@ -31,6 +33,28 @@ sf.dt.day().print() {% endtabs %} ``` +╔═══╤════════════════════════╗ +║ 0 │ 12/31/2016, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 1 │ 1/1/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 2 │ 1/2/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 3 │ 1/3/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 4 │ 1/4/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 5 │ 1/5/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 6 │ 1/6/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 7 │ 1/7/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 8 │ 1/8/2017, 1:00:00 AM ║ +╟───┼────────────────────────╢ +║ 9 │ 1/9/2017, 1:00:00 AM ║ +╚═══╧════════════════════════╝ + ╔═══╤═══╗ ║ 0 │ 6 ║ ╟───┼───╢ diff --git a/api-reference/series/series.dt.hour.md b/api-reference/series/series.dt.hour.md index 16369bb..41ae2b3 100644 --- a/api-reference/series/series.dt.hour.md +++ b/api-reference/series/series.dt.hour.md @@ -2,9 +2,9 @@ description: Obtain the hours in a time series --- -# Series.dt.hour +# Series.dt.hours -> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] +> danfo.Series.dt.**hours**() **Parameters:** None @@ -17,7 +17,7 @@ description: Obtain the hours in a time series ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) +let data = new dfd.dateRange({"start":"2000-01-01", period:3, freq:"H"}) let sf = new dfd.Series(data) // print series sf.print() @@ -46,7 +46,6 @@ sf.dt.hours().print() ╟───┼───╢ ║ 1 │ 2 ║ ╚═══╧═══╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.minute.md b/api-reference/series/series.dt.minute.md index ea8bfee..e092c07 100644 --- a/api-reference/series/series.dt.minute.md +++ b/api-reference/series/series.dt.minute.md @@ -4,7 +4,7 @@ description: Obtain the minutes in a Time Series # Series.dt.minutes -> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] +> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] **Parameters**: None @@ -17,7 +17,7 @@ description: Obtain the minutes in a Time Series ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) +let data = new dfd.dateRange({"start":"2000-01-01", period:3, freq:"m"}) let sf = new dfd.Series(data) //print the series sf.print() diff --git a/api-reference/series/series.dt.month.md b/api-reference/series/series.dt.month.md index e21eeda..7337900 100644 --- a/api-reference/series/series.dt.month.md +++ b/api-reference/series/series.dt.month.md @@ -4,7 +4,7 @@ description: Obtain the month in a date time series # Series.dt.month -> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] +> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] **Parameters**: None @@ -17,7 +17,7 @@ description: Obtain the month in a date time series ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) +let data = new dfd.dateRange({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) let sf = new dfd.Series(data) sf.dt.month().print() diff --git a/api-reference/series/series.dt.month_name.md b/api-reference/series/series.dt.month_name.md index 4e83618..0029d6f 100644 --- a/api-reference/series/series.dt.month_name.md +++ b/api-reference/series/series.dt.month_name.md @@ -2,9 +2,9 @@ description: obtain the month name in a Time Series --- -# Series.dt.month\_name +# Series.dt.monthName -> danfo.Series.dt.month\_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] +> danfo.Series.dt.monthName() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] **Parameters**: None @@ -22,7 +22,7 @@ let sf = new dfd.Series(data) //print series sf.print() //print month names -sf.dt.month_name().print() +sf.dt.monthName().print() ``` {% endtab %} diff --git a/api-reference/series/series.dt.monthday.md b/api-reference/series/series.dt.monthday.md index b385f17..03f1c45 100644 --- a/api-reference/series/series.dt.monthday.md +++ b/api-reference/series/series.dt.monthday.md @@ -2,9 +2,9 @@ description: Obtain the day of the month --- -# Series.dt.monthday +# Series.dt.dayOfMonth -> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] +> danfo.Series.dt.dayOfMonth() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] **Parameters:** None @@ -17,12 +17,12 @@ description: Obtain the day of the month ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) +let data = new dfd.dateRange({"start":"2000-01-01", period:4, freq:"D"}) let sf = new dfd.Series(data) //print series sf.print() //print monthdays -sf.dt.monthday().print() +sf.dt.dayOfMonth().print() ``` {% endtab %} diff --git a/api-reference/series/series.dt.second.md b/api-reference/series/series.dt.second.md index 43330be..1ccee42 100644 --- a/api-reference/series/series.dt.second.md +++ b/api-reference/series/series.dt.second.md @@ -4,7 +4,7 @@ description: Obtain the seconds in Date series # Series.dt.seconds -> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] +> danfo.Series.dt.**seconds**() **Parameters**: None @@ -19,7 +19,7 @@ Obtain the seconds of the datetime ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) +let data = new dfd.dateRange({"start":"2000-01-01", period:3, freq:"s"}) let sf = new dfd.Series(data) //print the series frame sf.print() @@ -38,7 +38,6 @@ sf.dt.seconds().print() {% tabs %} {% tab title="Output" %} ``` - ╔═══╤══════════════════════╗ ║ 0 │ 1/1/2000, 1:00:00 AM ║ ╟───┼──────────────────────╢ @@ -54,7 +53,6 @@ sf.dt.seconds().print() ╟───┼───╢ ║ 2 │ 2 ║ ╚═══╧═══╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.dt.weekdays.md b/api-reference/series/series.dt.weekdays.md index 04dbe18..05996c3 100644 --- a/api-reference/series/series.dt.weekdays.md +++ b/api-reference/series/series.dt.weekdays.md @@ -2,9 +2,9 @@ description: Obtain the days of the weeks --- -# Series.dt.weekdays +# Series.dt.dayOfWeek -> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] +> danfo.Series.dt.dayOfWeek() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] **Parameters**: None @@ -17,12 +17,12 @@ description: Obtain the days of the weeks ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) +let data = new dfd.dateRange({"start":'2016-12-31', "end":'2018-01-08'}) let sf = new dfd.Series(data) //print series sf.print() //print days of the week -sf.dt.weekdays().print() +sf.dt.dayOfWeek().print() ``` {% endtab %} @@ -55,25 +55,25 @@ sf.dt.weekdays().print() ║ 9 │ 1/9/2017, 1:00:00 AM ║ ╚═══╧════════════════════════╝ -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ +╔═══╤═══╗ +║ 0 │ 6 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 2 ║ +╟───┼───╢ +║ 4 │ 3 ║ +╟───┼───╢ +║ 5 │ 4 ║ +╟───┼───╢ +║ 6 │ 5 ║ +╟───┼───╢ +║ 7 │ 6 ║ +╟───┼───╢ +║ 8 │ 0 ║ +╟───┼───╢ +║ 9 │ 1 ║ +╚═══╧═══╝ ``` diff --git a/api-reference/series/series.dt.year.md b/api-reference/series/series.dt.year.md index ed1117f..48fbbea 100644 --- a/api-reference/series/series.dt.year.md +++ b/api-reference/series/series.dt.year.md @@ -4,7 +4,7 @@ description: Obtain the year in a date time series # Series.dt.year -> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] +> danfo.Series.dt.**year**() **Parameters**: None @@ -17,7 +17,7 @@ description: Obtain the year in a date time series ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) +let data = new dfd.dateRange({"start":"2000-01-01", period:3, freq:"Y"}) let sf = new dfd.Series(data) sf.print() sf.dt.year().print() diff --git a/api-reference/series/series.eq.md b/api-reference/series/series.eq.md index 43a3ece..f711b5c 100644 --- a/api-reference/series/series.eq.md +++ b/api-reference/series/series.eq.md @@ -4,11 +4,11 @@ description: Check all the values in a series is equal to another value # Series.eq -> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] +> danfo.Series.eq(other) -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | ---------------- | ------- | +| other | Series, Array or number | value to compare | | **Returns**: Series (Boolean element) @@ -34,23 +34,21 @@ sf1.eq(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} @@ -73,23 +71,21 @@ sf1.eq(10).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.fillna.md b/api-reference/series/series.fillna.md index a1db3a8..b263a06 100644 --- a/api-reference/series/series.fillna.md +++ b/api-reference/series/series.fillna.md @@ -2,13 +2,14 @@ description: Replace all NaN value with specified value --- -# Series.fillna +# Series.fillNa -> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] +> danfo.Series.fillNa(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ----------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------------------------- | +| **value** | Any |

The value to replace all missing value with.

| | +| **options** | Object | **inplace**: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| **Examples** @@ -22,7 +23,7 @@ const dfd = require("danfojs-node") let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] let sf = new dfd.Series(data1) -let sf_rep = sf.fillna({ value: -999}) +let sf_rep = sf.fillNa(-999) sf_rep.print() ``` @@ -32,43 +33,41 @@ sf_rep.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ -999 ║ +╟───┼──────╢ +║ 1 │ 1 ║ +╟───┼──────╢ +║ 2 │ 2 ║ +╟───┼──────╢ +║ 3 │ 33 ║ +╟───┼──────╢ +║ 4 │ 4 ║ +╟───┼──────╢ +║ 5 │ -999 ║ +╟───┼──────╢ +║ 6 │ 5 ║ +╟───┼──────╢ +║ 7 │ 6 ║ +╟───┼──────╢ +║ 8 │ 7 ║ +╟───┼──────╢ +║ 9 │ 8 ║ +╚═══╧══════╝ ``` {% endtab %} {% endtabs %} -### Fill nan value in-place +### Fill nan value inplace {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] +let data1 = [NaN, 1, 2, 33, 4, undefined, 5, 6, 7, 8] let sf = new dfd.Series(data1) -sf.fillna({ value: -999, inplace: true }) +sf.fillNa(-999, { inplace: true }) sf.print() ``` @@ -78,29 +77,27 @@ sf.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ -999 ║ +╟───┼──────╢ +║ 1 │ 1 ║ +╟───┼──────╢ +║ 2 │ 2 ║ +╟───┼──────╢ +║ 3 │ 33 ║ +╟───┼──────╢ +║ 4 │ 4 ║ +╟───┼──────╢ +║ 5 │ -999 ║ +╟───┼──────╢ +║ 6 │ 5 ║ +╟───┼──────╢ +║ 7 │ 6 ║ +╟───┼──────╢ +║ 8 │ 7 ║ +╟───┼──────╢ +║ 9 │ 8 ║ +╚═══╧══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.ge.md b/api-reference/series/series.ge.md index 0fb1aeb..8ceae56 100644 --- a/api-reference/series/series.ge.md +++ b/api-reference/series/series.ge.md @@ -4,7 +4,7 @@ description: Check if all the values in a series is greater than or equal a valu # Series.ge -> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] +> danfo.Series.ge(other) | Parameters | Type | Description | Default | | ---------- | ----------------------- | ------------------- | ------- | @@ -14,7 +14,7 @@ description: Check if all the values in a series is greater than or equal a valu **Example** -Compare all the value in a Series to the values in another series +Compare all the values in a Series to the values in another series {% tabs %} {% tab title="Node" %} @@ -34,28 +34,26 @@ sf1.ge(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} -Check if all the value in a Series is greater than or equal a value. +Check if all the value in a Series is greater than or equal to a scalar value. {% tabs %} {% tab title="Node" %} @@ -73,23 +71,21 @@ sf1.ge(20).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.gt.md b/api-reference/series/series.gt.md index 184ca28..f76171d 100644 --- a/api-reference/series/series.gt.md +++ b/api-reference/series/series.gt.md @@ -4,7 +4,7 @@ description: Check if all the value in a series is greater than a value # Series.gt -> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] +> danfo.Series.gt(other) | Parameters | Type | Description | Default | | ---------- | ----------------------- | ------------------- | ------- | @@ -32,23 +32,21 @@ sf1.gt(20).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} @@ -73,23 +71,21 @@ sf1.gt(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.head.md b/api-reference/series/series.head.md index 2892263..1601c9e 100644 --- a/api-reference/series/series.head.md +++ b/api-reference/series/series.head.md @@ -4,13 +4,13 @@ description: Obtain the first n rows for the object based on position. # Series.head -> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] +> danfo.Series.head(rows) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of first n values | 5 | +| Parameters | Type | Description | Default | +| ---------- | ---- | ------------------------ | ------- | +| rows | Int | number of first n values | 5 | - **Return:** Series +**Return:** Series **Example** @@ -29,7 +29,7 @@ sf1.head().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤══════════════════════╗ ║ │ 0 ║ ╟───┼──────────────────────╢ @@ -46,6 +46,3 @@ sf1.head().print() ``` {% endtab %} {% endtabs %} - - - diff --git a/api-reference/series/series.iloc.md b/api-reference/series/series.iloc.md index ab7d1f3..8adadff 100644 --- a/api-reference/series/series.iloc.md +++ b/api-reference/series/series.iloc.md @@ -1,14 +1,10 @@ # Series.iloc -danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.Series.**iloc**() -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** +| Parameters | Type | Description | Default | +| ---------- | --------------------- | ---------------------------------------------------------------------- | ------- | +| rows | Array or String slice | Array, string slice, index of row positions boolean mask to filter by. | | ## **Examples** @@ -21,7 +17,7 @@ Allowed inputs are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `"1:7"` -_**Note:** only **** the start label is included, and the end label is ignored._ +_**Note:** only \*\*\*\* the start label is included, and the end label is ignored._ `.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. @@ -32,10 +28,8 @@ _**Note:** only **** the start label is included, and the end label is ignored._ ```javascript const dfd = require("danfojs-node") - let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) s.iloc([0,5]).print() - ``` {% endtab %} @@ -48,20 +42,18 @@ s.iloc([0,5]).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╚═══╧══════════════════════╝ +╔═══╤════╗ +║ 0 │ 12 ║ +╟───┼────╢ +║ 5 │ 30 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} ### **Index by a slice of row** -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. +The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. {% tabs %} {% tab title="Node" %} @@ -82,24 +74,22 @@ s.iloc(["0:5"]).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 2.2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 30 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 0 │ 12 ║ +╟───┼─────╢ +║ 1 │ 34 ║ +╟───┼─────╢ +║ 2 │ 2.2 ║ +╟───┼─────╢ +║ 3 │ 2 ║ +╟───┼─────╢ +║ 4 │ 30 ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} -By specifying a start index in a slice, all values after that index are returned. +By specifying a start index in a slice, all values after that index are returned. {% tabs %} {% tab title="Node" %} @@ -120,29 +110,27 @@ s.iloc(["5:"]).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╟───┼──────────────────────╢ -║ 6 │ 2.1 ║ -╟───┼──────────────────────╢ -║ 7 │ 7 ║ -╚═══╧══════════════════════╝ +╔═══╤═════╗ +║ 5 │ 30 ║ +╟───┼─────╢ +║ 6 │ 2.1 ║ +╟───┼─────╢ +║ 7 │ 7 ║ +╚═══╧═════╝ ``` {% endtab %} {% endtabs %} -### Slice Series by boolean condition +### Slice Series by boolean condition {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") - let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) s.iloc(s.gt(20)).print() + ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.index.md b/api-reference/series/series.index.md index 1cc95da..9a79c76 100644 --- a/api-reference/series/series.index.md +++ b/api-reference/series/series.index.md @@ -4,7 +4,7 @@ description: Obtain the index of a Series # Series.index -> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] +> danfo.Series.index **Returns**: Array @@ -25,9 +25,8 @@ console.log(sf1.index) {% tabs %} {% tab title="Output" %} -```text +``` [ 0, 1, 2, 3 ] ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.isna.md b/api-reference/series/series.isna.md index cdf6343..6dfe2e9 100644 --- a/api-reference/series/series.isna.md +++ b/api-reference/series/series.isna.md @@ -2,13 +2,13 @@ description: Detect Missing values --- -# Series.isna +# Series.isNa -> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] +> danfo.Series.isNa() **Parameters**: None -**Returns**: Series \(Boolean element\) +**Returns**: Series (Boolean element) **Example** @@ -20,26 +20,23 @@ const dfd = require("danfojs-node") let data1 = [NaN, undefined, "girl", "Man"] let sf = new dfd.Series(data1) -sf.isna().print() +sf.isNa().print() ``` {% endtab %} {% endtabs %} {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╚═══╧══════════════════════╝ +``` +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.le.md b/api-reference/series/series.le.md index 44006e2..2e1111d 100644 --- a/api-reference/series/series.le.md +++ b/api-reference/series/series.le.md @@ -4,7 +4,7 @@ description: Check if all the values in a series is less than or equal to a valu # Series.le -> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] +> danfo.Series.le(other) | Parameters | Type | Description | Default | | ---------- | ----------------------- | ------------------- | ------- | @@ -14,7 +14,7 @@ description: Check if all the values in a series is less than or equal to a valu **Example** -Check if all the values in a series is less than or equal to a value +Check if all the values in a series are less than or equal to a value {% tabs %} {% tab title="Node" %} @@ -32,23 +32,21 @@ sf1.le(20).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} @@ -73,24 +71,21 @@ sf1.le(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.loc.md b/api-reference/series/series.loc.md index 13772ab..8f9bcbb 100644 --- a/api-reference/series/series.loc.md +++ b/api-reference/series/series.loc.md @@ -4,19 +4,15 @@ description: Access a group of rows by label(s) or a boolean array. # Series.loc -danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] +danfo.Series.**loc**() -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** +| Parameters | Type | Description | Default | +| ---------- | ------------- | ---------------------------------------------------------------------- | ------- | +| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | ## **Examples** -`.loc()` is label position based (from `0` to `length-1` of the row axis). +`.loc()` is label position based (from `0` to `length-1` of the row axis). Allowed inputs are: @@ -25,7 +21,7 @@ Allowed inputs are: * A boolean mask. E.g \[ true, false, false ] * A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` -_**Note:** only **** the start label is included, and the end label is ignored._ +_**Note:** only \*\*\*\* the start label is included, and the end label is ignored._ `.loc` will raise a `ValueEror` if a requested label is not found. @@ -43,7 +39,6 @@ let s = new dfd.Series(data, { index }) s.print() s.loc(["a", "g"]).print() - ``` {% endtab %} @@ -85,7 +80,7 @@ s.loc(["a", "g"]).print() ### **Index by a slice of row** -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. +The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. {% tabs %} {% tab title="Node" %} @@ -125,14 +120,14 @@ s.loc([`"a":"e"`]).print() {% hint style="info" %} Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -`s.loc([a:e]).print()`\ +`s.loc(["a:e"]).print()`\ For the slice above to work, you must quote each slice, e.g:\ `s.loc(["a":"e"]).print()`\ \ _**Inner quotes are not needed for numeric indices!**_ {% endhint %} -### By specifying a start index in a slice, all values after that index are returned. +### By specifying a start index in a slice, all values after that index are returned. {% tabs %} {% tab title="Node" %} @@ -168,12 +163,11 @@ s.loc([`1:`]).print() ╟───┼─────╢ ║ 7 │ 7 ║ ╚═══╧═════╝ - ``` {% endtab %} {% endtabs %} -### Slice Series by boolean condition +### Slice Series by boolean condition {% tabs %} {% tab title="Node" %} diff --git a/api-reference/series/series.lt.md b/api-reference/series/series.lt.md index 7af18bc..0807c50 100644 --- a/api-reference/series/series.lt.md +++ b/api-reference/series/series.lt.md @@ -4,7 +4,7 @@ description: Check if all values in a Series are less than a value. # Series.lt -> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] +> danfo.Series.lt(other) | Parameters | Type | Description | Default | | ---------- | ----------------------- | ------------------- | ------- | @@ -32,23 +32,21 @@ sf1.lt(20).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ true ║ +╟───┼───────╢ +║ 1 │ false ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ false ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} @@ -73,24 +71,21 @@ sf1.lt(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ - +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ false ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ false ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.map.md b/api-reference/series/series.map.md index 0e0850a..13ea329 100644 --- a/api-reference/series/series.map.md +++ b/api-reference/series/series.map.md @@ -4,7 +4,7 @@ description: Map the value of a series to a function or Object # Series.map -> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] +> danfo.series.**map**(callable) | Parameter | Type | Description | Default | | --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -13,7 +13,7 @@ description: Map the value of a series to a function or Object **Example** -Mapping the element in a Series words in an Object +Mapping the element in a Series words in an Object {% tabs %} {% tab title="Node" %} @@ -23,7 +23,6 @@ const dfd = require("danfojs-node") let sf = new dfd.Series([1, 2, 3, 4]) let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } sf.map(map).print() - ``` {% endtab %} @@ -36,17 +35,15 @@ sf.map(map).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ ok ║ -╟───┼──────────────────────╢ -║ 1 │ okie ║ -╟───┼──────────────────────╢ -║ 2 │ frit ║ -╟───┼──────────────────────╢ -║ 3 │ gop ║ -╚═══╧══════════════════════╝ +╔═══╤══════╗ +║ 0 │ ok ║ +╟───┼──────╢ +║ 1 │ okie ║ +╟───┼──────╢ +║ 2 │ frit ║ +╟───┼──────╢ +║ 3 │ gop ║ +╚═══╧══════╝ ``` {% endtab %} {% endtabs %} @@ -63,7 +60,6 @@ let sf = new dfd.Series([1,2,3,4]) sf.map((x)=>{ return `I have ${x} cat(s)` }).print() - ``` {% endtab %} @@ -76,17 +72,15 @@ sf.map((x)=>{ {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ I have 1 cat(s) ║ -╟───┼──────────────────────╢ -║ 1 │ I have 2 cat(s) ║ -╟───┼──────────────────────╢ -║ 2 │ I have 3 cat(s) ║ -╟───┼──────────────────────╢ -║ 3 │ I have 4 cat(s) ║ -╚═══╧══════════════════════╝ +╔═══╤═════════════════╗ +║ 0 │ I have 1 cat(s) ║ +╟───┼─────────────────╢ +║ 1 │ I have 2 cat(s) ║ +╟───┼─────────────────╢ +║ 2 │ I have 3 cat(s) ║ +╟───┼─────────────────╢ +║ 3 │ I have 4 cat(s) ║ +╚═══╧═════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.max.md b/api-reference/series/series.max.md index 4f7193a..3b8d696 100644 --- a/api-reference/series/series.max.md +++ b/api-reference/series/series.max.md @@ -4,7 +4,7 @@ description: Obtain the maximum value in a Series # Series.max -> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] +> danfo.Series.max() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.max()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.maximum.md b/api-reference/series/series.maximum.md index afc5a48..da34106 100644 --- a/api-reference/series/series.maximum.md +++ b/api-reference/series/series.maximum.md @@ -4,11 +4,11 @@ description: Obtain the maximum number between two series # Series.maximum -> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] +> danfo.Series.maximum(other) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------- | ------- | +| other | Series | series to match | | **Return:** {Series} @@ -30,21 +30,17 @@ sf1.maximum(sf2).print() {% tabs %} {% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 41 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 0 │ 30 ║ +╟───┼────╢ +║ 1 │ 41 ║ +╟───┼────╢ +║ 2 │ 3 ║ +╟───┼────╢ +║ 3 │ 5 ║ +╚═══╧════╝ + ``` {% endtab %} {% endtabs %} - - - diff --git a/api-reference/series/series.mean.md b/api-reference/series/series.mean.md index 17d97e6..29d23a4 100644 --- a/api-reference/series/series.mean.md +++ b/api-reference/series/series.mean.md @@ -1,10 +1,10 @@ --- -description: Obtain the mean of a series +description: Returns the mean of a series --- # Series.mean -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] +> danfo.Series.mean() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.mean()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.median.md b/api-reference/series/series.median.md index d1cde75..b1b8524 100644 --- a/api-reference/series/series.median.md +++ b/api-reference/series/series.median.md @@ -1,10 +1,10 @@ --- -description: Obtain the median of a series +description: Returns the median of a series --- # Series.median -> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] +> danfo.Series.median() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.median()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.min.md b/api-reference/series/series.min.md index 6e11a67..2ec7533 100644 --- a/api-reference/series/series.min.md +++ b/api-reference/series/series.min.md @@ -4,7 +4,7 @@ description: Obtain the minimum value in a series # Series.min -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] +> danfo.Series.min() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.min()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.minimum.md b/api-reference/series/series.minimum.md index a06ba69..0be491f 100644 --- a/api-reference/series/series.minimum.md +++ b/api-reference/series/series.minimum.md @@ -1,14 +1,14 @@ --- -description: Obtain the minimum value between two series (element wise) +description: Return the minimum between two series (element wise) --- # Series.minimum -> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] +> danfo.Series.minimum(other) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------- | ------- | +| other | Series | series to match | | **Return:** {Series} @@ -30,19 +30,16 @@ sf1.minimum(sf2).print() {% tabs %} {% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 40 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 0 │ 10 ║ +╟───┼────╢ +║ 1 │ 40 ║ +╟───┼────╢ +║ 2 │ 2 ║ +╟───┼────╢ +║ 3 │ 0 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.mod.md b/api-reference/series/series.mod.md index fdf0555..0f8a584 100644 --- a/api-reference/series/series.mod.md +++ b/api-reference/series/series.mod.md @@ -1,10 +1,10 @@ --- -description: Return Modulo of series and other, element-wise (binary operator mod). +description: Returns Modulo of series and other, element-wise (binary operator mod). --- # Series.mod -> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] +> danfo.Series.mod(other, options) | Parameters | Type | Description | Default | | ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -34,17 +34,15 @@ sf1.mod(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.8999999761581421 ║ -╟───┼──────────────────────╢ -║ 1 │ 1.3999993801116943 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.7000000476837158 ║ -╟───┼──────────────────────╢ -║ 3 │ 0.19999980926513672 ║ -╚═══╧══════════════════════╝ +╔═══╤═════════════════════╗ +║ 0 │ 0.8999999999999999 ║ +╟───┼─────────────────────╢ +║ 1 │ 1.3999999999999977 ║ +╟───┼─────────────────────╢ +║ 2 │ 0.7000000000000002 ║ +╟───┼─────────────────────╢ +║ 3 │ 0.20000000000000018 ║ +╚═══╧═════════════════════╝ ``` {% endtab %} {% endtabs %} @@ -67,19 +65,17 @@ sf1.mod(2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╚═══╧══════════════════════╝ +╔═══╤═══╗ +║ 0 │ 1 ║ +╟───┼───╢ +║ 1 │ 0 ║ +╟───┼───╢ +║ 2 │ 1 ║ +╟───┼───╢ +║ 3 │ 0 ║ +╟───┼───╢ +║ 4 │ 1 ║ +╚═══╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.mode.md b/api-reference/series/series.mode.md index 6077686..24317e9 100644 --- a/api-reference/series/series.mode.md +++ b/api-reference/series/series.mode.md @@ -1,10 +1,10 @@ --- -description: Obtain the center value in a series +description: Returns the mode of elements in a series --- # Series.mode -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] +> danfo.Series.mode() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.mode()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.mul.md b/api-reference/series/series.mul.md index d5d33de..fed6958 100644 --- a/api-reference/series/series.mul.md +++ b/api-reference/series/series.mul.md @@ -4,7 +4,7 @@ description: Return Multiplication of series and other, element-wise (binary ope # Series.mul -> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] +> danfo.Series.mul(other, options) | Parameters | Type | Description | Default | | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -83,4 +83,3 @@ sf1.mul(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.ndim.md b/api-reference/series/series.ndim.md index 8623e80..9981c95 100644 --- a/api-reference/series/series.ndim.md +++ b/api-reference/series/series.ndim.md @@ -4,7 +4,7 @@ description: Obtain the dimension of a series # Series.ndim -> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] +> danfo.Series.ndim **Parameters:** None diff --git a/api-reference/series/series.ne.md b/api-reference/series/series.ne.md index 16cf1dc..5cb2173 100644 --- a/api-reference/series/series.ne.md +++ b/api-reference/series/series.ne.md @@ -4,11 +4,11 @@ description: Check if all values in a series is not equal to a value(s) # Series.ne -> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] +> danfo.Series.ne(other) -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | +| Parameters | Type | Description | Default | +| ---------- | ----------------------- | --------------------- | ------- | +| other | Series, Array or number | value to compare with | | **Returns**: Series (Boolean element) @@ -34,23 +34,21 @@ sf1.ne(sf2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ false ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ true ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} @@ -73,23 +71,21 @@ sf1.ne(10).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ false ║ +╟───┼───────╢ +║ 1 │ true ║ +╟───┼───────╢ +║ 2 │ true ║ +╟───┼───────╢ +║ 3 │ true ║ +╟───┼───────╢ +║ 4 │ true ║ +╟───┼───────╢ +║ 5 │ true ║ +╟───┼───────╢ +║ 6 │ false ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.nunique.md b/api-reference/series/series.nunique.md index 092a2eb..55fe86b 100644 --- a/api-reference/series/series.nunique.md +++ b/api-reference/series/series.nunique.md @@ -2,9 +2,9 @@ description: Returns the number of unique values in a series --- -# Series.nunique +# Series.nUnique -> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] +> danfo.Series.nUnique() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] **Parameters**: None @@ -20,7 +20,7 @@ const dfd = require("danfojs-node") let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] let sf = new dfd.Series(data1) -console.log(sf.nunique()) +console.log(sf.nUnique()) ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.or.md b/api-reference/series/series.or.md index 948c61d..a7af323 100644 --- a/api-reference/series/series.or.md +++ b/api-reference/series/series.or.md @@ -6,13 +6,13 @@ description: >- # Series.or -> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] +> danfo.Series.**or**(other) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | +| Parameters | Type | Description | Default | +| ---------- | -------------------------------- | -------------------- | ------- | +| other | Series, Scalar, Array of Scalars | Data to compare with | | - **Return:** Series +**Return:** Series ### **Logical OR between two Series object** @@ -34,7 +34,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -73,7 +73,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -110,7 +110,7 @@ res.print() {% tabs %} {% tab title="Output" %} -```text +``` ╔═══╤═══════╗ ║ 0 │ false ║ ╟───┼───────╢ @@ -129,4 +129,3 @@ res.print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.pow.md b/api-reference/series/series.pow.md index 2fbe542..761d60b 100644 --- a/api-reference/series/series.pow.md +++ b/api-reference/series/series.pow.md @@ -1,12 +1,12 @@ --- description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). + Returns the exponential power of series and other, element-wise (binary + operator pow). --- # Series.pow -> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] +> danfo.Series.pow(other, options) | Parameters | Type | Description | Default | | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | diff --git a/api-reference/series/series.replace.md b/api-reference/series/series.replace.md index 8a1f48b..3ad3402 100644 --- a/api-reference/series/series.replace.md +++ b/api-reference/series/series.replace.md @@ -4,11 +4,13 @@ description: Replace values given in replace param with value # Series.replace -> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] +> danfo.Series.**replace**(oldValue, newValue, options) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| +| Parameters | Type | Description | Default | +| ------------ | ------ | --------------------------------------------------------------------------------- | ------------------------------------- | +| **oldValue** | Any |

The value you want to replace.

| | +| **newValue** | Any | The new value you want to replace with. | | +| options | Object | **inplace**: Boolean, indicating whether to perform the operation inplace or not. |

{

inplace: false

}

| **Returns**: Series @@ -23,7 +25,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) +let sf_rep = sf.replace(10, -50) sf_rep.print() ``` @@ -48,7 +50,6 @@ sf_rep.print() ╟───┼─────╢ ║ 6 │ -50 ║ ╚═══╧═════╝ - ``` {% endtab %} {% endtabs %} @@ -62,7 +63,7 @@ const dfd = require("danfojs-node") let data1 = [10, 45, 56, 25, 23, 20, 10] let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) +sf.replace(10, -50, { inplace: true}) sf.print() ``` @@ -85,5 +86,4 @@ sf.print() ╟───┼─────╢ ║ 6 │ -50 ║ ╚═══╧═════╝ - ``` diff --git a/api-reference/series/series.reset_index.md b/api-reference/series/series.reset_index.md index c51497a..7f46d6f 100644 --- a/api-reference/series/series.reset_index.md +++ b/api-reference/series/series.reset_index.md @@ -2,17 +2,15 @@ description: Reset the index of a series. --- -# Series.reset\_index +# Series.resetIndex -> danfo.series.reset\_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] +> danfo.series.resetIndex(options) -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | +| Parameters | Type | Description | Default | +| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ---------------- | +| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | -**Returns :** Series - -`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. +`resetIndex` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. ### **Reset index to default values** @@ -24,7 +22,7 @@ let data = [20, 30, 40] let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) sf.print() -let sf_reset = sf.reset_index() +let sf_reset = sf.resetIndex() sf_reset.print() ``` {% endtab %} @@ -66,9 +64,8 @@ let data = [1, 2, 3, 4, 5, 6] let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) sf.print() -sf.reset_index({ inplace: true }) +sf.resetIndex({ inplace: true }) sf.print() - ``` {% endtab %} diff --git a/api-reference/series/series.round.md b/api-reference/series/series.round.md index b6f0d82..6b05e45 100644 --- a/api-reference/series/series.round.md +++ b/api-reference/series/series.round.md @@ -4,7 +4,7 @@ description: round off floating values in series # Series.round -> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] +> danfo.Series.round(dp, options) | Parameters | Type | Description | Default | | ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -31,18 +31,15 @@ sf1.round(2).print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.19 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.56 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.02 ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ 0 │ 30.21 ║ +╟───┼───────╢ +║ 1 │ 40.19 ║ +╟───┼───────╢ +║ 2 │ 3.56 ║ +╟───┼───────╢ +║ 3 │ 5.02 ║ +╚═══╧═══════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.sample.md b/api-reference/series/series.sample.md index a28298d..368f549 100644 --- a/api-reference/series/series.sample.md +++ b/api-reference/series/series.sample.md @@ -1,33 +1,33 @@ --- -description: Return a random sample of items from an axis of object. +description: Returns a random sample of items from an axis of object. --- # Series.sample -> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] +> danfo.Series.sample(num) -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| num | Int | The number of rows to return. | | -| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| num | Int | The number of rows to return. | | +| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| **Returns:** - **** return **{Promies} resolves to Series** +\*\*\*\* return **{Promies} resolves to Series** **Example** ```javascript const dfd = require("danfojs-node") -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5) - sample.print() - +async function sample_data() { + let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; + let sf1 = new dfd.Series(data1); + let sample = await sf1.sample(5) + sample.print() + } -load_data() +sample_data() ``` {% tabs %} @@ -53,13 +53,12 @@ load_data() ```javascript const dfd = require("danfojs-node") -async function load_data() { +async function sample_data() { let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5, { seed: 2 }) + let sample = await sf1.sample(5, { seed: 5 }) sample.print() } -load_data() - +sample_data() ``` diff --git a/api-reference/series/series.set_index.md b/api-reference/series/series.set_index.md index 3de352f..c8cd012 100644 --- a/api-reference/series/series.set_index.md +++ b/api-reference/series/series.set_index.md @@ -2,9 +2,9 @@ description: Assign new Index to Series --- -# Series.set\_index +# Series.setIndex -> danfo.series.**set\_index(**options**)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] +> danfo.series.setIndex**(options)** | Parameter | Type | Description | Default | | --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -19,11 +19,12 @@ description: Assign new Index to Series {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") + let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] let sf = new dfd.Series(data) sf.print() -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) +let sf_new = sf.setIndex(["one", "two", "three"]) sf_new.print() ``` {% endtab %} @@ -63,7 +64,7 @@ const dfd = require("danfojs-node") let data = ["Humans","Life","Meaning","Fact","Truth"] let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) +let sf_new = sf.setIndex(["H", "L", "M","F","T"]) sf_new.print() ``` {% endtab %} @@ -77,19 +78,17 @@ sf_new.print() {% tabs %} {% tab title="Output" %} ``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ H │ Humans ║ -╟───┼──────────────────────╢ -║ L │ Life ║ -╟───┼──────────────────────╢ -║ M │ Meaning ║ -╟───┼──────────────────────╢ -║ F │ Fact ║ -╟───┼──────────────────────╢ -║ T │ Truth ║ -╚═══╧══════════════════════╝ +╔═══╤═════════╗ +║ H │ Humans ║ +╟───┼─────────╢ +║ L │ Life ║ +╟───┼─────────╢ +║ M │ Meaning ║ +╟───┼─────────╢ +║ F │ Fact ║ +╟───┼─────────╢ +║ T │ Truth ║ +╚═══╧═════════╝ ``` {% endtab %} {% endtabs %} @@ -103,7 +102,7 @@ const dfd = require("danfojs") let data = [1, 2, 3, 4, 5, 6] let sf = new dfd.Series(data) -sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) +sf.setIndex(["one", "two", "three", "four", "five", "six"], { inplace: true }) sf.print() ``` {% endtab %} @@ -130,7 +129,6 @@ sf.print() ╟───────┼───╢ ║ six │ 6 ║ ╚═══════╧═══╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.shape.md b/api-reference/series/series.shape.md index 9eb5031..feb93b9 100644 --- a/api-reference/series/series.shape.md +++ b/api-reference/series/series.shape.md @@ -4,11 +4,11 @@ description: Obtain the shape of a Series # Series.shape -> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] +> danfo.Series.shape **Parameters**: None -**Returns**: Array \[int, int\] +**Returns**: Array \[int, int] **Example** @@ -27,9 +27,8 @@ console.log(sf1.shape) {% tabs %} {% tab title="Output" %} -```text +``` [ 4, 1 ] ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.sort_values.md b/api-reference/series/series.sort_values.md index 5c7e5fa..8933511 100644 --- a/api-reference/series/series.sort_values.md +++ b/api-reference/series/series.sort_values.md @@ -2,17 +2,17 @@ description: Sorts a Series in ascending or descending order --- -# Series.sort_values +# Series.sortValues -> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] +> danfo.Series.sortValues(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] | Parameters | Type | Description | Default | | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | | options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| - **Return:** Series +**Return:** Series -### Sort values in a Series +### Sort values in a Series {% tabs %} {% tab title="Node" %} @@ -21,7 +21,7 @@ const dfd = require("danfojs-node") let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] let sf1 = new dfd.Series(data1) -let sf2 = sf1.sort_values() +let sf2 = sf1.sortValues() sf2.print() ``` @@ -54,7 +54,7 @@ sf2.print() {% endtab %} {% endtabs %} -### Sort Series in-place +### Sort Series inplace {% tabs %} {% tab title="Node" %} @@ -92,7 +92,6 @@ sf1.print() ╟───┼────╢ ║ 6 │ 89 ║ ╚═══╧════╝ - ``` {% endtab %} {% endtabs %} @@ -106,7 +105,7 @@ const dfd = require("danfojs-node") let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] let sf1 = new dfd.Series(data1) -sf1.sort_values({ "ascending": false, "inplace": true }) +sf1.sortValues({ "ascending": false, "inplace": true }) sf1.print() ``` diff --git a/api-reference/series/series.std.md b/api-reference/series/series.std.md index aa05018..13801e5 100644 --- a/api-reference/series/series.std.md +++ b/api-reference/series/series.std.md @@ -4,7 +4,7 @@ description: Obtain the standard deviation for a series # Series.std -> danfo.Series.std() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)] +> danfo.Series.std() **Parameter:** None @@ -33,5 +33,4 @@ console.log(sf1.std()) {% endtab %} {% endtabs %} - **** - +\*\*\*\* diff --git a/api-reference/series/series.str.split.md b/api-reference/series/series.str.split.md index 006795d..57c1d2c 100644 --- a/api-reference/series/series.str.split.md +++ b/api-reference/series/series.str.split.md @@ -6,17 +6,13 @@ description: >- # Series.str.split -> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] +> danfo.Series.str.**split**(splitVal, options) | Parameters | Type | Description | Default | | ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | | splitVal | String | separator or delimiter used to split the string | " " | | options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| -**Returns** - - return **Series** - **Examples** Split the string value in the Series by space and obtain the Series values @@ -38,7 +34,7 @@ console.log(sf.str.split().values) {% endtab %} {% endtabs %} -**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` +**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` {% tabs %} {% tab title="JavaScript" %} diff --git a/api-reference/series/series.sub.md b/api-reference/series/series.sub.md index e281d06..8a367f6 100644 --- a/api-reference/series/series.sub.md +++ b/api-reference/series/series.sub.md @@ -4,7 +4,7 @@ description: Return Subtraction of series and other, element-wise (binary operat # Series.sub -> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] +> danfo.Series.sub(other, options) | Parameters | Type | Description | Default | | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | @@ -83,4 +83,3 @@ sf1.sub(2).print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.sum.md b/api-reference/series/series.sum.md index fabcba7..2abfcaf 100644 --- a/api-reference/series/series.sum.md +++ b/api-reference/series/series.sum.md @@ -4,7 +4,7 @@ description: Return the sum of the values in a series. # Series.sum -> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] +> danfo.Series.sum() **Parameter:** None @@ -33,4 +33,4 @@ console.log(sf1.sum()) {% endtab %} {% endtabs %} -**** +*** diff --git a/api-reference/series/series.tail.md b/api-reference/series/series.tail.md index 7f986a1..88bb5f4 100644 --- a/api-reference/series/series.tail.md +++ b/api-reference/series/series.tail.md @@ -4,13 +4,13 @@ description: Prints the last n values in a Series # Series.tail -> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] +> danfo.Series.tail(rows) -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of last n values | 5 | +| Parameters | Type | Description | Default | +| ---------- | ---- | ----------------------- | ------- | +| rows | Int | number of last n values | 5 | - **Return:** Series +**Return:** Series **Example** @@ -29,7 +29,7 @@ sf1.tail().print() {% tabs %} {% tab title="Output" %} -```text +``` ╔════╤══════════════════════╗ ║ │ 0 ║ ╟────┼──────────────────────╢ @@ -46,4 +46,3 @@ sf1.tail().print() ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.tensor.md b/api-reference/series/series.tensor.md index a5c112c..698f743 100644 --- a/api-reference/series/series.tensor.md +++ b/api-reference/series/series.tensor.md @@ -4,7 +4,7 @@ description: Obtain the tensor representation of the values in a Series # Series.tensor -> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] +> danfo.Series.tensor **Parameters**: None @@ -27,7 +27,7 @@ console.log(sf1.tensor) {% tabs %} {% tab title="Output" %} -```text +``` Tensor { kept: false, isDisposedInternal: false, @@ -43,4 +43,3 @@ Tensor { ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.unique.md b/api-reference/series/series.unique.md index c89d187..e3128e1 100644 --- a/api-reference/series/series.unique.md +++ b/api-reference/series/series.unique.md @@ -4,7 +4,7 @@ description: Obtain the unique value in a Series # Series.unique -> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] +> danfo.Series.**unique**() **Parameters**: None @@ -27,29 +27,26 @@ sf.unique().print() {% tabs %} {% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╟───┼──────────────────────╢ -║ 6 │ 7 ║ -╟───┼──────────────────────╢ -║ 7 │ 8 ║ -╟───┼──────────────────────╢ -║ 8 │ 22 ║ -╚═══╧══════════════════════╝ +``` +╔═══╤════╗ +║ 0 │ 1 ║ +╟───┼────╢ +║ 1 │ 2 ║ +╟───┼────╢ +║ 2 │ 3 ║ +╟───┼────╢ +║ 3 │ 4 ║ +╟───┼────╢ +║ 4 │ 5 ║ +╟───┼────╢ +║ 5 │ 6 ║ +╟───┼────╢ +║ 6 │ 7 ║ +╟───┼────╢ +║ 7 │ 8 ║ +╟───┼────╢ +║ 8 │ 22 ║ +╚═══╧════╝ ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.value_counts.md b/api-reference/series/series.value_counts.md index 338064f..007fc15 100644 --- a/api-reference/series/series.value_counts.md +++ b/api-reference/series/series.value_counts.md @@ -2,9 +2,9 @@ description: Count the number of occurrence for each element in a Series --- -# Series.value\_counts +# Series.valueCounts -> danfo.Series.value\_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] +> danfo.Series.valueCounts() **Parameters:** None @@ -20,7 +20,7 @@ const dfd = require("danfojs-node") let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] let sf = new dfd.Series(data1) -sf.value_counts().print() +sf.valueCounts().print() ``` {% endtab %} {% endtabs %} @@ -28,27 +28,25 @@ sf.value_counts().print() {% tabs %} {% tab title="Output" %} ``` -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 1 │ 3 ║ -╟────┼──────────────────────╢ -║ 2 │ 1 ║ -╟────┼──────────────────────╢ -║ 3 │ 1 ║ -╟────┼──────────────────────╢ -║ 4 │ 1 ║ -╟────┼──────────────────────╢ -║ 5 │ 4 ║ -╟────┼──────────────────────╢ -║ 6 │ 1 ║ -╟────┼──────────────────────╢ -║ 7 │ 1 ║ -╟────┼──────────────────────╢ -║ 8 │ 2 ║ -╟────┼──────────────────────╢ -║ 22 │ 1 ║ -╚════╧══════════════════════╝ +╔════╤═══╗ +║ 1 │ 3 ║ +╟────┼───╢ +║ 2 │ 1 ║ +╟────┼───╢ +║ 3 │ 1 ║ +╟────┼───╢ +║ 4 │ 1 ║ +╟────┼───╢ +║ 5 │ 4 ║ +╟────┼───╢ +║ 6 │ 1 ║ +╟────┼───╢ +║ 7 │ 1 ║ +╟────┼───╢ +║ 8 │ 2 ║ +╟────┼───╢ +║ 22 │ 1 ║ +╚════╧═══╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/series/series.values.md b/api-reference/series/series.values.md index 4857487..e34e113 100644 --- a/api-reference/series/series.values.md +++ b/api-reference/series/series.values.md @@ -4,11 +4,11 @@ description: Obtain the values in a series # Series.values -> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] +> danfo.Series.values **Parameters:** None -**Returns**: Array +**Returns**: Array **Example** @@ -27,9 +27,8 @@ console.log(sf1.values) {% tabs %} {% tab title="Output" %} -```text +``` [ 30.21091, 40.190901, 3.564, 5.0212 ] ``` {% endtab %} {% endtabs %} - diff --git a/api-reference/series/series.var.md b/api-reference/series/series.var.md index 4fdcbc2..b28bf5a 100644 --- a/api-reference/series/series.var.md +++ b/api-reference/series/series.var.md @@ -4,7 +4,7 @@ description: Calculate the variance of a Series # Series.var -> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] +> danfo.Series.var() **Parameter:** None @@ -27,9 +27,8 @@ console.log(sf1.var()) {% tabs %} {% tab title="Output" %} -```text +``` 968.25 ``` {% endtab %} {% endtabs %} - diff --git a/contributing-guide.md b/contributing-guide.md index 4fedc98..60f4f4b 100644 --- a/contributing-guide.md +++ b/contributing-guide.md @@ -29,80 +29,67 @@ description: >- ## TL:DR -All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome. +All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome. -For contributors familiar with open-source, below is a quick guide to setting up danfojs locally. +For contributors familiar with open-source, below is a quick guide to setting up danfojs locally. ``` -git clone https://github.com/opensource9ja/danfojs.git +git clone https://github.com/javascriptdata/danfojs.git cd danfojs git checkout -b ``` -There are two folders, **danfojs-browser** and **danfojs-node**. If you are contributing a new feature, then you should include it in both versions. If you are doing a bug fix for a single version, then open that folder and install packages. +There are three main folders in the `src` folder, **danfojs-base**, **danfojs-browser,** and **danfojs-node**. -For instance, if I want to do some bug fixes in danfojs-node. I can do the following: - -``` -cd danfojs-node -yarn ##install all packages -``` - -Add my bug fixes and ensure test passes: - -``` -yarn test ## run test -``` +The **danfojs-base** folder holds all shared classes, modules, and functions used by both danfojs-browser and danfojs-node. So features or bug fixes that work the same way in both versions will generally be done in the **danfojs-base** folder. ## Where to start? -For first time contributors, you can find pending issues on the GitHub “issues” page. There are a number of issues listed and "good first issue" where you could start out. Once you’ve found an interesting issue, and have an improvement in mind, next thing is to set up your development environment. +For first-time contributors, you can find pending issues on the GitHub “issues” page. There are a number of issues listed and "good first issue" where you could start out. Once you’ve found an interesting issue, and have an improvement in mind, next thing is to set up your development environment. ## Working with the code -Now that you have an issue you want to fix, an enhancement to add, or documentation to improve, you need to learn how to work with GitHub and the danfojs code base. +If you have an issue you want to fix, an enhancement to add, or documentation to improve, you need to learn how to work with GitHub and the Danfojs code base. ### **Version control, Git, and GitHub** -The danfojs code is hosted on GitHub. To contribute you will need to sign up for a free GitHub account. We use Git for version control to allow many people to work together on this project. +Danfojs code is hosted on GitHub. To contribute you will need to sign up for a free GitHub account. We use Git for version control to allow many people to work together on this project. Some great resources for learning Git: * Official [GitHub pages](http://help.github.com). -### **Getting started with Git¶** +### **Getting started with Git** Find [Instructions](http://help.github.com/set-up-git-redirect) for installing git, setting up your SSH key, and configuring git. These steps need to be completed before you can work seamlessly between your local repository and GitHub. -## **Forking the danfojs repo** +## **Forking the Danfojs repo** You will need your own fork to work on the code. Go to the danfojs [project page](https://github.com/opensource9ja/danfojs) and hit the Fork button. Next, you will clone your fork to your local machine: ``` -git clone https://github.com/opensource9ja/danfojs.git +git clone https://github.com/javascriptdata/danfojs.git cd danfojs ``` This creates the directory danfojs and connects your repository to the upstream (main project) repository. -> **All development are done in two folders--**[**danfojs-browser**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-browser) **and** [**danfojs-node**](https://github.com/opensource9ja/danfojs/tree/master/danfojs-node) **folders. The two folders are similar and it is always recommended to pull latest changes from master before development in any of the folder.** +Some Javascript features are supported both in the browser and node environment, and it is recommended to add features in the **danfojs-base** folder. + +For features that work differently or only in a specific environment, you can add them in the corresponding danfojs-node or danfojs-browser folder. -Some Javascript features are supported both in the browser and node environment, and it is recommended to add these to both versions. -For features that work only in NodeJs environment, especially file related issues, these should be developed and tested in the danfojs-node folder, and the corresponding tests are written there. ## **Creating a development environment** To test out code changes, you’ll need to build danfojs, which requires a Nodejs environment. ```python -git clone https://github.com/opensource9ja/danfojs.git +git clone https://github.com/javascriptdata/danfojs.git cd danfojs -cd danfojs-browser && yarn ## installs required packages in browser version -cd .. && cd danfojs-node && yarn ## installs required packages in node version -cd .. ## Go back to root folder +yarn install ## automatically installs all required packages yarn test ##Runs test in both node and browser folder ``` @@ -127,10 +114,9 @@ function add_series(series1, series2){ return new Series() } - ``` -And for functions that contain more than two argument, keyword argument should be used. Parsing of keyword argument is also applicable to most of the methods in a class +And for functions that contain more than two arguments, a keyword argument can be used. Parsing of keyword argument is also applicable to most of the methods in a class ```javascript /** @@ -151,9 +137,9 @@ function join_df(kwargs){ ## **Writing tests** -We strongly encourage contributors to write tests for their code. Like many packages, danfojs uses mocha +We strongly encourage contributors to write tests for their code. Like many packages, Danfojs uses mocha. -All tests should go into the tests subdirectory and place in the corresponding module. The tests folder contains some current examples of tests, and we suggest looking to these for inspiration. +All tests should go into the tests subdirectory and placed in the corresponding module. The tests folder contains some current examples of tests, and we suggest looking to these for inspiration. Below is the general Framework to write a test for each module. @@ -236,16 +222,16 @@ describe("DataFrame", function(){ To run the test for the module you created, -**1)** Open the package.json +**1)** Open the package.json -**2)** change the name of the test file to the file name you want. and don't forget the file is in the test folder +**2)** change the name of the test script to the file name you want to test. ```python "scripts": { "test": "....... danfojs/tests/sub_directory_name/filename", ``` -**3)** run the test, in the danfojs directory terminal +**3)** run the test, in the danfojs directory terminal ```python yarn test @@ -300,30 +286,7 @@ This request then goes to the repository maintainers, and they will review the c In other to contribute to the code base of danfojs, there are some functions and properties provided to make implementation easy. -The main exposed modules are the **Frame** and **Series** module. This module inherits from the **Generic** module. - -The **Generic** module consists of the following methods and properties - -* `.dtypes` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L213)] is used to obtain the dtype for each column -* `.index` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L250)] to obtain the index for Dataframe or Series -* `.__set_index(label)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L257)] to set the index value -* `.__reset_index()` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L271)] to reset the index in DataFrame and Series -* `.values` Obtain the values in DataFrame and Series per rows -* `.col_data` Obtain the values in DataFrame and Series per columns -* `.column_names` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)] Obtain the list of column names -* `.__set_col_types` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L165)] set the dtype for a column or infer the dtype from it -* `.columns` to access the column names directly -* `row_data_tensor` store the tensor representation of the data in DataFrame and Series - -The **Frame** module consists of the following methods and properties to aid implementation. - -* `__frame_is_compactible_for_operation` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1754)]: check if all the values in a DataFrame are numerical. This helps to check if the numerical operation can be done using the dataframe. -* `.__get_ops_tensors(tensors, axis)` \[[source\]](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1767) : obtain tensors from dataframes along axis 0 or 1. -* `.__get_df_from_tensor(val, col_names)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L1741)]: Obtain dataframe from tensor. -* `.__get_tensor_and_idx(df, axis)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/frame.js#L928)]: Obtain tensors, their index value and their axis from dataframe. +The folder **danfojs-base** contains the bulk of Danfojs modules, and these are simply extended or exported by the **danfojs-browser** and **danfojs-node** folders. The base class for Frames and Series is the NdFrame class which is found in the `danfojs-base/core/generic` file. -The **Series** module contains mostly Generic properties and less special internal properties. -* `__check_series_op_compactibility(other)` \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L666)] check if two series are compatible for numerical operation -Lastly, the **Utils** module contains important utility functions. diff --git a/examples/migrating-to-the-stable-version-of-danfo.js.md b/examples/migrating-to-the-stable-version-of-danfo.js.md new file mode 100644 index 0000000..07c8206 --- /dev/null +++ b/examples/migrating-to-the-stable-version-of-danfo.js.md @@ -0,0 +1,92 @@ +--- +description: >- + This page contains migration guides and tips for pre-v1 users of Danfo.js who + want to migrate their projects to the latest stable release of Danfo.js. +--- + +# Migrating to the stable version of Danfo.js + +We recently released the first stable version of Danfo.js. See release note here. This new version improves previous versions, by standardizing the API. As such we now have better naming conventions, class structures, and error messages. + +The following list summarizes some of these updates: + +* **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increases the developer experience. +* **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. +* Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. +* **New features**: We added lots of new features which users have been requesting for. For example: + * Stream and process large CSV data + * Read JSON objects with key support + * Date time is now a first-class data type. +* General bug fixes and improvements +* Better error messages + +## Breaking Updates + +There are two major breaking changes in the new stable version. + +### Naming convention + +Update your function and/or method names to use camelCase instead of snake\_case. For example: + +```javascript +read_csv ==> readCSV +to_json ==> toCSV +drop_duplicates ==> dropDuplicates +``` + +**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. + +### Functions and Methods argument structure + +Another major breaking change of v1, is that the structure of arguments/parameters in most functions has been updated to be more intuitive. + +In general, it is important to understand our thought process behind this, so, here goes: + +Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: + +``` +rename( { mapper, axis, inplace } ) => DataFrame +``` + +The structure above combines both required and optional arguments as a single object argument, which is less intuitive. A better method signature will/should take into account the required and optional arguments, as well as their position. Hence we need something like: + +``` +rename(mapper, options: {axis, inplace}) //where mapper is required, and options argument is optional. +``` + +Re-designing functions and methods to follow this intuitive format is the bulk of the breaking change in this new version, as such, when migrating, you have to make these updates. + +{% hint style="info" %} +If using Typescript, then the TS compiler will help in migration, else, you have to manually identify and update your function/method signature. +{% endhint %} + +### Axis Order + +In this new version, we have flipped the result of the axis ordering for all operations. This ordering is now consistent with Pandas and Tensorflow.js. That is, the axis row (0), represents the operations carried out horizontally on a DataFrame, and the axis columns (1) represent operations carried out vertically down the DataFrame. + +{% hint style="info" %} +In short, when migrating to the new version, you should flip the axis number so as to get the same result. That is, change all `axis: 0` to `axis: 1`, to get the same result. +{% endhint %} + +All examples in this doc have been updated to reflect this update. + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md index b9f9cca..9ee7073 100644 --- a/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md +++ b/examples/titanic-survival-prediction-using-danfo.js-and-tensorflow.js.md @@ -13,7 +13,7 @@ In this tutorial, I will show you how to load and process the famous Titanic dat The main objective of this tutorial is to show you how to use danfo.js to load and process data easily in JavaScript, so we won't be doing anything too advanced. Also, I assumed that you're familiar with basic deep learning with Tensorflow.js and Pandas as well. If you do not have any background in ML, these are good resources to get started: -* [Introduction to Machine Learning](https://developers.google.com/machine-learning/crash-course/ml-intro) +* [Introduction to Machine Learning](https://developers.google.com/machine-learning/crash-course/ml-intro) * [Deep Learning and Neural Networks](https://www.tensorflow.org/resources/learn-ml/basics-of-machine-learning) * [A Gentle Introduction to TensorFlow.js](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html) @@ -41,19 +41,19 @@ When you're done, create a file called app.js and import the packages: ```javascript const dfd = require("danfojs-node") -const tf = dfd.tf //Reference to the exported tensorflowjs library +const tf = dfd.tensorflow //Reference to the exported tensorflowjs library ``` ## Loading and processing your data -To load a CSV dataset, you can use the [read_csv](../api-reference/input-output/danfo.read_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. +To load a CSV dataset, you can use the [readCSV](../api-reference/input-output/danfo.read\_csv.md) function. This can load a file from both a local path, as well as over the internet. In this tutorial, you'll load the titanic dataset from the internet. Below your import add the following lines of code: ```javascript async function load_process_data() { - let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") + let df = await dfd.redCSV("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") df.head().print() @@ -61,8 +61,7 @@ async function load_process_data() { ``` ``` - Shape: (5,8) - + ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ Survived │ Pclass │ Name │ Sex │ ... │ Age │ Siblings/Spou... │ Parents/Child... │ Fare ║ ╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ @@ -78,7 +77,7 @@ async function load_process_data() { ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -You wrote an async function because loading dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read_csv function. +You wrote an async function because loading a dataset over the internet takes a few seconds depending on your network. Inside the async function, you pass in the url of the titanic dataset to the read\_csv function. Next you'll perform some basic data preprocessing. The [ctypes](../api-reference/dataframe/dataframe.dtypes.md) attribute returns the column data types: @@ -115,7 +114,7 @@ From the data types table above, you'll notice that there are two strong columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df -df.addColumn({ column: "Name", values: title, inplace: true }) +df.addColumn("Name", title, { inplace: true }) ``` In the code above, you are calling the [apply](../api-reference/series/series.apply.md) function on the _**Name**_ column. The parameter to the [apply](../api-reference/series/series.apply.md) function is a function that gets called on each element of the column. This function can be any JavaScript function. @@ -147,7 +146,7 @@ let cols = ["Sex", "Name"] cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, values: enc_val, inplace: true }) + df.addColumn( col, enc_val, { inplace: true }) }) df.head().print() @@ -207,19 +206,19 @@ In the code cell above, first, you create an instance from the MinMaxScaler clas ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -The full code for the load_process_data function becomes: +The full code for the load\_process\_data function becomes: ```javascript const dfd = require("danfojs-node") const tf = dfd.tf; async function load_process_data() { - let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") + let df = await dfd.readCSV("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") //A feature engineering: Extract all titles from names columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df - df.addColumn({ column: "Name", values: title, inplace: true }) + df.addColumn("Name", title, { inplace: true }) //label Encode Name feature let encoder = new dfd.LabelEncoder() @@ -227,14 +226,14 @@ async function load_process_data() { cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, values: enc_val, inplace: true }) + df.addColumn( col, enc_val, { inplace: true }) }) - let Xtrain,ytrain; + let Xtrain, ytrain; Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] - + // Standardize the data with MinMaxScaler let scaler = new dfd.MinMaxScaler() scaler.fit(Xtrain) @@ -250,7 +249,7 @@ load_process_data() In this section, you'll build a simple classification model using tensorflow.js. If you're not familiar with Tensorflow.js, you can start [here](https://blog.tensorflow.org/2018/04/a-gentle-introduction-to-tensorflowjs.html). -Create a simple function called get_model. This will construct and return a model when called. +Create a simple function called get\_model. This will construct and return a model when called. ```javascript function get_model() { @@ -297,23 +296,23 @@ async function train() { } ``` -This function calls the _**load_process_data**_ function to retrieve training data as tensors and also calls the _**get_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. +This function calls the _**load\_process\_data**_ function to retrieve training data as tensors and also calls the _**get\_model**_ to retrieve the model. Next, you compile the model by specifying an optimizer, a loss function and a metric to report. Next, you call the **fit** function on the model, by passing the training data and labels (tensors), specify batch size, epoch size, validation split size, and also a callback function to track training progress. The training progress is printed to the console at the end of each Epoch. Below is the full code from loading data to training your model: ```javascript -const dfd = require("danfojs-node") -const tf = dfd.tf; +const dfd = require("danfojs-node-nightly") +const tf = dfd.tensorflow async function load_process_data() { - let df = await dfd.read_csv("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") + let df = await dfd.readCSV("https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv") //A feature engineering: Extract all titles from names columns let title = df['Name'].apply((x) => { return x.split(".")[0] }).values //replace in df - df.addColumn({ column: "Name", values: title, inplace: true }) + df.addColumn("Name", title, { inplace: true }) //label Encode Name feature let encoder = new dfd.LabelEncoder() @@ -321,11 +320,11 @@ async function load_process_data() { cols.forEach(col => { encoder.fit(df[col]) enc_val = encoder.transform(df[col]) - df.addColumn({ column: col, values: enc_val, inplace: true }) + df.addColumn( col, enc_val, { inplace: true }) }) - let Xtrain,ytrain; + let Xtrain, ytrain; Xtrain = df.iloc({ columns: [`1:`] }) ytrain = df['Survived'] @@ -333,7 +332,6 @@ async function load_process_data() { let scaler = new dfd.MinMaxScaler() scaler.fit(Xtrain) Xtrain = scaler.transform(Xtrain) - return [Xtrain.tensor, ytrain.tensor] //return the data as tensors } @@ -417,8 +415,8 @@ After 15 epochs, you reach an accuracy of about 83%. This can definitely be impr In this tutorial, you have seen how to use danfo.js with tensorflow.js to load and process data, as well as train a neural network. This is similar to the Pandas-Tensorflow packages in Python. -You also notice that danfo.js provides similar API as Pandas and can easily be picked up by Python developers. +You also notice that danfo.js provides a similar API as Pandas and can easily be picked up by Python developers. As an extra task, you can try to do more feature engineering using danfo.js and try to improve the accuracy of your model. -Go danfo! 😎 +Go Danfo! 😎 diff --git a/examples/using-danfojs-in-react.md b/examples/using-danfojs-in-react.md index 3f97b10..682a0d7 100644 --- a/examples/using-danfojs-in-react.md +++ b/examples/using-danfojs-in-react.md @@ -2,9 +2,9 @@ **TL:DR** See Example react application using danfojs [here](https://github.com/opensource9ja/Data-aRT) -Danfojs works for both browser and NodeJs environment, and as such is available to frontend frameworks like React and Vue. +Danfojs works for both browser and NodeJs environment, and as such is available to frontend frameworks like React and Vue. -In order to use Danfojs in a library like React, you must install the [browser side version ](https://www.npmjs.com/package/danfojs)from npm. +In order to use Danfojs in a library like React, you must install the [browser side version ](https://www.npmjs.com/package/danfojs)from npm. ```bash npm install danfojs @@ -18,14 +18,14 @@ Follow the steps here to bootstrap a React app, and in your App.js or any file w ```bash import "./App.css"; -import * as dfd from "danfojs/src/index"; +import * as dfd from "danfojs"; ``` Now you have access to all features under the `dfd` namespace. Below is a sample App.js file using danfojs: ```bash import "./App.css"; -import * as dfd from "danfojs/src/index"; +import * as dfd from "danfojs"; function App() { @@ -53,7 +53,6 @@ function App() { } export default App; - ``` On running the app, we get the following output in the console: @@ -63,7 +62,7 @@ On running the app, we get the following output in the console: Note that you can also import specific modules. For instance, in the code below we import only the DataFrame module: ```bash -import { DataFrame } from "danfojs/src/index"; +import { DataFrame } from "danfojs"; ``` -Following these steps, you can use danfojs in any client-side library. +Following these steps, you can use danfojs in any client-side library. diff --git a/getting-started.md b/getting-started.md index 9388ab0..de8a123 100644 --- a/getting-started.md +++ b/getting-started.md @@ -6,6 +6,12 @@ description: >- # Getting Started +{% hint style="info" %} +A stable version of Danfojs (v1), has been released, and it comes with full Typescript support, new features, and many bug fixes. See release note [here](release-notes.md#latest-release-node-v1.0.0-browser-v1.0.0). + +There are a couple of breaking changes, so we have prepared a short migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1.0.0 users. +{% endhint %} + ## Installation There are three ways to install and use Danfo.js in your application @@ -33,23 +39,26 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) or the [VS-Code Nodejs notebook extension](https://marketplace.visualstudio.com/items?itemName=donjayamanne.typescript-notebook). {% endhint %} ## 10 minutes to danfo.js This is a short introduction to Danfo.js, and its flow is adapted from the official [10 minutes to Pandas](https://pandas.pydata.org/pandas-docs/stable/user\_guide/10min.html#min) -We will show you how to use danfo.js in both browser environments and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in both environments. +We will show you how to use danfo.js in a browser, client-side libraries, and Node.js environments. Most functions except [plotting](https://jsdata.gitbook.io/danfojs/api-reference/plotting) which require a DOM work the same way in all environments. {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") + +//or using ES6 +import * as dfd from "danfojs-node" ``` {% endtab %} @@ -78,6 +87,15 @@ const dfd = require("danfojs-node") ``` {% endtab %} + +{% tab title="React" %} +```jsx +import * as dfd from "danfojs" + +//import specific methods/classes +import { readCSV, DataFrame } from "danfojs" +``` +{% endtab %} {% endtabs %} ### Creating a DataFrame/Series @@ -87,6 +105,8 @@ You can create a [`Series`](https://pandas.pydata.org/pandas-docs/stable/referen {% tabs %} {% tab title="Node" %} ```javascript +import * as dfd from "danfojs-node" + s = new dfd.Series([1, 3, 5, undefined, 6, 8]) s.print() ``` @@ -144,7 +164,7 @@ Creating a [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -const tf = require("@tensorflow/tfjs-node") +const tf = dfd.tensorflow //Tensorflow.js is exportedfrom Danfojs let tensor_arr = tf.tensor([12,34,56,2]) @@ -169,7 +189,7 @@ s.print() @@ -574,6 +603,19 @@ console.log(df.columns); ``` //output + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D │ E ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1/1/2017, 1:00:… │ bval1 │ 10 │ 1.2 │ test ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 1/1/2018, 1:00:… │ bval2 │ 20 │ 3.45 │ train ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 1/1/2019, 1:00:… │ bval3 │ 30 │ 60.1 │ test ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 1/1/2020, 1:00:… │ bval4 │ 40 │ 45 │ train ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + [ 0, 1, 2, 3 ] [ 'A', 'B', 'C', 'D', 'E' ] ``` @@ -588,12 +630,12 @@ For `df`, our [`DataFrame`](https://pandas.pydata.org/pandas-docs/stable/referen const dfd = require("danfojs-node") -json_data = [{ A: 0.4612, B: 4.28283, C: -1.509, D: -1.1352 }, +j son_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 }] -df = new dfd.DataFrame(json_data) +let df = new dfd.DataFrame(json_data) console.log(df.tensor); //or @@ -670,12 +712,12 @@ Tensor const dfd = require("danfojs-node") -json_data = [{ A: 0.4612, B: 4.28283, C: -1.509, D: -1.1352 }, +let 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 }] -df = new dfd.DataFrame(json_data) +let df = new dfd.DataFrame(json_data) df.describe().print() ``` @@ -749,7 +791,7 @@ let data = {"A": [-20, 30, 47.3, NaN], let df = new dfd.DataFrame(data) -df.sort_values({by: "C", inplace: true}) +df.sortValues("C", {inplace: true}) df.print() ``` {% endtab %} @@ -776,7 +818,7 @@ df.print() let df = new dfd.DataFrame(data) - df.sort_values({by: "C", inplace: true}) + df.sortValues("C", {inplace: true}) df.print() @@ -1175,83 +1217,7 @@ sub_df.print() #### Boolean Querying/Filtering -Using a single column’s values to select data. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() //before query - -let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) -query_df.print() //after query -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -``` -//before query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -The best way to query data is to use a boolean mask just as we demonstrated above with iloc and locs. For example, in the following code, we pass a condition parameter instead: +The best way to query data is to use a boolean mask just as we demonstrated above with iloc and loc. For example, in the following code, we use a condition parameter to query the DataFrame: ```javascript let data = { @@ -1261,7 +1227,7 @@ let data = { } let df = new dfd.DataFrame(data) -let query_df = df.query({ condition: df["B"].gt(5) }) +let query_df = df.query(df["B"].gt(5)) query_df.print() ``` @@ -1283,10 +1249,7 @@ let data = { "B": [34, 4, 5, 6], "C": [20, 20, 30, 40] } -let query_df = df.query({ - condition: - df["B"].gt(5).and(df["C"].lt(30)) -}) +let query_df = df.query( df["B"].gt(5).and(df["C"].lt(0))) query_df.print() //after query //output @@ -1295,7 +1258,6 @@ query_df.print() //after query ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 0 │ Ng │ 34 │ 20 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` #### Adding a new column @@ -1315,7 +1277,7 @@ let df = new dfd.DataFrame(data) df.print() let new_col = [1, 2, 3, 4] -df.addColumn({ column: "D", values: new_col, inplace: true }); //happens inplace +df.addColumn("D", new_col, { inplace: true }); //happens inplace df.print() ``` @@ -1390,9 +1352,9 @@ df.print() ### Missing data -**NaN** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. +**NaN, null,** and **undefined** represent missing data in Danfo.js. These values can be dropped or filled using some functions available in Danfo.js. -To drop any rows that have missing data: +To drop any columns that have missing data: {% tabs %} {% tab title="Node" %} @@ -1405,7 +1367,7 @@ let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(0) +let df_drop = df.dropNa({ axis: 0 }) df_drop.print() ``` {% endtab %} @@ -1433,7 +1395,7 @@ df_drop.print() df.print() - let df_drop = df.dropna({axis: 0}) + let df_drop = df.dropNa({axis: 0}) df_drop.print() @@ -1459,28 +1421,32 @@ df_drop.print() ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -//after droppping -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 20 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +//after dropping +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ B │ C ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ 5 │ 6 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ 30 │ 40 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╝ ``` -To drop any columns with have missing data, set the axis to 1: +To drop row(s) with have missing data, set the axis to 1: ```javascript const dfd = require("danfojs-node") -let data = [[1, 2, 3], [NaN, 5, 6], [20, NaN, 40], [39, 34, 78]] +let data = [[1, 2, 3], [NaN, 5, 6], [20, 30, 40], [39, 34, 78]] let cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -let df_drop = df.dropna(1) +let df_drop = df.dropNa({ axis: 1 }) df_drop.print() ``` @@ -1493,25 +1459,21 @@ df_drop.print() ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 1 │ NaN │ 5 │ 6 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ NaN │ 40 ║ +║ 2 │ 20 │ 30 │ 40 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 3 │ 39 │ 34 │ 78 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -//after droppping +//after dropping -╔════════════╤═══════════════════╗ -║ │ C ║ -╟────────────┼───────────────────╢ -║ 0 │ 3 ║ -╟────────────┼───────────────────╢ -║ 1 │ 6 ║ -╟────────────┼───────────────────╢ -║ 2 │ 40 ║ -╟────────────┼───────────────────╢ -║ 3 │ 78 ║ -╚════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 2 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ 39 │ 20 │ 78 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Filling missing data: @@ -1527,7 +1489,7 @@ let data = { } let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") +let df_filled = df.fillNa("Apples") df_filled.print() ``` @@ -1560,7 +1522,7 @@ let data = { let df = new dfd.DataFrame(data) df.print() -let df_filled = df.fillna(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) +let df_filled = df.fillNa(["Apples", df["Count"].mean()], { columns: ["Name", "Count"] }) df_filled.print() ``` @@ -1588,7 +1550,7 @@ let data = {"Name":["Apples", "Mango", "Banana", undefined], "Price": [200, 300, 40, 250]} let df = new dfd.DataFrame(data) -df.isna().print() +df.isNa().print() ``` ``` @@ -1624,7 +1586,7 @@ cols = ["A", "B", "C"] let df = new dfd.DataFrame(data, { columns: cols }) df.print() -df.mean().print() //defaults to column axis +df.mean().print() //defaults to column (1) axis ``` {% endtab %} @@ -1673,15 +1635,15 @@ df.mean().print() //defaults to column axis ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 4 ║ -╟───┼──────────────────────╢ -║ B │ 38.5 ║ -╟───┼──────────────────────╢ -║ C │ 31.75 ║ -╚═══╧══════════════════════╝ +╔═══╤════════════════════╗ +║ 0 │ 11.333333333333334 ║ +╟───┼────────────────────╢ +║ 1 │ 7.333333333333333 ║ +╟───┼────────────────────╢ +║ 2 │ 24 ║ +╟───┼────────────────────╢ +║ 3 │ 56.333333333333336 ║ +╚═══╧════════════════════╝ ``` Same operation on the row axis: @@ -1695,7 +1657,7 @@ cols = ["A", "B", "C"] let df = new dfd.DataFrame(data) df.print() -df.mean(0).print() //row axis=0, column=1 +df.mean({ axis: 0 }).print() //row axis=0, column=1 ``` ``` @@ -1711,20 +1673,16 @@ df.mean(0).print() //row axis=0, column=1 ║ 3 │ 2 │ 89 │ 78 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11.333333015441895 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.333333492279053 ║ -╟───┼──────────────────────╢ -║ 2 │ 24 ║ -╟───┼──────────────────────╢ -║ 3 │ 56.33333206176758 ║ -╚═══╧══════════════════════╝ +╔═══╤═══════╗ +║ A │ 4 ║ +╟───┼───────╢ +║ B │ 38.5 ║ +╟───┼───────╢ +║ C │ 31.75 ║ +╚═══╧═══════╝ ``` -Operations on objects with different dimensionality and need alignment. danfo automatically broadcasts along the specified dimension. +Operations on objects with different dimensionality and need alignment. Danfo automatically broadcasts along the specified dimension. ```javascript const dfd = require("danfojs-node") @@ -1755,7 +1713,7 @@ df_new.print() #### Apply -Applying functions to the data along specified axis. If axis = 1 (default), then the specified function (`callable)` will be called with each column data, and vice versa: +Applying functions to the data along a specified axis. If axis = 1 (default), then the specified function (`callable)` will be called with each row data, and vice versa: ```javascript const dfd = require("danfojs") @@ -1790,17 +1748,19 @@ df_new.print() //after applying ╔═══╤═════╗ -║ A │ 64 ║ +║ 0 │ 6 ║ ╟───┼─────╢ -║ B │ 126 ║ +║ 1 │ 15 ║ ╟───┼─────╢ -║ C │ 127 ║ +║ 2 │ 90 ║ +╟───┼─────╢ +║ 3 │ 206 ║ ╚═══╧═════╝ ``` Applying Element wise operations to the data: -You can use the `apply_map` function if you need to apply a function to each element in the DataFrame. `apply_map` works element-wise. +You can use the `applyMap` function if you need to apply a function to each element in the DataFrame. `applyMap` works element-wise. ```javascript const dfd = require("danfojs-node") @@ -1813,7 +1773,7 @@ function sum_vals(x) { return x + 10 } -let df_new = df.apply_map(sum_vals) +let df_new = df.applyMap(sum_vals) df_new.print() ``` @@ -1832,7 +1792,7 @@ df_new.print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - //after apply_map + //after applyMap ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ @@ -1854,8 +1814,8 @@ Series is equipped with a set of string processing methods in the **str** attrib ```javascript const dfd = require("danfojs-node") -s = new dfd.Series(['A', 'B', 'C', 'Aaba', 'Baca', 'CABA', 'dog', 'cat']) -lower_s = s.str.toLowerCase() +let s = new dfd.Series(['A', 'B', 'C', 'Aaba', 'Baca', 'CABA', 'dog', 'cat']) +let lower_s = s.str.toLowerCase() lower_s.print() ``` @@ -1908,22 +1868,23 @@ let df1 = new dfd.DataFrame(data, { columns: colum1 }) let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) //along column axis +let com_df = dfd.concat({ dfList: [df1, df2], axis: 1 }) //along column axis com_df.print() ``` ``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Key1 │ Key2 │ A │ B │ Key11 │ Key21 │ A1 │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ K0 │ k0 │ A0 │ B0 │ K0 │ k0 │ C0 │ D0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ k0 │ K1 │ A1 │ B1 │ K1 │ K0 │ C1 │ D1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ K1 │ K0 │ A2 │ B2 │ K1 │ K0 │ C2 │ D2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ K2 │ K2 │ A3 │ B3 │ K2 │ K0 │ C3 │ D3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` Concatenate along row axis (0). @@ -1945,7 +1906,7 @@ let df1 = new dfd.DataFrame(data, { columns: colum1 }) let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) //along row axis +let com_df = dfd.concat({ dfList: [df1, df2], axis: 0 }) //along row axis com_df.print() ``` @@ -1992,7 +1953,7 @@ let df2 = new dfd.DataFrame(data2, { columns: colum2 }) df1.print() df2.print() -let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) +let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"], how: "inner" }) merge_df.print() ``` @@ -2108,19 +2069,17 @@ Grouping and then applying the[`sum()`](api-reference/groupby/groupby.sum.md) fu ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) +let data = { + A: ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"], + B: ["one", "one", "two", "three", "two", "two", "one", "three"], + C: [1, 3, 2, 4, 5, 2, 6, 7], + D: [3, 2, 4, 1, 5, 6, 7, 8], +}; +let df = new dfd.DataFrame(data); -let grp = df.groupby(["A"]) -grp.col(["C"]).sum().print() +let grp = df.groupby(["A"]); +grp.col(["C"]).sum().print(); ``` ``` @@ -2178,12 +2137,12 @@ danfo provides a simple but powerful, and efficient functionality for working wi ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) +let data = new dfd.dateRange({"start":'2018-01', freq:'M', period:3}) let sf = new dfd.Series(data) //print series sf.print() //print month names -sf.dt.month_name().print() +sf.dt.monthName().print() ``` ``` @@ -2197,15 +2156,13 @@ sf.dt.month_name().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Jan ║ -╟───┼──────────────────────╢ -║ 1 │ Feb ║ -╟───┼──────────────────────╢ -║ 2 │ Mar ║ -╚═══╧══════════════════════╝ +╔═══╤══════════╗ +║ 0 │ January ║ +╟───┼──────────╢ +║ 1 │ February ║ +╟───┼──────────╢ +║ 2 │ March ║ +╚═══╧══════════╝ ``` More Examples: @@ -2213,12 +2170,12 @@ More Examples: ```javascript const dfd = require("danfojs-node") -let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) +let data = new dfd.dateRange({"start":'2018-01', freq:'M', period:3}) let sf = new dfd.Series(data) //print series sf.print() -//print month names -sf.dt.weekdays().print() +//print week day names +sf.dt.dayOfWeekName().print() ``` ``` @@ -2232,24 +2189,32 @@ sf.dt.weekdays().print() ║ 2 │ 3/1/2018, 1:00:00 AM ║ ╚═══╧══════════════════════╝ -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Mon ║ -╟───┼──────────────────────╢ -║ 1 │ Thu ║ -╟───┼──────────────────────╢ -║ 2 │ Thu ║ -╚═══╧════════════════════ +╔═══╤══════════╗ +║ 0 │ Monday ║ +╟───┼──────────╢ +║ 1 │ Thursday ║ +╟───┼──────────╢ +║ 2 │ Thursday ║ +╚═══╧══════════╝ ``` ### Plotting See the [Plotting](api-reference/plotting/) docs. -We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. This gives you the ability to make interactive plots from DataFrame and Series. Plotting only works in the browser version of danfo.js, and requires an HTML div to show plots. +We currently support [Plotly.js](https://plotly.com/javascript/) for plotting. In the future, we plan other JS plotting libraries like Vega, D3. + +Using the `plot` API, you can make interactive plots from DataFrame and Series. Plotting only works in the browser/client-side version of Danfo.js, and requires an HTML div to display plots. + +{% tabs %} +{% tab title="Browser" %} + +{% endtab %} + +{% tab title="Second Tab" %} -**Update**: As of `v0.2.3`, we stopped bundling Danfojs with Plotly. This has greatly reduced bundle size by about 80%. See more details in the release notes here. In order to make Plots, you must explicitly add the Plotly CDN to your file as we show in the updated examples: +{% endtab %} +{% endtabs %} ```markup @@ -2258,7 +2223,6 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting. - Document @@ -2268,25 +2232,30 @@ We use [Plotly.js](https://plotly.com/javascript/) as our backend for plotting.
@@ -2333,7 +2302,11 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe [Writing to a CSV file.](api-reference/dataframe/dataframe.to\_csv.md) -Convert any DataFrame to csv format. If a file path is specified, then the CSV is saved to the path, else it is returned as a string. +Convert any DataFrame to csv format. + +In NodeJs, if a file path is specified, then the CSV is saved to the path, else it is returned as a string. + +In the browser, you can automatically download the file as CSV by setting the `download` paramater to `true`. ```javascript const dfd = require("danfojs-node") @@ -2346,7 +2319,7 @@ let data = { let df = new dfd.DataFrame(data) -const csv = df.to_csv() +const csv = df.toCSV() console.log(csv); //output Abs,Count,country code @@ -2355,11 +2328,10 @@ Abs,Count,country code 47.3,5,GH -df.to_csv({filePath: "testOut.csv" }) //writes to file in Nodejs - +df.toCSV({filePath: "testOut.csv" }) //writes to file system in Nodejs -df.to_csv({fileName: "testOut", download: true }) //downloads the file in browser version +df.toCSV({fileName: "testOut", download: true }) //downloads the file in browser version ``` ``` @@ -2371,14 +2343,14 @@ Abs,Count,country code [Reading from a CSV file.](https://pandas.pydata.org/pandas-docs/stable/user\_guide/io.html#io-read-csv-table) -The **read\_csv** method can read CSV file from local disk, or over the internet. If the file is to be read from a local disk in Node environment, you have to prefix the full path name with a "**file://**" prefix. For instance, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: +The **readCSV** method can read CSV files from local disk, or over the internet. Both full and relative paths are supported. For example, to read a CSV file at the path **/home/Desktop/titanic.csv**, you can do the following: {% tabs %} {% tab title="JavaScript" %} ```javascript const dfd = require("danfojs") -dfd.read_csv("file:///home/Desktop/titanic.csv") +dfd.readCSV("/home/Desktop/titanic.csv") .then(df => { //do something with the CSV file @@ -2440,7 +2412,7 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.to_json() +const json = df.toJSON() console.log(json); //output [ @@ -2450,7 +2422,7 @@ console.log(json); ] -const json = df.to_json({format: "row"}) +const json = df.toJSON({format: "row"}) console.log(json); //output { diff --git a/release-notes.md b/release-notes.md index 36ef577..6bfac22 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,30 @@ # Release Notes -### \[LATEST] Release Node (v0.3.3), Browser (0.3.3) +### \[LATEST] Release Node (v1.0.0), Browser (v1.0.0) + +**Date:** 12th Jan 2022 + +Major breaking update. See the migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1 users. + +**New Features** + +* Full Typescript support +* streamCsvTransforme ==> Pipable stream transformer for incrementally transforming DataFrames +* streamJSON ==> Supports streaming of local or remote JSON files into DataFrame. +* streamCSV ==> Supports streaming of local or remote CSV files into DataFrame. +* openCsvInputStream ==> Open a local/remote CSV file as a readable stream +* writeCsvOutputStream ==> Open a local/remote CSV file as a writable stream +* [https://github.com/javascriptdata/danfojs/issues/325](https://github.com/javascriptdata/danfojs/issues/325) +* [https://github.com/javascriptdata/danfojs/issues/296](https://github.com/javascriptdata/danfojs/issues/296) + +**Bug Fixes** + +* [https://github.com/javascriptdata/danfojs/issues/335](https://github.com/javascriptdata/danfojs/issues/335) +* [https://github.com/javascriptdata/danfojs/issues/338](https://github.com/javascriptdata/danfojs/issues/338) + +Contributors [@risenW](https://github.com/risenW) [@steveoni](https://github.com/steveoni) + +### Release Node (v0.3.3), Browser (0.3.3) **Date:** 10th Oct 2021 @@ -161,13 +185,13 @@ model.summary(); We added/updated the following features: -* [Read JSON](api-reference/input-output/danfo.read_json.md) files from local and remote URL into DataFrame (New feature) -* [Read Excel](api-reference/input-output/danfo.read_excel.md) files from local or remote URL into DataFrame (New feature) +* [Read JSON](api-reference/input-output/danfo.read\_json.md) files from local and remote URL into DataFrame (New feature) +* [Read Excel](api-reference/input-output/danfo.read\_excel.md) files from local or remote URL into DataFrame (New feature) * Fix string comparison bug in [query](api-reference/dataframe/danfo.dataframe.query.md) function (Fix) * Add append function for [DataFrame](api-reference/dataframe/dataframe.append.md) and [Series](api-reference/series/series.append.md) (New feature) * Fix null value bug when creating DataFrame from JSON files (Fix) * Add relative import for reading files into DataFrame -* Add [sort_index](api-reference/dataframe/dataframe.sort_index.md) function to DataFrame and Series (New feature) +* Add [sort\_index](api-reference/dataframe/dataframe.sort\_index.md) function to DataFrame and Series (New feature) * Minor patch and overall optimizations (Fix) **Contributors**: [Rising Odegua](https://github.com/risenW), [Stephen Oni](https://github.com/steveoni), [Jhenner Tigreros](https://github.com/JhennerTigreros), [Aditya Zope](https://github.com/adzo261) From 153a1f77f45ac94336489b44be0330fae4c177ae Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Jan 2022 16:26:46 +0100 Subject: [PATCH 161/202] clean up doc --- api-reference-v1-stable/README.md | 54 --- .../configuration-options.md | 128 ----- api-reference-v1-stable/dataframe/README.md | 145 ------ .../dataframe/creating-a-dataframe.md | 355 -------------- .../dataframe/danfo.dataframe.abs.md | 74 --- .../dataframe/danfo.dataframe.add.md | 246 ---------- .../dataframe/danfo.dataframe.addcolumn.md | 118 ----- .../dataframe/danfo.dataframe.apply.md | 106 ---- .../dataframe/danfo.dataframe.column.md | 72 --- .../dataframe/danfo.dataframe.copy.md | 53 -- .../dataframe/danfo.dataframe.count.md | 100 ---- .../dataframe/danfo.dataframe.cummax.md | 99 ---- .../dataframe/danfo.dataframe.cummin.md | 99 ---- .../dataframe/danfo.dataframe.cumprod.md | 99 ---- .../dataframe/danfo.dataframe.cumsum.md | 99 ---- .../dataframe/danfo.dataframe.describe.md | 61 --- .../dataframe/danfo.dataframe.div.md | 254 ---------- .../dataframe/danfo.dataframe.dropna.md | 96 ---- .../dataframe/danfo.dataframe.eq.md | 190 -------- .../dataframe/danfo.dataframe.fillna.md | 178 ------- .../dataframe/danfo.dataframe.ge.md | 195 -------- .../dataframe/danfo.dataframe.groupby.md | 148 ------ .../dataframe/danfo.dataframe.gt.md | 191 -------- .../dataframe/danfo.dataframe.head.md | 53 -- .../dataframe/danfo.dataframe.iloc.md | 331 ------------- .../dataframe/danfo.dataframe.isna.md | 54 --- .../dataframe/danfo.dataframe.it.md | 194 -------- .../dataframe/danfo.dataframe.le.md | 194 -------- .../dataframe/danfo.dataframe.loc.md | 367 -------------- .../dataframe/danfo.dataframe.max.md | 118 ----- .../dataframe/danfo.dataframe.mean.md | 120 ----- .../dataframe/danfo.dataframe.median.md | 120 ----- .../dataframe/danfo.dataframe.min.md | 120 ----- .../dataframe/danfo.dataframe.mod.md | 258 ---------- .../dataframe/danfo.dataframe.mul.md | 252 ---------- .../dataframe/danfo.dataframe.ne.md | 187 -------- .../dataframe/danfo.dataframe.pow.md | 260 ---------- .../dataframe/danfo.dataframe.query.md | 278 ----------- .../dataframe/danfo.dataframe.replace.md | 102 ---- .../dataframe/danfo.dataframe.round.md | 128 ----- .../dataframe/danfo.dataframe.sample.md | 112 ----- .../dataframe/danfo.dataframe.std.md | 94 ---- .../dataframe/danfo.dataframe.sub.md | 250 ---------- .../dataframe/danfo.dataframe.sum.md | 121 ----- .../dataframe/danfo.dataframe.tail.md | 53 -- .../dataframe/danfo.dataframe.var.md | 94 ---- .../dataframe/dataframe.append.md | 76 --- .../dataframe/dataframe.apply_map.md | 68 --- .../dataframe/dataframe.astype.md | 222 --------- .../dataframe/dataframe.axes.md | 47 -- .../dataframe/dataframe.drop.md | 143 ------ .../dataframe/dataframe.dtypes.md | 100 ---- .../dataframe/dataframe.index.md | 69 --- .../dataframe/dataframe.ndim.md | 46 -- .../dataframe/dataframe.nunique-1.md | 98 ---- .../dataframe/dataframe.print.md | 105 ---- .../dataframe/dataframe.rename.md | 148 ------ .../dataframe/dataframe.reset_index.md | 73 --- .../dataframe/dataframe.select_dtypes.md | 94 ---- .../dataframe/dataframe.set_index.md | 176 ------- .../dataframe/dataframe.shape.md | 43 -- .../dataframe/dataframe.sort_index.md | 74 --- .../dataframe/dataframe.sort_values.md | 99 ---- .../dataframe/dataframe.tensor.md | 110 ----- .../dataframe/dataframe.to_csv.md | 114 ----- .../dataframe/dataframe.to_excel.md | 53 -- .../dataframe/dataframe.to_json.md | 127 ----- .../dataframe/dataframe.values.md | 50 -- .../general-functions/README.md | 27 -- .../general-functions/danfo.concat.md | 187 -------- .../general-functions/danfo.date_range.md | 111 ----- .../general-functions/danfo.get_dummies.md | 188 -------- .../general-functions/danfo.labelencoder.md | 140 ------ .../general-functions/danfo.merge.md | 453 ------------------ .../general-functions/danfo.minmaxscaler.md | 125 ----- .../general-functions/danfo.onehotencoder.md | 148 ------ .../general-functions/danfo.standardscaler.md | 132 ----- .../general-functions/danfo.to_datetime.md | 141 ------ api-reference-v1-stable/groupby.md | 122 ----- api-reference-v1-stable/groupby/README.md | 34 -- .../groupby/groupby.agg.md | 93 ---- .../groupby/groupby.apply.md | 84 ---- .../groupby/groupby.col.md | 105 ---- .../groupby/groupby.count.md | 175 ------- .../groupby/groupby.cummax.md | 258 ---------- .../groupby/groupby.cummin.md | 258 ---------- .../groupby/groupby.cumprod.md | 258 ---------- .../groupby/groupby.cumsum.md | 259 ---------- .../groupby/groupby.get_groups.md | 129 ----- .../groupby/groupby.max.md | 170 ------- .../groupby/groupby.mean.md | 173 ------- .../groupby/groupby.min.md | 171 ------- .../groupby/groupby.std.md | 175 ------- .../groupby/groupby.sum.md | 172 ------- .../groupby/groupby.var.md | 175 ------- .../input-output/README.md | 18 - .../input-output/danfo.read_csv.md | 134 ------ .../input-output/danfo.read_excel.md | 68 --- .../input-output/danfo.read_json.md | 127 ----- .../input-output/danfo.to_csv.md | 115 ----- .../input-output/danfo.to_excel.md | 54 --- .../input-output/danfo.to_json.md | 124 ----- api-reference-v1-stable/input-output/read.md | 138 ------ api-reference-v1-stable/plotting/README.md | 19 - .../plotting/bar-charts.md | 75 --- api-reference-v1-stable/plotting/box-plots.md | 116 ----- .../plotting/configuring-your-plots.md | 68 --- .../plotting/histograms.md | 117 ----- .../plotting/line-charts.md | 109 ----- .../plotting/pie-charts.md | 123 ----- .../plotting/scatter-plots.md | 88 ---- api-reference-v1-stable/plotting/tables.md | 95 ---- .../plotting/timeseries-plots.md | 58 --- .../plotting/violin-plots.md | 112 ----- api-reference-v1-stable/series/README.md | 182 ------- .../series/creating-a-series.md | 210 -------- .../series/danfo.series.add.md | 22 - .../series/danfo.series.apply.md | 63 --- .../series/danfo.series.copy.md | 22 - .../series/danfo.series.count.md | 24 - .../series/danfo.series.describe.md | 26 - .../series/danfo.series.div.md | 26 - .../series/danfo.series.head.md | 25 - .../series/danfo.series.map.md | 42 -- .../series/danfo.series.max.md | 2 - .../series/danfo.series.maximum.md | 22 - .../series/danfo.series.mean.md | 2 - .../series/danfo.series.median.md | 2 - .../series/danfo.series.min.md | 2 - .../series/danfo.series.minimum.md | 22 - .../series/danfo.series.mod.md | 24 - .../series/danfo.series.mode.md | 2 - .../series/danfo.series.mul.md | 26 - .../series/danfo.series.pow.md | 26 - .../series/danfo.series.reset_index.md | 31 -- .../series/danfo.series.round.md | 20 - .../series/danfo.series.sample.md | 22 - .../series/danfo.series.set_index.md | 40 -- .../series/danfo.series.sort_values.md | 27 -- .../series/danfo.series.std.md | 20 - .../series/danfo.series.sub.md | 24 - .../series/danfo.series.sum-1.md | 22 - .../series/danfo.series.tail.md | 22 - .../series/danfo.series.tostring.md | 18 - .../series/danfo.series.var.md | 20 - api-reference-v1-stable/series/series.abs.md | 52 -- api-reference-v1-stable/series/series.add.md | 86 ---- api-reference-v1-stable/series/series.and.md | 132 ----- .../series/series.append.md | 135 ------ .../series/series.apply.md | 149 ------ .../series/series.argmax.md | 35 -- .../series/series.argmin.md | 35 -- .../series/series.argsort.md | 75 --- .../series/series.astype.md | 2 - api-reference-v1-stable/series/series.copy.md | 45 -- api-reference-v1-stable/series/series.corr.md | 2 - .../series/series.count.md | 36 -- .../series/series.cummax.md | 51 -- .../series/series.cummin.md | 51 -- .../series/series.cumprod.md | 51 -- .../series/series.cumsum.md | 74 --- .../series/series.describe.md | 57 --- api-reference-v1-stable/series/series.div.md | 87 ---- api-reference-v1-stable/series/series.dot.md | 2 - .../series/series.drop_duplicates.md | 121 ----- .../series/series.dropna.md | 91 ---- .../series/series.dt.day.md | 55 --- .../series/series.dt.hour.md | 52 -- .../series/series.dt.minute.md | 60 --- .../series/series.dt.month.md | 47 -- .../series/series.dt.month_name.md | 55 --- .../series/series.dt.monthday.md | 55 --- .../series/series.dt.second.md | 60 --- .../series/series.dt.weekdays.md | 79 --- .../series/series.dt.year.md | 45 -- .../series/series.dtype.md | 34 -- api-reference-v1-stable/series/series.eq.md | 95 ---- .../series/series.fillna.md | 106 ---- api-reference-v1-stable/series/series.ge.md | 95 ---- api-reference-v1-stable/series/series.gt.md | 95 ---- api-reference-v1-stable/series/series.head.md | 51 -- api-reference-v1-stable/series/series.iloc.md | 158 ------ .../series/series.index.md | 33 -- api-reference-v1-stable/series/series.isna.md | 45 -- api-reference-v1-stable/series/series.le.md | 96 ---- api-reference-v1-stable/series/series.loc.md | 198 -------- api-reference-v1-stable/series/series.lt.md | 96 ---- api-reference-v1-stable/series/series.map.md | 92 ---- api-reference-v1-stable/series/series.max.md | 36 -- .../series/series.maximum.md | 50 -- api-reference-v1-stable/series/series.mean.md | 36 -- .../series/series.median.md | 36 -- api-reference-v1-stable/series/series.min.md | 36 -- .../series/series.minimum.md | 48 -- api-reference-v1-stable/series/series.mod.md | 85 ---- api-reference-v1-stable/series/series.mode.md | 36 -- api-reference-v1-stable/series/series.mul.md | 86 ---- api-reference-v1-stable/series/series.ndim.md | 34 -- api-reference-v1-stable/series/series.ne.md | 95 ---- .../series/series.nunique.md | 34 -- api-reference-v1-stable/series/series.or.md | 132 ----- api-reference-v1-stable/series/series.pow.md | 87 ---- .../series/series.replace.md | 89 ---- .../series/series.reset_index.md | 113 ----- .../series/series.round.md | 48 -- .../series/series.sample.md | 65 --- .../series/series.set_index.md | 136 ------ .../series/series.shape.md | 35 -- api-reference-v1-stable/series/series.size.md | 37 -- .../series/series.sort_values.md | 140 ------ api-reference-v1-stable/series/series.std.md | 37 -- .../series/series.str.capitalize.md | 52 -- .../series/series.str.charat.md | 53 -- .../series/series.str.concat.md | 165 ------- .../series/series.str.endswith.md | 51 -- .../series/series.str.includes.md | 51 -- .../series/series.str.indexof.md | 51 -- .../series/series.str.join.md | 52 -- .../series/series.str.lastindexof.md | 54 --- .../series/series.str.len.md | 52 -- .../series/series.str.repeat.md | 51 -- .../series/series.str.replace.md | 50 -- .../series/series.str.search.md | 94 ---- .../series/series.str.slice.md | 54 --- .../series/series.str.split.md | 74 --- .../series/series.str.startswith.md | 51 -- .../series/series.str.substr.md | 50 -- .../series/series.str.substring.md | 56 --- .../series/series.str.tolowercase.md | 50 -- .../series/series.str.touppercase.md | 52 -- .../series/series.str.trim.md | 50 -- api-reference-v1-stable/series/series.sub.md | 86 ---- api-reference-v1-stable/series/series.sum.md | 36 -- api-reference-v1-stable/series/series.tail.md | 49 -- .../series/series.tensor.md | 46 -- .../series/series.unique.md | 55 --- .../series/series.value_counts.md | 54 --- .../series/series.values.md | 35 -- api-reference-v1-stable/series/series.var.md | 35 -- 239 files changed, 22625 deletions(-) delete mode 100644 api-reference-v1-stable/README.md delete mode 100644 api-reference-v1-stable/configuration-options.md delete mode 100644 api-reference-v1-stable/dataframe/README.md delete mode 100644 api-reference-v1-stable/dataframe/creating-a-dataframe.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.abs.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.add.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.apply.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.column.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.copy.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.count.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.describe.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.div.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.eq.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ge.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.gt.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.head.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.isna.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.it.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.le.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.loc.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.max.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mean.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.median.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.min.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mod.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.mul.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.ne.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.pow.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.query.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.replace.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.round.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sample.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.std.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sub.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.sum.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.tail.md delete mode 100644 api-reference-v1-stable/dataframe/danfo.dataframe.var.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.append.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.apply_map.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.astype.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.axes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.drop.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.dtypes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.ndim.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.nunique-1.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.print.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.rename.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.reset_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.select_dtypes.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.set_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.shape.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_index.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.sort_values.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.tensor.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_csv.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_excel.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.to_json.md delete mode 100644 api-reference-v1-stable/dataframe/dataframe.values.md delete mode 100644 api-reference-v1-stable/general-functions/README.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.concat.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.date_range.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.get_dummies.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.labelencoder.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.merge.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.minmaxscaler.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.onehotencoder.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.standardscaler.md delete mode 100644 api-reference-v1-stable/general-functions/danfo.to_datetime.md delete mode 100644 api-reference-v1-stable/groupby.md delete mode 100644 api-reference-v1-stable/groupby/README.md delete mode 100644 api-reference-v1-stable/groupby/groupby.agg.md delete mode 100644 api-reference-v1-stable/groupby/groupby.apply.md delete mode 100644 api-reference-v1-stable/groupby/groupby.col.md delete mode 100644 api-reference-v1-stable/groupby/groupby.count.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cummax.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cummin.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cumprod.md delete mode 100644 api-reference-v1-stable/groupby/groupby.cumsum.md delete mode 100644 api-reference-v1-stable/groupby/groupby.get_groups.md delete mode 100644 api-reference-v1-stable/groupby/groupby.max.md delete mode 100644 api-reference-v1-stable/groupby/groupby.mean.md delete mode 100644 api-reference-v1-stable/groupby/groupby.min.md delete mode 100644 api-reference-v1-stable/groupby/groupby.std.md delete mode 100644 api-reference-v1-stable/groupby/groupby.sum.md delete mode 100644 api-reference-v1-stable/groupby/groupby.var.md delete mode 100644 api-reference-v1-stable/input-output/README.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_csv.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_excel.md delete mode 100644 api-reference-v1-stable/input-output/danfo.read_json.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_csv.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_excel.md delete mode 100644 api-reference-v1-stable/input-output/danfo.to_json.md delete mode 100644 api-reference-v1-stable/input-output/read.md delete mode 100644 api-reference-v1-stable/plotting/README.md delete mode 100644 api-reference-v1-stable/plotting/bar-charts.md delete mode 100644 api-reference-v1-stable/plotting/box-plots.md delete mode 100644 api-reference-v1-stable/plotting/configuring-your-plots.md delete mode 100644 api-reference-v1-stable/plotting/histograms.md delete mode 100644 api-reference-v1-stable/plotting/line-charts.md delete mode 100644 api-reference-v1-stable/plotting/pie-charts.md delete mode 100644 api-reference-v1-stable/plotting/scatter-plots.md delete mode 100644 api-reference-v1-stable/plotting/tables.md delete mode 100644 api-reference-v1-stable/plotting/timeseries-plots.md delete mode 100644 api-reference-v1-stable/plotting/violin-plots.md delete mode 100644 api-reference-v1-stable/series/README.md delete mode 100644 api-reference-v1-stable/series/creating-a-series.md delete mode 100644 api-reference-v1-stable/series/danfo.series.add.md delete mode 100644 api-reference-v1-stable/series/danfo.series.apply.md delete mode 100644 api-reference-v1-stable/series/danfo.series.copy.md delete mode 100644 api-reference-v1-stable/series/danfo.series.count.md delete mode 100644 api-reference-v1-stable/series/danfo.series.describe.md delete mode 100644 api-reference-v1-stable/series/danfo.series.div.md delete mode 100644 api-reference-v1-stable/series/danfo.series.head.md delete mode 100644 api-reference-v1-stable/series/danfo.series.map.md delete mode 100644 api-reference-v1-stable/series/danfo.series.max.md delete mode 100644 api-reference-v1-stable/series/danfo.series.maximum.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mean.md delete mode 100644 api-reference-v1-stable/series/danfo.series.median.md delete mode 100644 api-reference-v1-stable/series/danfo.series.min.md delete mode 100644 api-reference-v1-stable/series/danfo.series.minimum.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mod.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mode.md delete mode 100644 api-reference-v1-stable/series/danfo.series.mul.md delete mode 100644 api-reference-v1-stable/series/danfo.series.pow.md delete mode 100644 api-reference-v1-stable/series/danfo.series.reset_index.md delete mode 100644 api-reference-v1-stable/series/danfo.series.round.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sample.md delete mode 100644 api-reference-v1-stable/series/danfo.series.set_index.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sort_values.md delete mode 100644 api-reference-v1-stable/series/danfo.series.std.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sub.md delete mode 100644 api-reference-v1-stable/series/danfo.series.sum-1.md delete mode 100644 api-reference-v1-stable/series/danfo.series.tail.md delete mode 100644 api-reference-v1-stable/series/danfo.series.tostring.md delete mode 100644 api-reference-v1-stable/series/danfo.series.var.md delete mode 100644 api-reference-v1-stable/series/series.abs.md delete mode 100644 api-reference-v1-stable/series/series.add.md delete mode 100644 api-reference-v1-stable/series/series.and.md delete mode 100644 api-reference-v1-stable/series/series.append.md delete mode 100644 api-reference-v1-stable/series/series.apply.md delete mode 100644 api-reference-v1-stable/series/series.argmax.md delete mode 100644 api-reference-v1-stable/series/series.argmin.md delete mode 100644 api-reference-v1-stable/series/series.argsort.md delete mode 100644 api-reference-v1-stable/series/series.astype.md delete mode 100644 api-reference-v1-stable/series/series.copy.md delete mode 100644 api-reference-v1-stable/series/series.corr.md delete mode 100644 api-reference-v1-stable/series/series.count.md delete mode 100644 api-reference-v1-stable/series/series.cummax.md delete mode 100644 api-reference-v1-stable/series/series.cummin.md delete mode 100644 api-reference-v1-stable/series/series.cumprod.md delete mode 100644 api-reference-v1-stable/series/series.cumsum.md delete mode 100644 api-reference-v1-stable/series/series.describe.md delete mode 100644 api-reference-v1-stable/series/series.div.md delete mode 100644 api-reference-v1-stable/series/series.dot.md delete mode 100644 api-reference-v1-stable/series/series.drop_duplicates.md delete mode 100644 api-reference-v1-stable/series/series.dropna.md delete mode 100644 api-reference-v1-stable/series/series.dt.day.md delete mode 100644 api-reference-v1-stable/series/series.dt.hour.md delete mode 100644 api-reference-v1-stable/series/series.dt.minute.md delete mode 100644 api-reference-v1-stable/series/series.dt.month.md delete mode 100644 api-reference-v1-stable/series/series.dt.month_name.md delete mode 100644 api-reference-v1-stable/series/series.dt.monthday.md delete mode 100644 api-reference-v1-stable/series/series.dt.second.md delete mode 100644 api-reference-v1-stable/series/series.dt.weekdays.md delete mode 100644 api-reference-v1-stable/series/series.dt.year.md delete mode 100644 api-reference-v1-stable/series/series.dtype.md delete mode 100644 api-reference-v1-stable/series/series.eq.md delete mode 100644 api-reference-v1-stable/series/series.fillna.md delete mode 100644 api-reference-v1-stable/series/series.ge.md delete mode 100644 api-reference-v1-stable/series/series.gt.md delete mode 100644 api-reference-v1-stable/series/series.head.md delete mode 100644 api-reference-v1-stable/series/series.iloc.md delete mode 100644 api-reference-v1-stable/series/series.index.md delete mode 100644 api-reference-v1-stable/series/series.isna.md delete mode 100644 api-reference-v1-stable/series/series.le.md delete mode 100644 api-reference-v1-stable/series/series.loc.md delete mode 100644 api-reference-v1-stable/series/series.lt.md delete mode 100644 api-reference-v1-stable/series/series.map.md delete mode 100644 api-reference-v1-stable/series/series.max.md delete mode 100644 api-reference-v1-stable/series/series.maximum.md delete mode 100644 api-reference-v1-stable/series/series.mean.md delete mode 100644 api-reference-v1-stable/series/series.median.md delete mode 100644 api-reference-v1-stable/series/series.min.md delete mode 100644 api-reference-v1-stable/series/series.minimum.md delete mode 100644 api-reference-v1-stable/series/series.mod.md delete mode 100644 api-reference-v1-stable/series/series.mode.md delete mode 100644 api-reference-v1-stable/series/series.mul.md delete mode 100644 api-reference-v1-stable/series/series.ndim.md delete mode 100644 api-reference-v1-stable/series/series.ne.md delete mode 100644 api-reference-v1-stable/series/series.nunique.md delete mode 100644 api-reference-v1-stable/series/series.or.md delete mode 100644 api-reference-v1-stable/series/series.pow.md delete mode 100644 api-reference-v1-stable/series/series.replace.md delete mode 100644 api-reference-v1-stable/series/series.reset_index.md delete mode 100644 api-reference-v1-stable/series/series.round.md delete mode 100644 api-reference-v1-stable/series/series.sample.md delete mode 100644 api-reference-v1-stable/series/series.set_index.md delete mode 100644 api-reference-v1-stable/series/series.shape.md delete mode 100644 api-reference-v1-stable/series/series.size.md delete mode 100644 api-reference-v1-stable/series/series.sort_values.md delete mode 100644 api-reference-v1-stable/series/series.std.md delete mode 100644 api-reference-v1-stable/series/series.str.capitalize.md delete mode 100644 api-reference-v1-stable/series/series.str.charat.md delete mode 100644 api-reference-v1-stable/series/series.str.concat.md delete mode 100644 api-reference-v1-stable/series/series.str.endswith.md delete mode 100644 api-reference-v1-stable/series/series.str.includes.md delete mode 100644 api-reference-v1-stable/series/series.str.indexof.md delete mode 100644 api-reference-v1-stable/series/series.str.join.md delete mode 100644 api-reference-v1-stable/series/series.str.lastindexof.md delete mode 100644 api-reference-v1-stable/series/series.str.len.md delete mode 100644 api-reference-v1-stable/series/series.str.repeat.md delete mode 100644 api-reference-v1-stable/series/series.str.replace.md delete mode 100644 api-reference-v1-stable/series/series.str.search.md delete mode 100644 api-reference-v1-stable/series/series.str.slice.md delete mode 100644 api-reference-v1-stable/series/series.str.split.md delete mode 100644 api-reference-v1-stable/series/series.str.startswith.md delete mode 100644 api-reference-v1-stable/series/series.str.substr.md delete mode 100644 api-reference-v1-stable/series/series.str.substring.md delete mode 100644 api-reference-v1-stable/series/series.str.tolowercase.md delete mode 100644 api-reference-v1-stable/series/series.str.touppercase.md delete mode 100644 api-reference-v1-stable/series/series.str.trim.md delete mode 100644 api-reference-v1-stable/series/series.sub.md delete mode 100644 api-reference-v1-stable/series/series.sum.md delete mode 100644 api-reference-v1-stable/series/series.tail.md delete mode 100644 api-reference-v1-stable/series/series.tensor.md delete mode 100644 api-reference-v1-stable/series/series.unique.md delete mode 100644 api-reference-v1-stable/series/series.value_counts.md delete mode 100644 api-reference-v1-stable/series/series.values.md delete mode 100644 api-reference-v1-stable/series/series.var.md diff --git a/api-reference-v1-stable/README.md b/api-reference-v1-stable/README.md deleted file mode 100644 index b5d5d28..0000000 --- a/api-reference-v1-stable/README.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - This page gives an overview of all public danfo objects, functions and - methods. All classes and functions exposed in danfo.* namespace are public. ---- - -# API reference - -* [General Functions](general-functions/) - * [Data manipulations](general-functions/#data-manipulations) - * [Data Processing/Normalization](general-functions/#data-processing-normalization) - * [Top-level dealing with datetime like](general-functions/#top-level-dealing-with-datetime) -* [Input/output](input-output/) - * [CSV](input-output/#csv) - * [JSON](input-output/#json) -* [Series](series/) - * [Attributes](series/#attributes) - * [Conversion](series/#conversion) - * [Indexing, iteration](series/#indexing-iteration) - * [Binary operator functions](series/#binary-operator-functions) - * [Function application, GroupBy & window](series/#function-application-and-groupby) - * [Computations / descriptive stats](series/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](series/#reindexing-selection-label-manipulation) - * [Missing data handling](series/#missing-data-handling) - * [Reshaping, sorting](series/#reshaping-sorting) - * [Accessors](series/#accessors) - * [Serialization / IO / conversion](series/#serialization-io-conversion) -* [DataFrame](dataframe/) - * [Attributes ](dataframe/#attributes) - * [Conversion](dataframe/#conversion) - * [Indexing, iteration](dataframe/#indexing-iteration) - * [Binary operator functions](dataframe/#binary-operator-functions) - * [Function application, GroupBy & window](dataframe/#function-application-and-groupby) - * [Computations / descriptive stats](dataframe/#computations-descriptive-stats) - * [Reindexing / selection / label manipulation](dataframe/#reindexing-selection-label-manipulation) - * [Missing data handling](dataframe/#missing-data-handling) - * [Reshaping, sorting, transposing](dataframe/#sorting-and-transposing) - * [Combining / comparing / joining / merging](dataframe/#combining-comparing-joining-merging) - * [Serialization / IO / conversion](dataframe/#serialization-io-conversion) -* [Plotting](plotting/) - * [Line Charts](plotting/line-charts.md) - * [Bar Charts](plotting/bar-charts.md) - * [Scatter Plots](plotting/scatter-plots.md) - * [Histograms](plotting/histograms.md) - * [Pie Charts](plotting/pie-charts.md) - * [Tables](plotting/tables.md) - * [Box Plots](plotting/box-plots.md) - * [Violin Plots](plotting/violin-plots.md) - * [Timeseries Plots](plotting/timeseries-plots.md) -* [GroupBy](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html) - * [Indexing, iteration](groupby/#indexing-iteration) - * [Function application](groupby/#function-application) - * [Computations / descriptive stats](groupby/#computations-descriptive-stats) - diff --git a/api-reference-v1-stable/configuration-options.md b/api-reference-v1-stable/configuration-options.md deleted file mode 100644 index f4c2136..0000000 --- a/api-reference-v1-stable/configuration-options.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: >- - This section describes all user configurable options available on - DataFrame/Series creation. ---- - -# Configuration Options - -On DataFrame/Series creation, a config object can be passed along to configure some internal properties of the created object. The following list shows what options are available and what they do. - -| Parameter | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| tableDisplayConfig | **Object**, General table display options. Because we use the table package under the hood to display a table in the console, all [table display configurations](https://www.npmjs.com/package/table) are supported. | -| tableMaxRow | **Number**, the total number of rows to display in the console when the **print** function is called. Defaults to 10 | -| dtypeTestLim | **Number**, the total number of values to test when inferring data type. Defaults to 10 | -| lowMemoryMode |

Boolean, whether to use minimal memory or not. Defaults to false.
Note: There's a slight decrease in speed when low memory mode is set to true.

| - -> See an example of creating DataFrame [in low memory mode](dataframe/creating-a-dataframe.md#creating-a-dataframe-and-specifying-memory-mode) - -## Examples of setting configs - -### Add a DataFrame header - -```javascript - const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] - }; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - }, - } -}); -df.print() -``` - -```javascript -╔════════════════════════════════════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟────────────┬───────────────────┬───────────────────┬───────────────────╢ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Configure column size and display format of DataFrame - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -}; -const df = new DataFrame(data, { - config: { - tableDisplayConfig: { - header: { - alignment: 'center', - content: 'THE HEADER\nThis is the table about something', - }, - columns: [ - { alignment: 'left' }, - { alignment: 'center', width: 20 }, - { alignment: 'right' }, - { alignment: 'justify' } - ], - }, - } -}); -df.print() -``` - -```javascript -╔══════════════════════════════════════════╗ -║ THE HEADER ║ -║ This is the table about something ║ -╟───┬──────────────────────┬───────┬───────╢ -║ │ Name │ Count │ Price ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼──────────────────────┼───────┼───────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧══════════════════════╧═══════╧═══════╝ -``` - -### Configure the number of rows displayed when **print** is called - -```javascript -const data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250], - -}; -const df = new DataFrame(data, { - config: { - tableMaxColInConsole: 6, - tableMaxRow: 1 - } -}); -df.print() -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/dataframe/README.md b/api-reference-v1-stable/dataframe/README.md deleted file mode 100644 index d48a28d..0000000 --- a/api-reference-v1-stable/dataframe/README.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -description: Two-dimensional, size-mutable, potentially heterogeneous tabular data. ---- - -# Dataframe - -> `DataFrame`(data, {\ -> **columns:** \[ Array ],\ -> **dtypes:** \[ Array ], **** \ -> **index:** \[Array], \ -> **options**: Object}) - -### Attributes - -| [`DataFrame.index`](dataframe.index.md) | The index (row labels) of the DataFrame. | -| ------------------------------------------------ | ---------------------------------------- | -| [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | - -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| -------------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.select_dtypes`](dataframe.select\_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | - -### Conversion - -| [`DataFrame.astype`](dataframe.astype.md) | Cast a pandas object to a specified dtype `dtype`. | -| ------------------------------------------- | -------------------------------------------------- | -| [`DataFrame.copy`](danfo.dataframe.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows | -| --------------------------------------------- | ------------------------------------------------------------------ | -| [`DataFrame.loc`](danfo.dataframe.loc.md) | Access a group of rows and columns by label(s) or a boolean array. | -| [`DataFrame.iloc`](danfo.dataframe.iloc.md) | Purely integer-location based indexing for selection by position. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | -| [`DataFrame.query`](danfo.dataframe.query.md) | Query the columns of a DataFrame with a boolean expression. | - -### Binary operator functions - -| [`DataFrame.add`](danfo.dataframe.add.md) | Get Addition of dataframe and other, element-wise (binary operator add). | -| ----------------------------------------- | --------------------------------------------------------------------------------------- | -| [`DataFrame.sub`](danfo.dataframe.sub.md) | Get Subtraction of dataframe and other, element-wise (binary operator sub). | -| [`DataFrame.mul`](danfo.dataframe.mul.md) | Get Multiplication of dataframe and other, element-wise (binary operator mul). | -| [`DataFrame.div`](danfo.dataframe.div.md) | Get Floating division of dataframe and other, element-wise (binary operator truediv). | -| [`DataFrame.mod`](danfo.dataframe.mod.md) | Get Modulo of dataframe and other, element-wise (binary operator mod). | -| [`DataFrame.pow`](danfo.dataframe.pow.md) | Get Exponential power of dataframe and other, element-wise (binary operator pow). | -| [`DataFrame.lt`](broken-reference) | Get Less than of dataframe and other, element-wise (binary operator lt). | -| [`DataFrame.gt`](danfo.dataframe.gt.md) | Get Greater than of dataframe and other, element-wise (binary operator gt). | -| [`DataFrame.le`](danfo.dataframe.le.md) | Get Less than or equal to of dataframe and other, element-wise (binary operator le). | -| [`DataFrame.ge`](broken-reference) | Get Greater than or equal to of dataframe and other, element-wise (binary operator ge). | -| [`DataFrame.ne`](danfo.dataframe.ne.md) | Get Not equal to of dataframe and other, element-wise (binary operator ne). | -| [`DataFrame.eq`](danfo.dataframe.eq.md) | Get Equal to of dataframe and other, element-wise (binary operator eq). | - -### Function application & GroupBy - -| [`DataFrame.apply`](danfo.dataframe.apply.md) | Apply a function along an axis of the DataFrame. | -| --------------------------------------------- | --------------------------------------------------------- | -| [`DataFrame.groupby`](../groupby/) | Group DataFrame using a mapper or by a Series of columns. | -| [`DataFrame.map`](../series/series.map.md) | Map a function on Object along an axis to DataFrame | - -### Computations / descriptive stats - -| [`DataFrame.abs`](danfo.dataframe.abs.md) | Return a Series/DataFrame with absolute numeric value of each element. | -| --------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.corr`](broken-reference) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrame.count`](danfo.dataframe.count.md) | Count non-NAN cells for each column or row. | -| [`DataFrame.cummax`](danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`DataFrame.cummin`](danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`DataFrame.cumprod`](danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`DataFrame.cumsum`](danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`DataFrame.describe`](danfo.dataframe.describe.md) | Generate descriptive statistics. | -| [`DataFrame.max`](danfo.dataframe.max.md) | Return the maximum of the values for the requested axis. | -| [`DataFrame.mean`](danfo.dataframe.mean.md) | Return the mean of the values for the requested axis. | -| [`DataFrame.median`](danfo.dataframe.median.md) | Return the median of the values for the requested axis. | -| [`DataFrame.min`](danfo.dataframe.min.md) | Return the minimum of the values for the requested axis. | -| [`DataFrame.mode`](../series/series.mode.md) | Get the mode(s) of each element along the selected axis. | -| [`DataFrame.round`](danfo.dataframe.round.md) | Round a DataFrame to a variable number of decimal places. | -| [`DataFrame.sum`](danfo.dataframe.sum.md) | Return the sum of the values for the requested axis. | -| [`DataFrame.std`](danfo.dataframe.std.md) | Return sample standard deviation over requested axis. | -| [`DataFrame.var`](danfo.dataframe.var.md) | Return unbiased variance over requested axis. | -| [`DataFrame.nunique`](broken-reference) | Count distinct observations over requested axis. | - -### Reindexing / selection / label manipulation - -| | | -| ---------------------------------------------------- | ------------------------------------------------------- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset\_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------------------- | ------------------------------------------- | -| [`DataFrame.dropna`](danfo.dataframe.dropna.md) | Remove missing values. | -| [`DataFrame.fillna`](danfo.dataframe.fillna.md) | Fill NaN values with specified values | -| [`DataFrame.isna`](danfo.dataframe.isna.md) | Detect missing values. | -| [`DataFrame.replace`](danfo.dataframe.replace.md) | Replace values given in replace with value. | - -### Sorting & transposing - -| | | -| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| [`DataFrame.sort_values`](dataframe.sort\_values.md) | Sort by the values along either axis. | -| [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | - -### Combining / comparing / joining / merging - -| | | -| ---------------------------------------------------------- | ------------------------------------------------------------------- | -| [`DataFrame.addColumn`](danfo.dataframe.addcolumn.md) | Add new columns to a DataFrame. | -| [`DataFrame.concat`](../general-functions/danfo.concat.md) | Concatenate DataFrames together. | -| [`DataFrame.merge`](../general-functions/danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| -------------------------------------------------------- | ------------------------------------------------------------- | -| [DataFrame.plot.bar](../plotting/bar-charts.md) | Vertical bar plot. | -| [`DataFrame.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`DataFrame.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`DataFrame.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`DataFrame.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`DataFrame.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`DataFrame.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| -------------------------------------------- | ---------------------------------------------------- | -| [`DataFrame.to_csv`](dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`DataFrame.to_json`](dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/dataframe/creating-a-dataframe.md b/api-reference-v1-stable/dataframe/creating-a-dataframe.md deleted file mode 100644 index 0228131..0000000 --- a/api-reference-v1-stable/dataframe/creating-a-dataframe.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -description: Creates a DataFrame object from flat structure ---- - -# Creating a DataFrame - -new danfo.**DataFrame**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data2D Array, 2D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

columns: Array of column names. If not specified, column names are - auto generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a DataFrame, you new to call the new Keyword and pass in a flat data structure. In the following examples, we show you how to create DataFrames by specifying different config options. - -### Creating a `DataFrame` from a JSON object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -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 }] - -df = new dfd.DataFrame(json_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Creating a `DataFrame` from an array of array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let arr = [[12, 34, 2.2, 2], [30, 30, 2.1, 7]] -let df = new dfd.DataFrame(arr, {columns: ["A", "B", "C", "D"]}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.2 │ 2 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.1 │ 7 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` from a 2D tensor - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -const tf = require("@tensorflow/tfjs-node") - - -let tensor_arr = tf.tensor2d([[12, 34, 2.2, 2], [30, 30, 2.1, 7]]) -let df = new dfd.DataFrame(tensor_arr, {columns: ["A", "B", "C", "D"]}) -df.print() -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 34 │ 2.20000004768... │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 30 │ 2.09999990463... │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` - -### Creating a `DataFrame` from an object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -dates = new dfd.date_range({ start: '2017-01-01', end: "2020-01-01", period: 4, freq: "Y" }) - -console.log(dates); - -obj_data = {'A': dates, - 'B': ["bval1", "bval2", "bval3", "bval4"], - 'C': [10, 20, 30, 40], - 'D': [1.2, 3.45, 60.1, 45], - 'E': ["test", "train", "test", "train"] - } - -df = new dfd.DataFrame(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -//output in console -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D │ E ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1/1/2017, 1:0... │ bval1 │ 10 │ 1.2 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1/1/2018, 1:0... │ bval2 │ 20 │ 3.45 │ train ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1/1/2019, 1:0... │ bval3 │ 30 │ 60.1 │ test ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1/1/2020, 1:0... │ bval4 │ 40 │ 45 │ train ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying index, dtypes, columns - -You can create a DataFrame and specify options like index, column names, dtypes as well as configuration options like display, memory mode etc. - -> Note: Specifing dtypes, column names and index on DataFrame creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; -let index = ["a", "b"]; -let columns = ["col1", "col2", "col3", "col4", "col5", "col6"] -let dtypes = ["int32", "float32", "int32", "int32", "int32", "string"] - -let df = new DataFrame(data1, { index, columns, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 │ col5 │ col6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 1 │ 2.3 │ 3 │ 4 │ 5 │ girl ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 40.1 │ 39 │ 89 │ 78 │ boy ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -### Creating a `DataFrame` and specifying memory mode - -To use less space on DataFrame creation, you can set the low memory mode as demonstrated below: - -```javascript -import { DataFrame } from "danfojs" - -let data1 = [[1, 2.3, 3, 4, 5, "girl"], [30, 40.1, 39, 89, 78, "boy"]]; - -let df = new DataFrame(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the DataFrame. The drawback is that some operations especially the ones involving column data become slightly slower. -{% endhint %} - -For loading flat files like CSV, EXCEL and, JSON into DataFrames, see this [page](../input-output/) - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md b/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md deleted file mode 100644 index 8504222..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.abs.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a DataFrame with the absolute numeric value of each element. ---- - -# DataFrame.abs - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - - **** return **Series** - -## **Examples** - -The abs function only works on numeric columns and will throw an error if string columns are found in the DataFrame. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let df_abs = df.abs() -df_abs.abs().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after applying abs function - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.add.md b/api-reference-v1-stable/dataframe/danfo.dataframe.add.md deleted file mode 100644 index 925a3cd..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.add.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -description: Get Addition of DataFrame and other, element-wise (binary operator add). ---- - -# DataFrame.add - -danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Addition of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.add(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.add(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 8 │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 9 │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.add(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 2 │ 22 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 9 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 25 │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Addition of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.add(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Addition works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.add(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 12 │ 25 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 47 │ 22 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 58 │ 12 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 26 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md b/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md deleted file mode 100644 index ef0ecc9..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.addcolumn.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Add new column to a DataFrame ---- - -# DataFrame.addColumn - -danfo.DataFrame.**addColumn**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1083)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| options | Object |

{column : str, name of the column to add

values: Series, Array of new values to add
inplace: Default to false.

}

| | - -**Returns:** - -## **Examples** - -## **Add Array as a new column to DataFrame** - -New columns get added at the end of the DataFrame, and this happens so returns nothing, - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -df.print() - -let new_col = [1, 2, 3, 4] -df.addColumn({ "column": "D", "values": new_col, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Add Series as a new column to DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) -let s = new dfd.Series([1, 2, 3, 4]) -df.addColumn({ "column": "D", "values": s, inplace: true }); - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md b/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md deleted file mode 100644 index de42294..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.apply.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Apply a function to each element or along a specified axis of a DataFrame. ---- - -# DataFrame.apply - -danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Apply a function along default axis 1 (columns) - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with an array of the values across the specified axis. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 1 }) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ A │ 64 ║ -╟───┼─────╢ -║ B │ 126 ║ -╟───┼─────╢ -║ C │ 127 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### Apply a function along axis 0 (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [4, 5, 6], [20, 30, 40], [39, 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -function sum_vals(col) { - return col.reduce((a, b) => a + b, 0); -} - -let df_new = df.apply(sum_vals, { axis: 0 }) -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ 6 ║ -╟───┼─────╢ -║ 1 │ 15 ║ -╟───┼─────╢ -║ 2 │ 90 ║ -╟───┼─────╢ -║ 3 │ 206 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.column.md b/api-reference-v1-stable/dataframe/danfo.dataframe.column.md deleted file mode 100644 index 7d963a2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.column.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -description: Return the elements of the specified column in the DataFrame ---- - -# DataFrame.column - -danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1217)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------- | ------- | -| column | String | The name of a column in the DataFrame | | - -**Returns:** - - **** return **Series** - -## **Examples** - -## **Select a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { "Name": ["Apples", "App", "Banana", undefined], - "Count": [NaN, 5, NaN, 10] , - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) - -df.column("Name").print() - -//Alternatively, you can retrieve columns by using the object property -df['Name'].print() //produces the same result as above - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -╔═══╤═══════════╗ -║ 0 │ Apples ║ -╟───┼───────────╢ -║ 1 │ App ║ -╟───┼───────────╢ -║ 2 │ Banana ║ -╟───┼───────────╢ -║ 3 │ undefined ║ -╚═══╧═══════════╝ - -``` -{% endtab %} -{% endtabs %} - -To select more than one column with specific rows, you can use any of the following: [DataFrame.loc](danfo.dataframe.loc.md), [DataFrame.iloc](danfo.dataframe.iloc.md) or [DataFrame.query](danfo.dataframe.query.md) diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md b/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md deleted file mode 100644 index 188179d..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.copy.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Makes a new copy of the DataFrame ---- - -# DataFrame.copy - -danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -**Returns:** - - **** return **new DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) -let new_df = df.copy() -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.count.md b/api-reference-v1-stable/dataframe/danfo.dataframe.count.md deleted file mode 100644 index 637cbf4..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.count.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Count non-NaN cells for each column or row. The values NaN and undefined are - considered NaN ---- - -# DataFrame.count - -danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Count Non-NaN values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤══════════════════════╗ -║ │ 0 ║ -╟───────┼──────────────────────╢ -║ Name │ 3 ║ -╟───────┼──────────────────────╢ -║ Count │ 2 ║ -╟───────┼──────────────────────╢ -║ Price │ 4 ║ -╚═══════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Count Non-NaN values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.count({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md deleted file mode 100644 index fb69bb5..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cummax.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative maximum over a DataFrame or Series axis. ---- - -# DataFrame.cummax - -danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative maximum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 11 │ 20 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 11 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 11 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative maximum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummax({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 15 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 89 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md deleted file mode 100644 index be026a6..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cummin.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative minimum over a DataFrame or Series axis. ---- - -# DataFrame.cummin - -danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative minimum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 15 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 15 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative minimum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cummin({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 11 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 2 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md deleted file mode 100644 index 06ad53a..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cumprod.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative product over a DataFrame or Series axis. ---- - -# DataFrame.cumprod - -danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative product of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 10 │ 18 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 300 │ 720 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 26700 │ 56160 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative product of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[1, 2, 3], [1, 5, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumprod({axis: 1}) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 60 │ 2400 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 178 │ 13884 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md deleted file mode 100644 index 07be896..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.cumsum.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Return cumulative sum over a DataFrame or Series axis. ---- - -# DataFrame.cumsum - -danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L706)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -| options | Object |

axis: 0 for row and 1 for column

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {axis: 1, inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Cumulative sum of elements along default axis (row) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 0 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 12 │ 35 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 14 │ 65 │ 49 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 16 │ 154 │ 127 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Cumulative sum of elements along column axis (1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let new_df = df.cumsum({ axis: 1 }) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 31 │ 34 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 16 │ 22 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 32 │ 72 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 91 │ 169 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md b/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md deleted file mode 100644 index 0540873..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.describe.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -description: >- - Generate descriptive statistics for each numeric column. Numeric columns are - of type Int and float. ---- - -# DataFrame.describe - -danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L821)] - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [[0, 2, 4, "a"], [360, 180, 360, "b"], [2, 4, 6, "c"]] -let col_names = ["col1", "col2", "col3", "col4"] -let df = new dfd.DataFrame(data, {columns: col_names}) - -df.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ count │ 3 │ 3 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ mean │ 120.66666666666… │ 62 │ 123.33333333333… ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ std │ 207.27115895206… │ 102.19589032832… │ 204.961785055979 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ min │ 0 │ 2 │ 4 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ median │ 2 │ 4 │ 6 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ max │ 360 │ 180 │ 360 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ variance │ 42961.333333333… │ 10444 │ 42009.333333333… ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.div.md b/api-reference-v1-stable/dataframe/danfo.dataframe.div.md deleted file mode 100644 index c98c66e..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.div.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -description: >- - Get Float division of DataFrame and other, element-wise (binary operator - truediv). ---- - -# DataFrame.div - -danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Division of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.div(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.div(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0.25 │ 0.6000000238418… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0.4000000059604… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1.25 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0.25 │ 0.8000000119209… ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of **** DataFrame **with** a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.div(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0.1000000014901… ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.8000000119209… │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0.25 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Division of **** Array **with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.div(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Division works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.div(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 5 │ 11.5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 22.5 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 28 │ 5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 5 │ 12 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md deleted file mode 100644 index 429bcbe..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.dropna.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Remove missing values (NaNs, undefined, null) for DataFrame ---- - -# DataFrame.dropna - -danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1430)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | -| options | Object |

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {**inplace:** false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Drop rows (axis=0) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -let df_drop = df.dropna(0) -df_drop.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop columns (axis=1) with missing values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.print() - -df.dropna({axis: 1, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╗ -║ │ C ║ -╟───┼───────────────────╢ -║ 0 │ 3 ║ -╟───┼───────────────────╢ -║ 1 │ 6 ║ -╟───┼───────────────────╢ -║ 2 │ 40 ║ -╟───┼───────────────────╢ -║ 3 │ 78 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md b/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md deleted file mode 100644 index 5f3cf2a..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.eq.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -description: Get Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.eq - -danfo.DataFrame.eq(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.eq(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.eq(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.eq(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.eq(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md deleted file mode 100644 index 2ddb860..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.fillna.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -description: >- - Fill NaN/undefined values using the specified method. Detect missing values - for an array-like object. ---- - -# DataFrame.fillna - -danfo.DataFrame.**fillna**(values, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1235)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| values | Array \| Scalar | The list of value(s) to use for replacement. | | -| options | Object |

{columns:Array of column name(s) to fill. If undefined fill all columns

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Fill missing values in specified columns with specified values - -Missing values are NaN, undefined or null values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -df.print() - -let values = ["Apples", df["Count"].mean()] -let df_filled = df.fillna(values, { columns: ["Name", "Count"] }) -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//Before filling -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ NaN │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ NaN │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ NaN │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After filling - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 7.5 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 7.5 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝═╝ -``` -{% endtab %} -{% endtabs %} - -### Fill all columns with NaNs with a specified value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let df_filled = df.fillna("Apples") - -df_filled.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill NaNs inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = { - "Name": ["Apples", "Mango", "Banana", undefined], - "Count": [NaN, 5, NaN, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data) -let values = ["Apples", df["Count"].mean()] -df.fillna(values, { - columns: ["Name", "Count"], - inplace: true -}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ Apples │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ Apples │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Apples │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md deleted file mode 100644 index 8e5401b..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.ge.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -description: >- - Get Greater or Equal to of DataFrame and other, element-wise (binary operator - eq). ---- - -# DataFrame.ge - -danfo.DataFrame.ge(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.ge(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ge(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ge(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.ge(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md b/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md deleted file mode 100644 index e7d084f..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.groupby.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Group DataFrame using a mapper or by a Series of columns. ---- - -# DataFrame.groupby - -danfo.DataFrame.**groupby**(columns) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1142)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | ----------------------------------------------------- | ------- | -| columns | Array | The names of a column(s) in the DataFrame to group by | | - -**Returns:** - - **** return **DataFrame.groups** - -## **Examples** - -## **Groupby a single column from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]) -console.log(group_df) - -//GroupBy Object -GroupBy { - key_col: [ 'A' ], - col_dict: { Pear: [ [Array], [Array] ], Apple: [ [Array], [Array] ] }, - data: [ - [ 'Pear', 2, 3 ], - [ 'Pear', 5, 6 ], - [ 'Apple', 30, 40 ], - [ 'Apple', 89, 78 ] - ], - column_name: [ 'A', 'B', 'C' ], - data_tensors: { - Pear: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - '$index': [Array], - '$dtypes': [Array], - '$columns': [Array] - }, - Apple: DataFrame { - '$isSeries': false, - '$config': [Configs], - '$data': [Array], - '$dataIncolumnFormat': [Array], - ... - '$columns': [Array] - } - }, - col_dtype: [ 'string' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -A groupby operation will return a GroupBy class object. You can apply any of the following operation on the groupby result: - -1. [count](danfo.dataframe.count.md) -2. [sum](danfo.dataframe.sum.md) -3. [std](danfo.dataframe.std.md) -4. [var](danfo.dataframe.var.md) -5. [mean](danfo.dataframe.mean.md) -6. [cumsum](danfo.dataframe.cumsum.md) -7. [cummax](danfo.dataframe.cummax.md) -8. [cumprod](danfo.dataframe.cumprod.md) -9. [cummin](danfo.dataframe.cummin.md) -10. [max](danfo.dataframe.max.md) -11. [min](danfo.dataframe.min.md) - -## Example of Groupby and apply a sum function - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 5, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A"]).sum() - -group_df.print() - -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B_sum │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 7 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 119 │ 118 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -## **Groupby a two columns from a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["Pear", 2, 3], ["Pear", 2, 6], ["Apple", 30, 40], ["Apple", 89, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -let group_df = df.groupby(["A", "B"]).sum() - -group_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Pear │ 2 │ 9 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Apple │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Apple │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md b/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md deleted file mode 100644 index ec3f7ba..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.gt.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -description: Get Greater than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.gt - -danfo.DataFrame.g**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.gt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.gt(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.gt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.gt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.head.md b/api-reference-v1-stable/dataframe/danfo.dataframe.head.md deleted file mode 100644 index 3fe62c4..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.head.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the first n rows of the DataFrame based on position. ---- - -# DataFrame.head - -danfo.DataFrame.**head**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.head(2) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md deleted file mode 100644 index ffd7e25..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.iloc.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -description: Purely integer-location based indexing for selection by position. ---- - -# DataFrame.iloc - -danfo.DataFrame.**iloc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| args | Object |

{

rows: Array, index of row position

columns: Array, index of position along columns

}

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A string slice object with ints, e.g. `"1:7"` -* A boolean array. - -_**Note:** only the start index is included._ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,1,3]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row and return all columns** - -The [**iloc**](danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[1: 3]". This will return all values between index position 1 and 3. The end index is not included. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: ["1:3"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of column and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by the specified index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let sub_df = df.iloc({rows: [0,3], columns: [1,2]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Indexing both axes by slices - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:3"], columns: ["1:2"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -╔═══╤═══════════════════╗ -║ │ Count ║ -╟───┼───────────────────╢ -║ 2 │ 30 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### More default slicing behavior - -If you specify a slice start position, **iloc** automatically returns all values after that position. For instance: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -df.print() - -let sub_df = df.iloc({rows: ["2:"], columns: ["1:"]}) -sub_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md b/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md deleted file mode 100644 index 830bda5..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.isna.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Return a boolean same-sized object indicating if the values are NaN. - NaN/undefined values gets mapped to true values, and everything else gets - mapped to false values. ---- - -# DataFrame.isna - -danfo.DataFrame.**isna**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1350)] - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[1, 2, 3], [NaN, 5, 6], [NaN, 30, 40], [39, undefined, 78]] -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.isna().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ false │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ true │ false │ false ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ false │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.it.md b/api-reference-v1-stable/dataframe/danfo.dataframe.it.md deleted file mode 100644 index 3759197..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.it.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: Get Less than of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.It - -danfo.DataFrame.l**t**(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.lt(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10, 40]) - -let df_rep = df.lt(sf, { axis: 1 }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.lt(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.lt(val, axis=1) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.le.md b/api-reference-v1-stable/dataframe/danfo.dataframe.le.md deleted file mode 100644 index 31ce3f7..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.le.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -description: >- - Get Less than or Equal to of DataFrame and other, element-wise (binary - operator eq). ---- - -# DataFrame.le - -danfo.DataFrame.le(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) - -let df_rep = df.le(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.le(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.le(df2) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with an Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10,40] - -let df_rep = df.le(val, {axis:1}) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md b/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md deleted file mode 100644 index abdcdd9..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.loc.md +++ /dev/null @@ -1,367 +0,0 @@ ---- -description: Access a group of rows and columns by label(s) ---- - -# DataFrame.loc - -danfo.DataFrame.**loc**(args) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- | -| args | Object |

{

rows: Array, labels, Boolean mask of row index

columns: Array, labels of column names

}

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -`.loc()` is label position based-from `0` to `length-1` of the row axis. - -Allowed inputs for are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Index by specific rows and return all columns** - -If the row's index is specified and the columns are not, then it returns all columns and just the specified rows. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({rows: ["a", "c"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a list of column names and return all rows** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.print() -let sub_df = df.loc({columns: ["Count", "Price"]}) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after indexing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Count │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ a │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────╢ -║ b │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Index both axes by the specified labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: ["c","d"], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after slicing - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ c │ Banana │ 40 ║ -╟───┼───────────────────┼───────────────────╢ -║ d │ Pear │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"c"\`]**. This will return all values from label positions `a` to c. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -df.print() -let sub_df = df.loc({ rows: [`"a":"c"`], columns: ["Name", "Price"] }) -sub_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Price ║ -╟────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 200 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 300 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc with alphabetic slices. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -df`.loc({ row: [a:e]}).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -df``.loc({ row: [`"a":"e"`]}).print()``\ -\ -_**Inner**_ _**quotes are not needed for numeric indices!**_ -{% endhint %} - -### Slice DataFrame rows by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let sub_df = df.loc({ rows: df["Count"].gt(6) }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -### Slice DataFrame rows by multiple boolean conditions - -{% hint style="info" %} -_By design, you can chain as many boolean logic as possible, as long as they resolve to a Boolean array of the same length as the DataFrame._ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) -let condition = df["Count"].gt(6).and(df["Price"].lt(250)) -let sub_df = df.loc({ rows: condition }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ Apples │ 21 │ 200 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` - -### Slice DataFrame with boolean mask - -{% hint style="info" %} -_You can index a DataFrame with an array of boolean values as long as they resolve to an array of the same length as the DataFrame._ -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] -} - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c", "d"] }) - -let sub_df = df.loc({ rows: [false, true, true, true] }) -sub_df.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ Pear │ 10 │ 250 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.max.md b/api-reference-v1-stable/dataframe/danfo.dataframe.max.md deleted file mode 100644 index a5c2119..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.max.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -description: Return the maximum of the values for the requested axis. ---- - -# DataFrame.max - -danfo.DataFrame.**max**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Return the maximum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.max().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 11 ║ -╟───┼──────────────────────╢ -║ B │ 89 ║ -╟───┼──────────────────────╢ -║ C │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the maximum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.max({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 20 ║ -╟───┼──────────────────────╢ -║ 1 │ 15 ║ -╟───┼──────────────────────╢ -║ 2 │ 40 ║ -╟───┼──────────────────────╢ -║ 3 │ 89 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md deleted file mode 100644 index 172cff5..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mean.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the mean of the values for the requested axis. ---- - -# DataFrame.mean - -danfo.DataFrame.**mean**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Computes the mean of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.mean().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 4 ║ -╟───┼──────────────────────╢ -║ B │ 38.5 ║ -╟───┼──────────────────────╢ -║ C │ 31.75 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Computes the mean of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -let cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.mean({ axis: 0 }).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11.333333015441895 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.333333492279053 ║ -╟───┼──────────────────────╢ -║ 2 │ 24 ║ -╟───┼──────────────────────╢ -║ 3 │ 56.33333206176758 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.median.md b/api-reference-v1-stable/dataframe/danfo.dataframe.median.md deleted file mode 100644 index 3e33583..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.median.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the median of the values for the requested axis. ---- - -# DataFrame.median - -danfo.DataFrame.**median**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculates the median of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.median().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 2 ║ -╟───┼──────────────────────╢ -║ B │ 25 ║ -╟───┼──────────────────────╢ -║ C │ 23 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the median of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.median({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 11 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 30 ║ -╟───┼──────────────────────╢ -║ 3 │ 78 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.min.md b/api-reference-v1-stable/dataframe/danfo.dataframe.min.md deleted file mode 100644 index 49a13d6..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.min.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Return the minimum of the values for the requested axis. ---- - -# DataFrame.min - -danfo.DataFrame.**min**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Returns the minimum value along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() - -let df = new dfd.DataFrame(data) -df.min().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ 1 ║ -╟───┼──────────────────────╢ -║ B │ 15 ║ -╟───┼──────────────────────╢ -║ C │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Return the minimum value along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -df.print() -let df = new dfd.DataFrame(data) -df.min({axis: 0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11 │ 20 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 2 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md deleted file mode 100644 index 18558e6..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Get Modulo of DataFrame and other, element-wise (binary operator mod). ---- - -# DataFrame.mod - -danfo.DataFrame.mod(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Modulo of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mod(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mod(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 4 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mod(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 5 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Modulo of **** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mod(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Modulo works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mod(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 0 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md b/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md deleted file mode 100644 index 3303d77..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.mul.md +++ /dev/null @@ -1,252 +0,0 @@ ---- -description: Get Multiplication of dataframe and other, element-wise (binary operator mul). ---- - -# DataFrame.mul - -danfo.DataFrame.mul(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Multiplication of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.mul(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.mul(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 4 │ 15 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 16 │ 10 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 4 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.mul(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 100 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 8 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.mul(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Multiplication works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.mul(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 46 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 90 │ 40 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 112 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 48 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md b/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md deleted file mode 100644 index dd45cf0..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.ne.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Get Not Equal to of DataFrame and other, element-wise (binary operator eq). ---- - -# DataFrame.ne - -danfo.DataFrame.ne(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------------------------------- | ----------------------------------------------------------- | --------- | -| other | DataFrame, Series, Array, Scalar | Data structure, or array-like object to compare against | | -| option | Object | **axis**: 0 or 1. If 0, add column-wise, if 1, add row-wise | {axis: 1} | - -**Returns:** - -**** - -## **Examples** - -### Comparing **** DataFrame with a scalar value: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) - -let df_rep = df.ne(20) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ false ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ true │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a Series along the column axis: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([10,40]) - -let df_rep = df.ne(sf, {axis:1}) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ true ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let data2 = {"new_col1": [10, 45, 200, 10], - "new_Col2": [230, 200, 110, 24]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_rep = df.ne(df2) - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ false │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ true │ true ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ false │ false ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Comparing **** DataFrame with a JavaScript Array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24]} -let df = new dfd.DataFrame(data) -let val = [10, 40, 30, 20] - -let df_rep = df.le(val) - -df_rep.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ true │ false │ false │ true ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ false │ true │ true │ false ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md b/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md deleted file mode 100644 index e6f1e6c..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.pow.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -description: >- - Get Exponential power of dataframe and other, element-wise (binary operator - pow). ---- - -# DataFrame.pow - -danfo.DataFrame.pow(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Exponential of **scalar with** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.pow(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **Series with** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.pow(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 243 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 256 │ 32 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 625 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 1 │ 1024 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **** DataFrame with a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.pow(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1048576 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1024 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 95367433551872 │ 1 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 16 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - -### Exponential of **** Array with DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.pow(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Exponential works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.pow(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 529 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 2025 │ 400 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 3136 │ 100 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 100 │ 576 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.query.md b/api-reference-v1-stable/dataframe/danfo.dataframe.query.md deleted file mode 100644 index 129c8e7..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.query.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -description: >- - Query the DataFrame by the result of a logical comparison or boolean mask. - Supports logical operations like (">", "<", ">=", "<=", and. "==") ---- - -# DataFrame.query - -danfo.DataFrame.**query**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1011)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| kwargs | Object |

{

condition: A logical boolean mask,

column : str, name of the column

is: Logical operator, one of ">", "<", ">=", "<=", and. "=="

to: Int, Float, Str. Value to compare against,

inplace: boolean. true | false. Whether to perform operation to the original Object or create a new one.

}

| {**inplace**: false} | - -**Returns:** - - **** return **new DataFrame** - -## **Examples** - -## **Query a DataFrame using a boolean mask** - -{% hint style="info" %} -Querying by a boolean condition is supported from v0.3.0 and above. -{% endhint %} - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5) }) -query_df.print() //after query -``` - -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -It also supports condition chaining as long as the final boolean mask is the same lenght as the DataFrame rows. For example in the following code, we use multiple chaining conditions: - -```javascript -let data = { - "A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40] -} -let df = new dfd.DataFrame(data) - -let query_df = df.query({ condition: df["B"].gt(5).and(df["C"].lt(40)) }) -query_df.print() //after query - -//output -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` - -## **Query a DataFrame using logical operators** - -To query a DataFrame, you can specify the column to use, the logical operator (">", "<", ">=", "<=", and. "=="), and the value to compare against. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() //before query - -let query_df = df.query({ "column": "B", "is": ">", "to": 5 }) -query_df.print() //after query -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ "column": "A", "is": ">", "to": 9 }) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query by a string column in a DataFrame** - -The query method also works on string columns. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": ["Ng", "Yu", "Mo", "Ng"], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let df = new dfd.DataFrame(data) - -df.print() - -let query_df = df.query({ column: "A", is: "==", to: "Ng"}) -query_df.print() //after query - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Yu │ 4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Mo │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//after query - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Ng │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Ng │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## **Query a DataFrame inplace** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [30, 1, 2, 3], - "B": [34, 4, 5, 6], - "C": [20, 20, 30, 40]} - -let cols = ["A", "B", "C"] -let df = new dfd.DataFrame(data, { columns: cols }) - -df.query({ - column: "B", - is: ">", - to: 5, - inplace: true -}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 30 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 3 │ 6 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md b/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md deleted file mode 100644 index 82fa16d..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.replace.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -description: Replaces values in a DataFrame with specified values ---- - -# DataFrame.replace - -> danfo.DataFrame.**replace**(oldValue, newValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1670)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -| oldValue | String, boolean, Number | The value you want to replace | | -| newValue | String, boolean, Number | The new value you want to replace the old value with | | -| options | Object |

columns: Array. An array of column names to replace, If not specified, replace all columns.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -**** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_rep = df.replace(10, -999, { columns: ["Col1"] }) - -df_rep.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -999 │ 23 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 45 │ 20 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 56 │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -999 │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By not specifying a **** column**,** the **** replace works on all columns **** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [["A", "A", "A", "B"], ["B", "C", "C", "D"]] -let df = new dfd.DataFrame(data) -//replace value in all column -let df_rep = df.replace("A", "BOY") - -df_rep.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```javascript - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ BOY │ BOY │ BOY │ B ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ B │ C │ C │ D ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.round.md b/api-reference-v1-stable/dataframe/danfo.dataframe.round.md deleted file mode 100644 index e12cb52..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.round.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -description: Round elements in a DataFrame to a specified number of decimal places. ---- - -# DataFrame.round - -danfo.DataFrame.**round**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------- | ------------------ | -| dp | Int | Number of decimal places to round to. Defaults to 1 | 1 | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -## Round elements to 1dp (Default) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round() - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1 │ 3.6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.1 │ 40.2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Round elements to a specified number of decimal places - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -data = [[11.20, 20.1234, 3.567], [1, 15.1, 6.0], [2, 3.09, 40.234]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data, { columns: cols }) -df.print() - -let new_df = df.round(2) - -new_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.1234 │ 3.567 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.234 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after round operation - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 11.2 │ 20.12 │ 3.57 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 1 │ 15.1 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 3.09 │ 40.23 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md deleted file mode 100644 index b8a4c96..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sample.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -description: Return a random sample of rows from DataFrame. ---- - -# DataFrame.sample - -danfo.DataFrame.**sample**(num, seed) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L314)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------- | ------- | -| num | Int | The number of rows to return. Defaults to -1, which shuffles and return all rows. | -1 | -| seed | int | An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. | 1 | - -**Returns:** - - **** return **{Promies} resolves to DataFrame** - -**** - -## Sample a DataFrame randomly - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(2); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sample a DataFrame randomly with seed - -By setting `seed` when using `sample`, you can ensure that the random sampling is reproducible. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data = { - Name: ["Apples", "Mango", "Banana", "Pear"], - Count: [21, 5, 30, 10], - Price: [200, 300, 40, 250], - }; - - let df = new dfd.DataFrame(data); - let s_df = await df.sample(3, { seed: 2 }); - s_df.print(); - -} - -load_data() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ Mango │ 5 │ 300 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ Apples │ 21 │ 200 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.std.md b/api-reference-v1-stable/dataframe/danfo.dataframe.std.md deleted file mode 100644 index 1a37e2e..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.std.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return sample standard deviation over requested axis. ---- - -# DataFrame.std - -danfo.DataFrame.**std**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculates the standard deviation of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4.69041575982343 ║ -╟───┼──────────────────────╢ -║ 1 │ 34.23935357645254 ║ -╟───┼──────────────────────╢ -║ 2 │ 35.103418636936205 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculates the standard deviation of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.std({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 8.504900548115383 ║ -╟───┼──────────────────────╢ -║ 1 │ 7.094598884597588 ║ -╟───┼──────────────────────╢ -║ 2 │ 19.697715603592208 ║ -╟───┼──────────────────────╢ -║ 3 │ 47.37439533475159 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md deleted file mode 100644 index e36ddcc..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sub.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -description: Get Subtraction of dataframe and other, element-wise (binary operator sub). ---- - -# DataFrame.sub - -danfo.DataFrame.sub(other, option) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L347)] - -| Parameters | Type | Description | Default | -| ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| other | DataFrame, Series, Array or Scalar | Object to add with | | -| option | Object |

{

axis: 0 for row, 1 for column.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Subtraction of **scalar to** DataFrame along default axis 1 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} -let df = new dfd.DataFrame(data) - -let df_new = df.sub(2) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **Series to** DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [1, 4, 5, 1], - "Col2": [3, 2, 0, 4] -} - -let df = new dfd.DataFrame(data) -let sf = new dfd.Series([4, 5]) - -let df_new = df.sub(sf, { axis: 1 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ -3 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ -3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ -5 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -3 │ -1 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **** DataFrame to a DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = {"Col1": [1, 4, 5, 0], - "Col2": [2, 0, 1, 4]} - -let data2 = {"new_col1": [1, 5, 20, 10], - "new_Col2": [20, 2, 1, 2]} - -let df = new dfd.DataFrame(data) -let df2 = new dfd.DataFrame(data2) - -let df_new = df.sub(df2) - -df_new.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ -18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ -1 │ -2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ -15 │ 0 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ -10 │ 2 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### Subtraction of **** Array to DataFrame along axis 0 - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -let df_new = df.sub(val, { axis: 0 }) - -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - -### Subtraction works inplace - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "Col1": [10, 45, 56, 10], - "Col2": [23, 20, 10, 24] -} - -let df = new dfd.DataFrame(data) -let val = [2, 2, 2, 2] - -df.sub(val, { axis: 0, inplace: true }) - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ Col1 │ Col2 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ 8 │ 21 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ 43 │ 18 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ 54 │ 8 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ 8 │ 22 ║ -╚════════════╧═══════════════════╧═══════════════════╝ - - -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md b/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md deleted file mode 100644 index 3937d3f..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.sum.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Return the sum of the values for the requested axis. ---- - -# DataFrame.sum - -danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Sum elements along default axis (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum() -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤════════════════════╗ -║ A │ 37.199999999999996 ║ -╟───┼────────────────────╢ -║ B │ 41 ║ -╟───┼────────────────────╢ -║ C │ -10 ║ -╚═══╧════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Sum elements along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -df.print() - -let df_sum = df.sum({axis: 0}) -df_sum.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ sum ║ -╟───┼──────────────────────╢ -║ 0 │ 33.9 ║ -╟───┼──────────────────────╢ -║ 1 │ 6 ║ -╟───┼──────────────────────╢ -║ 2 │ 82.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -54 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md b/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md deleted file mode 100644 index 165acac..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.tail.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Returns the last n rows from the DataFrame based on position. ---- - -# DataFrame.tail - -danfo.DataFrame.**tail**(rows) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L292)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | ---------------------------- | ------- | -| rows | Int | The number of rows to return | 5 | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Name": ["Apples", "Mango", "Banana", "Pear"], - "Count": [21, 5, 30, 10], - "Price": [200, 300, 40, 250] } - -let df = new dfd.DataFrame(data) -let s_df = df.tail(3) -s_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Name │ Count │ Price ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ Banana │ 30 │ 40 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ Pear │ 10 │ 250 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/danfo.dataframe.var.md b/api-reference-v1-stable/dataframe/danfo.dataframe.var.md deleted file mode 100644 index ea0daf2..0000000 --- a/api-reference-v1-stable/dataframe/danfo.dataframe.var.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return unbiased variance over requested axis. ---- - -# DataFrame.var - -danfo.DataFrame.**var**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L454)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------- | ----------- | -| options | Object | **axis:** 0 or 1. If 0, compute the mean column-wise, if 1, row-wise. Defaults to 1 | { axis: 1 } | - -**Returns:** - - **** return **Series** - -## **Examples** - -## Calculate variance of values along default axis 1 (column) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 22 ║ -╟───┼──────────────────────╢ -║ 1 │ 1172.3333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 1232.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -## Calculate variance of values along row axis (0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -data = [[11, 20, 3], [1, 15, 6], [2, 30, 40], [2, 89, 78]] -cols = ["A", "B", "C"] - -let df = new dfd.DataFrame(data) -df.var({axis:0}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 72.33333333333334 ║ -╟───┼──────────────────────╢ -║ 1 │ 50.33333333333333 ║ -╟───┼──────────────────────╢ -║ 2 │ 388 ║ -╟───┼──────────────────────╢ -║ 3 │ 2244.333333333333 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/dataframe/dataframe.append.md b/api-reference-v1-stable/dataframe/dataframe.append.md deleted file mode 100644 index bc2e29d..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.append.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -description: Adds new row to the end of a DataFrame ---- - -# DataFrame.append - -danfo.DataFrame.**append**(val) \[[source](https://github.com/opensource9ja/danfojs/blob/2696f1d8420dd364464aae7c5c175c6cd0ef4c93/danfojs/src/core/frame.js#L2059)] - -| Parameters | Type | Description | Default | -| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | -| newValues | Array, Series or DataFrame | Value to append to the DataFrame | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as`newValues` as they map `1 - 1`. | | -| options | Object |

Optional parameters

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace : false

}

| - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Appends a new row to the end of a DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data) -df.print() - -let new_df = df.append([[20, 40, 60, "d"]], [3]) -new_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (4,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 20 │ 40 │ 60 │ d ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/dataframe/dataframe.apply_map.md b/api-reference-v1-stable/dataframe/dataframe.apply_map.md deleted file mode 100644 index 3819821..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.apply_map.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Apply a function to a Dataframe values element-wise. ---- - -# DataFrame.apply\_map - -danfo.DataFrame.**apply\_map**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L1566)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | --------------------------------------------------------------------- | --------- | -| callable | Function | Function to apply to each column or row | | -| options | Object | **axis**: 0 or 1. If 0, compute the power column-wise, if 1, row-wise | {axis: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Apply a function to all values in a DataFrame - -{% hint style="info" %} -Note that the specified function passed to `apply` will be called with each element in the DataFrame. If you need to apply a function across an axis, then use the [apply](danfo.dataframe.apply.md) function. -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - short_name: ["NG", "GH", "EGY", "SA"], - long_name: ["Nigeria", "Ghana", "Eqypt", "South Africa"] -} -let df = new dfd.DataFrame(data) - -function lower(x) { - return `${x}`.toLowerCase() -} - -let df_new = df.apply_map(lower) -df_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ short_name │ long_name ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 0 │ ng │ nigeria ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 1 │ gh │ ghana ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 2 │ egy │ eqypt ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 3 │ sa │ south africa ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.astype.md b/api-reference-v1-stable/dataframe/dataframe.astype.md deleted file mode 100644 index e6434dc..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.astype.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -description: Cast column of a DataFrame to a specified dtype. ---- - -# DataFrame.astype - -danfo.DataFrame.**astype**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Cast a float dtype column to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.print() -df.ctypes.print() - -let df_new = df.astype({column: "A", dtype: "int32"}) -df_new.print() - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//before casting -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ - - - //after casting - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20.1 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47 │ 5 │ 30.3 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ int32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Casting a string column of numbers to int** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["20", "13", "45", "90"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ 13 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ 45 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ 90 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -**Note:** Casting a string column of alphabets/words to numeric form will return NaNs as values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20.1, 30, 47.3, -20] , - "B": [34, -4, 5, 6], - "C": [20.1, -20.23, 30.3, 40.11], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -let df_new = df.astype({column: "D", dtype: "int32"}) -df_new.print() - -df_new.ctypes.print() - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20.1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20.23 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30.3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 40.11 │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ float32 ║ -╟───┼──────────────────────╢ -║ D │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.axes.md b/api-reference-v1-stable/dataframe/dataframe.axes.md deleted file mode 100644 index 399a0a4..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.axes.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: >- - Return an Object containing the axes of the DataFrame. It has the row axis - labels and column axis labels as the only members. They are returned in that - order. ---- - -# DataFrame.axis - -danfo.DataFrame.**axis** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Object** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.axis) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -{ index: [ 'a', 'b', 'c', 'd' ], columns: [ 'A', 'B', 'C' ] } -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.drop.md b/api-reference-v1-stable/dataframe/dataframe.drop.md deleted file mode 100644 index 0b742aa..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.drop.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -description: >- - Drop specified labels from rows or columns.Remove rows or columns by - specifying label names and corresponding axis. ---- - -# DataFrame.drop - -danfo.DataFrame.**drop**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| options | Object |

{

columns: Array of column names to drop.

index: Array of index labels to drop.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Drop columns by specifying the names - -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.drop({ columns: ["C", "B"], inplace: true }); -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ D ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ a ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ b ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ c ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ c ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying int labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] -} - -let df = new dfd.DataFrame(data) -df.drop({ index: [0, 2], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop rows by specifying string labels/index - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20], - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) -df.drop({ index: ["a", "c"], inplace: true }); -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ d │ -20 │ 6 │ 30 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.dtypes.md b/api-reference-v1-stable/dataframe/dataframe.dtypes.md deleted file mode 100644 index 791d296..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.dtypes.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: >- - Return the inferred column types in the DataFrame. This returns a Series with - the data type of each column. The result’s index is the original DataFrame’s - columns. ---- - -# DataFrame.ctypes - -danfo.DataFrame.**dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/frame.js#L1848)] - -**Returns:** - - **** return **Series** - -## **Examples** - -Returns auto-generated **** index of a **** DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Columns with mixed types are represented as **string.** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -df.ctypes.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ A │ float32 ║ -╟───┼──────────────────────╢ -║ B │ int32 ║ -╟───┼──────────────────────╢ -║ C │ int32 ║ -╟───┼──────────────────────╢ -║ D │ string ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note**: To cast a type, use the [astype](dataframe.astype.md) method. diff --git a/api-reference-v1-stable/dataframe/dataframe.index.md b/api-reference-v1-stable/dataframe/dataframe.index.md deleted file mode 100644 index a185e63..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.index.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -description: The index (row labels) of the DataFrame. ---- - -# DataFrame.index - -danfo.DataFrame.**index** \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/frame.js#L940)] - -## **Examples** - -Returns auto-generated **** index of a **** DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[0, 1, 2, 3] -``` -{% endtab %} -{% endtabs %} - - - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["r1", "r2", "r3", "r4"]) - -console.log(df.index); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 'r1', 'r2', 'r3', 'r4' ] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.ndim.md b/api-reference-v1-stable/dataframe/dataframe.ndim.md deleted file mode 100644 index c64dd09..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.ndim.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: >- - Return an int representing the number of axes / array dimensions. Returns 1 if - Series. Otherwise return 2 for DataFrame. ---- - -# DataFrame.ndim - -danfo.DataFrame.**ndim** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** - -**Note:** To get the **shape** of the DataFrame use the .[shape](dataframe.shape.md) property. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data) - -console.log(df.ndim) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -2 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.nunique-1.md b/api-reference-v1-stable/dataframe/dataframe.nunique-1.md deleted file mode 100644 index 8166904..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.nunique-1.md +++ /dev/null @@ -1,98 +0,0 @@ -# DataFrame.nunique - -danfo.DataFrame.**nunique**(axis) \[[source](https://github.com/opensource9ja/danfojs/blob/f84d7f53f2b0639e464f9483fb5cea969ad913d6/danfojs/src/core/frame.js#L1975)] - -| Parameters | Type | Description | Default | -| ---------- | ---- | -------------------------------------- | ------- | -| axis | Int | 0 for row axis, and 1 for column axis | 1 | - -**Returns:** - - **** return **Series** - -## **Examples** - -### Return number of unique values along column axis (axis=1) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique().print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 4 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} - -### Return number of unique values in row axis (axis=0) - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30], - "D": ["a", "b", "c", "c"] } - -let df = new dfd.DataFrame(data) -df.nunique(axis=0).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 4 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note:** To get the unique elements along an axis, use **** [DataFrame.unique.](dataframe.nunique-1.md) diff --git a/api-reference-v1-stable/dataframe/dataframe.print.md b/api-reference-v1-stable/dataframe/dataframe.print.md deleted file mode 100644 index d03232d..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.print.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: >- - Pretty prints default (10) number of rows in a DataFrame or Series to the - console ---- - -# DataFrame.print - -danfo.DataFrame.**print()** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 4 │ FR ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ GH ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Using JavaScript default **console.log** to display a DataFrame will return the Object instead unless you manually cast it to a String - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 4, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -console.log(df) -console.log(String(df)); -// console.log(df + ""); //same result as above -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -DataFrame { - '$isSeries': false, - '$config': Configs { - tableDisplayConfig: {}, - tableMaxRow: 10, - tableMaxColInConsole: 21, - dtypeTestLim: 7, - lowMemoryMode: false - }, - '$data': [ [ 20.2, 34, 'NG' ], [ 30, 5, 'FR' ], [ 47.3, 6, 'GH' ] ], - '$dataIncolumnFormat': [ [ 20.2, 30, 47.3 ], [ 34, 5, 6 ], [ 'NG', 'FR', 'GH' ] ], - '$index': [ 0, 1, 2 ], - '$dtypes': [ 'float32', 'int32', 'string' ], - '$columns': [ 'Abs', 'Count', 'country code' ] -} -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Abs │ Count │ country code ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20.2 │ 34 │ NG ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ FR ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ GH ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.rename.md b/api-reference-v1-stable/dataframe/dataframe.rename.md deleted file mode 100644 index c33ce99..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.rename.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: >- - Change axes labels. Object values must be unique (1-to-1). Labels not - contained in a dict / Series will be left as-is. Extra labels listed don’t - throw an error. ---- - -# DataFrame.rename - -danfo.DataFrame.**rename**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -| options | Object |

{

mapper: Object of labels and transformations to apply to that axis’ values.

axis: row=0, columns=1.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**axis**: 1, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### Rename columns - -By setting **inplace** to _true_, the original DataFrame is modified and nothing is returned. To not modify the original DataFrame and return a new one, set **inplace** to false or leave it as default. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 5], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df.rename({ mapper: {"A": "new_name"},inplace: true }) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename more the one column at time - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] } - - -let df = new dfd.DataFrame(data) -df = df.rename({ mapper: {"A": "new_name", "C": "new_c"}}) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ new_name │ B │ new_c ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Rename index by labels - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, -4, 6], - "C": [20, 2, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df = df.rename({ mapper: { "a": 0 }, axis: 0 }) -df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -4 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 47.3 │ 5 │ 30 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.reset_index.md b/api-reference-v1-stable/dataframe/dataframe.reset_index.md deleted file mode 100644 index ddee8e0..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.reset_index.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -description: Reset the index of the DataFrame, and use the default one instead. ---- - -# DataFrame.reset\_index - -danfo.DataFrame.**reset\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object |

{

inplace: sBoolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {inplace: false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] -} - - -let df = new dfd.DataFrame(data, { index: ["a", "b", "c"] }) -df.print() - -df.reset_index({ inplace: true }) //inplace -//df = df.reset_index() //not in inplace - -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md b/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md deleted file mode 100644 index ba5044e..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.select_dtypes.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Return a subset of the DataFrame’s columns based on the column dtypes. ---- - -# DataFrame.select\_dtypes - -danfo.DataFrame.**select\_dtypes** \[[source](https://github.com/opensource9ja/danfojs/blob/db48bf9701e1c3205811ba2699b42ce56ef7e63b/danfojs/src/core/frame.js#L778)] - -| Parameters | Type | Description | Default | -| ---------- | ----- | -------------------------------- | ------- | -| include | Array | List of column dtypes to return | | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40], - "D": ["a", "b", 20, 2.5]} - -let df = new dfd.DataFrame(data) - -float_df = df.select_dtypes(['float32']) -float_df.print() - -mix_df = df.select_dtypes(include=['float32', "int32"]) -mix_df.print() - -str_df = df.select_dtypes(include=['string']) -str_df.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//select float column(s) -╔═══╤══════════════════════╗ -║ │ A ║ -╟───┼──────────────────────╢ -║ 0 │ -20.1 ║ -╟───┼──────────────────────╢ -║ 1 │ 30 ║ -╟───┼──────────────────────╢ -║ 2 │ 47.3 ║ -╟───┼──────────────────────╢ -║ 3 │ -20 ║ -╚═══╧══════════════════════╝ - - - //select both float and int columns - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20.1 │ 34 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -4 │ -20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 5 │ 30 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ -20 │ 6 │ -40 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//return string type column -╔═══╤══════════════════════╗ -║ │ D ║ -╟───┼──────────────────────╢ -║ 0 │ a ║ -╟───┼──────────────────────╢ -║ 1 │ b ║ -╟───┼──────────────────────╢ -║ 2 │ 20 ║ -╟───┼──────────────────────╢ -║ 3 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.set_index.md b/api-reference-v1-stable/dataframe/dataframe.set_index.md deleted file mode 100644 index e82c213..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.set_index.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -description: >- - Set the DataFrame index using existing columns or an array (of the equal - length). ---- - -# DataFrame.set_index - -danfo.DataFrame.**set_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| options | Object |

{

index: An array of index values to set.

column: A column name to set the index to.

drop: Whether to drop the column whose index was set. Defaults to false.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**drop**: false, **inplace:**false} | - -## **Examples** - -### **Setting index to a column in the DataFrame** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ -20 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 30 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **** - -### **Setting index to a column in the DataFrame and dropping the column** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data, {index: ["a", "b", "c"]}) -df.print() - -df.set_index({column: "A", drop: true, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╗ -║ │ B │ C ║ -╟────────────┼───────────────────┼───────────────────╢ -║ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────╢ -║ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Set index to an array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, -5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.print() - -let new_index = ["a", "b", "c"] -df.set_index({index: new_index, inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 30 │ -5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**Note:** To reset an index to the default values, use the [DataFrame.reset_index](dataframe.reset_index.md). diff --git a/api-reference-v1-stable/dataframe/dataframe.shape.md b/api-reference-v1-stable/dataframe/dataframe.shape.md deleted file mode 100644 index 746491d..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.shape.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -description: Returns an Array representing the dimensionality of the DataFrame. ---- - -# DataFrame.shape - -danfo.DataFrame.**shape** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Int** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} -let df = new dfd.DataFrame(data, {index: ["a", "b", "c", "d"]}) - -console.log(df.shape) - - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[4,3] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_index.md b/api-reference-v1-stable/dataframe/dataframe.sort_index.md deleted file mode 100644 index 81d5b7f..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.sort_index.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Sort DataFrame by index ---- - -# DataFrame.sort\_index - -DataFrame.**sort\_index**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/frame.js#L2094)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

ascending: Sorting order.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [[0, 2, 4, "b"], - [360, 180, 360, "a"], - [2, 4, 6, "c"]] - -let df = new dfd.DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], - index: ["b", "a", "c"] }) -df.print() - -let df2 = df.sort_index({ ascending: false }) -df2.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after sorting in descending order - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ col1 │ col2 │ col3 │ col4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ c │ 2 │ 4 │ 6 │ c ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ b │ 0 │ 2 │ 4 │ b ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ a │ 360 │ 180 │ 360 │ a ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/dataframe/dataframe.sort_values.md b/api-reference-v1-stable/dataframe/dataframe.sort_values.md deleted file mode 100644 index 54345b1..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.sort_values.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -description: Sort a Dataframe in ascending or descending order by a specified column name. ---- - -# DataFrame.sort\_values - -danfo.DataFrame.**sort\_values**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -| options | Object |

{

by: This key can be either a single column name or a single array of the same length as the calling DataFrame,

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| {**ascending**: true, **inplace:**false} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Sort DataFrame by a column in ascending order** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "C", inplace: true}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Sort DataFrame by a column in descending order** - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3], - "B": [34, 5, 6], - "C": [20, 3, 30] } - - -let df = new dfd.DataFrame(data) -df.sort_values({by: "B", inplace: true, ascending: false}) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 5 │ 3 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.tensor.md b/api-reference-v1-stable/dataframe/dataframe.tensor.md deleted file mode 100644 index 822886e..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.tensor.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -description: >- - Return a Tensorflow tensor representation of the DataFrame. Only the values in - the DataFrame will be returned, the axes labels will be removed. ---- - -# DataFrame.tensor - -danfo.DataFrame.**tensor** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **tf.tensor** - -> **Note:** [Tensorflow](https://js.tensorflow.org/api/latest/#tensor) tensors have single dtype, and will replace any string value with NaN. Use with care. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "A": [-20, 30, 47.3, -20] , - "B": [34, -4, 5, 6] , - "C": [20, 20, 30, 30]} - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -Tensor - [[-20 , 34, 20], - [30 , -4, 20], - [47.2999992, 5 , 30], - [-20 , 6 , 30]] -``` -{% endtab %} -{% endtabs %} - -String values in a Tensor are represented as NaN, so ensure to transform them before working with tensor representations. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { "Abs": [20.2, 30, 47.3] , - "Count": [34, 5, 6] , - "country code": ["NG", "FR", "GH"] } - - -let df = new dfd.DataFrame(data) -let tf_tensor = df.tensor - -console.log(tf_tensor.dtype); - -console.log(tf_tensor); - -tf_tensor.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 - -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 3, 3 ], - dtype: 'float32', - size: 9, - strides: [ 3 ], - dataId: {}, - id: 0, - rankType: '2' -} - -Tensor - [[20.2000008, 34, NaN], - [30 , 4 , NaN], - [47.2999992, 5 , NaN]] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/dataframe/dataframe.to_csv.md b/api-reference-v1-stable/dataframe/dataframe.to_csv.md deleted file mode 100644 index 8e84e9a..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_csv.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -description: Convert DataFrame data to a comma-separated values (csv) ---- - -# DataFrame.to\_csv - -DataFrame.**to\_csv**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] - -| | | | | -| -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -*** - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = df.to_csv({ download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in browser - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_csv({ fileName: "testOut.csv", download: true}); -``` diff --git a/api-reference-v1-stable/dataframe/dataframe.to_excel.md b/api-reference-v1-stable/dataframe/dataframe.to_excel.md deleted file mode 100644 index 4adf437..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_excel.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# DataFrame.to_excel - -> DataFrame.**to_excel**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in a browser - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_excel({ fileName: "testOut.xlsx"}); -``` diff --git a/api-reference-v1-stable/dataframe/dataframe.to_json.md b/api-reference-v1-stable/dataframe/dataframe.to_json.md deleted file mode 100644 index 326f422..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.to_json.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -description: Convert DataFrame to JSON format ---- - -# DataFrame.to\_json - -> DataFrame.**to\_json**(options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| | | | | -| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = df.to_json({ download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = df.to_json({ - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -df.to_json({ fileName: "test_out.json" }); -``` diff --git a/api-reference-v1-stable/dataframe/dataframe.values.md b/api-reference-v1-stable/dataframe/dataframe.values.md deleted file mode 100644 index 598e395..0000000 --- a/api-reference-v1-stable/dataframe/dataframe.values.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Return a the JavaScript array representation of the DataFrame. ---- - -# DataFrame.values - -danfo.DataFrame.**values** \[[source](https://github.com/opensource9ja/danfojs/blob/eb5919d2cac34271fc3b725fa24aa3ad4eacde37/danfojs/src/core/generic.js#L290)] - -**Returns:** - - **** return **Array** - -**Note:** To get the [Tensorflow](https://js.tensorflow.org) tensor backing the DataFrame, you can call the **.**[**tensor**](dataframe.tensor.md) property on the DataFrame. - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = {"A": [-20.1, 30, 47.3, -20], - "B": [34, -4, 5, 6], - "C": [20, -20, 30, -40]} - -let df = new dfd.DataFrame(data) - -console.log(df.values) - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - [ -20.1, 34, 20 ], - [ 30, -4, -20 ], - [ 47.3, 5, 30 ], - [ -20, 6, -40 ] -] -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/general-functions/README.md b/api-reference-v1-stable/general-functions/README.md deleted file mode 100644 index 07815b0..0000000 --- a/api-reference-v1-stable/general-functions/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: Top level functions that can be called from the Danfo namespace ---- - -# General Functions - -### Data manipulations - -| | | -| ------------------------------------- | ----------------------------------------------------------------------------------------------- | -| [`merge`](danfo.merge.md) | Merge DataFrame or named Series objects with a database-style join. | -| [`concat`](danfo.concat.md) | Concatenate danfo objects along a particular axis with optional set logic along the other axes. | -| [`get_dummies`](danfo.get_dummies.md) | Convert categorical variable into dummy/indicator variables. Similar to OneHotEncoding | - -### Data Processing/Normalization - -| [LabelEncoder](danfo.labelencoder.md) | Encode target labels with value between 0 and n_classes-1. | -| ----------------------------------------- | ---------------------------------------------------------------------- | -| [OneHotEncoder](danfo.onehotencoder.md) | Encode categorical features as a one-hot numeric array. | -| [StandardScaler](danfo.standardscaler.md) | Standardize features by removing the mean and scaling to unit variance | -| [`MinMaxScaler`](danfo.minmaxscaler.md) | Transform features by scaling each feature to a given range | - -### Top-level dealing with datetime - -| [`toDateTime`](danfo.to_datetime.md) | Convert argument to datetime. | -| ------------------------------------ | --------------------------------------- | -| [`date_range`](danfo.date_range.md) | Return a fixed frequency DatetimeIndex. | diff --git a/api-reference-v1-stable/general-functions/danfo.concat.md b/api-reference-v1-stable/general-functions/danfo.concat.md deleted file mode 100644 index e248f46..0000000 --- a/api-reference-v1-stable/general-functions/danfo.concat.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -description: Concatenate DataFrames and Series along an axis ---- - -# danfo.concat - -danfo.**concat**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -| **kwargs** | Object |

{

df_list: List of DataFrames or Series to concatenate together.

axis: One of 0 or 1. The axis on which to perform concatenation. Specified axis must align in both Objects

}

| {**axis**: 1} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Concatenate two DataFrames along column axis (1)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 1 }) -com_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ ... │ Key1_2 │ Key2_2 │ A_2 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ ... │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ ... │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ ... │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ ... │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two DataFrames along row axis (0)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Concatenate two Series along row axis (0)** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], -['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], -['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) - - -let com_df = dfd.concat({ df_list: [df1, df2], axis: 0 }) -com_df.print(10) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K0 │ k0 │ C0 │ NaN │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ K1 │ K0 │ C1 │ NaN │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ K1 │ K0 │ C2 │ NaN │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ K2 │ K0 │ C3 │ NaN │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. diff --git a/api-reference-v1-stable/general-functions/danfo.date_range.md b/api-reference-v1-stable/general-functions/danfo.date_range.md deleted file mode 100644 index 9c4a337..0000000 --- a/api-reference-v1-stable/general-functions/danfo.date_range.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -description: Return a fixed frequency Dates spread between start and end parameters. ---- - -# danfo.date\_range - -danfo.**date\_range**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| **kwargs** | Object |

{

start: str or datetime-like. Left bound for generating dates.

end: str or datetime-like. Right bound for generating dates.

period : int. Number of periods to generate.

freq: str or DateOffset, one of ["M","D","s","H","m","Y"].

}

| {**freq:** 'D'} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:5, freq:'M'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '2/1/2018, 12:00:00 AM', - '3/1/2018, 12:00:00 AM', - '4/1/2018, 12:00:00 AM', - '5/1/2018, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'Y'}) -console.log(data); -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ - '1/1/2018, 12:00:00 AM', - '1/1/2019, 12:00:00 AM', - '1/1/2020, 12:00:00 AM', - '1/1/2021, 12:00:00 AM', - '1/1/2022, 12:00:00 AM', - '1/1/2023, 12:00:00 AM', - '1/1/2024, 12:00:00 AM', - '1/1/2025, 12:00:00 AM', - '1/1/2026, 12:00:00 AM', - '1/1/2027, 12:00:00 AM', - '1/1/2028, 12:00:00 AM', - '1/1/2029, 12:00:00 AM' -] -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -datetime properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.get_dummies.md b/api-reference-v1-stable/general-functions/danfo.get_dummies.md deleted file mode 100644 index e53fd81..0000000 --- a/api-reference-v1-stable/general-functions/danfo.get_dummies.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -description: Convert categorical variable into dummy/indicator variables. ---- - -# danfo.get\_dummies - -danfo.**get\_dummies**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| data | Series or Dataframe | The data to dummify | | -| **options** | Object |

{

columns: Array of column names to dummify. If not specified, all categorical columns are encoded.

prefixSeparator: String separator for created columns e.g "_",

prefix: String | Array of String, of column names

}

| {**prefixSeparator**: "\_"} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let datasf = ['pear', 'mango', "pawpaw", "mango", "bean"] -let sf1 = new dfd.Series(datasf) - -let dum_df = dfd.get_dummies(sf1, { prefix: "fruit" }) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruit_pear │ fruit_mango │ fruit_pawpaw │ fruit_bean ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert all categorical columns in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ fruits_pear │ fruits_mango │ ... │ fruits_bean │ Country_NG │ Country_GH │ Country_RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ 1 │ 0 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ 0 │ 1 │ ... │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ 0 │ 0 │ ... │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ 0 │ 1 │ ... │ 0 │ 0 │ 0 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ 0 │ 0 │ ... │ 1 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Convert a specific column in a DataFrame to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - -let df = new dfd.DataFrame(data) -df.print() - -let dum_df = dfd.get_dummies(df, { columns: ['fruits']}) -dum_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ fruits │ Count │ Country ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ pear │ 20 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ mango │ 30 │ NG ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ pawpaw │ 89 │ GH ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ mango │ 12 │ RU ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bean │ 30 │ RU ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //after dummification - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Count │ Country │ fruits_pear │ fruits_mango │ fruits_pawpaw │ fruits_bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 20 │ NG │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 30 │ NG │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 89 │ GH │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 12 │ RU │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 30 │ RU │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [LabelEncoder](danfo.labelencoder.md) and [OneHotEncoder](danfo.onehotencoder.md) -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.labelencoder.md b/api-reference-v1-stable/general-functions/danfo.labelencoder.md deleted file mode 100644 index b0745a8..0000000 --- a/api-reference-v1-stable/general-functions/danfo.labelencoder.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Encode target labels with value between 0 and n_classes-1. ---- - -# danfo.LabelEncoder - -class danfo.**LabelEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the LabelEncoder class for encoding Series and Arrays to integer between 0 and n\_classes -1. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to sklearn's [LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html?highlight=labelencoder#sklearn.preprocessing.LabelEncoder), and provides a fit and transform method. - -## **Examples** - -### **Label Encode values in a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = ["dog","cat","man","dog","cat","man","man","cat"] -let series = new dfd.Series(data) - -let encode = new dfd.LabelEncoder() - -encode.fit(series) -console.log(encode); - -let sf_enc = encode.transform(series.values) -sf_enc.print() - -let new_sf = encode.transform(["dog","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'dog', 'cat', 'man' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╟───┼──────────────────────╢ -║ 5 │ 2 ║ -╟───┼──────────────────────╢ -║ 6 │ 2 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with -1** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.LabelEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","man"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -LabelEncoder { label: [ 'pear', 'mango', 'pawpaw', 'bean' ] } -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [OneHotEncoder](danfo.onehotencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.merge.md b/api-reference-v1-stable/general-functions/danfo.merge.md deleted file mode 100644 index 0c4b760..0000000 --- a/api-reference-v1-stable/general-functions/danfo.merge.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -description: >- - Merge DataFrame or named Series objects with a database-style join.The join is - done on columns or indexes. ---- - -# danfo.merge - -danfo.**merge**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -| **kwargs** | Object |

{

left: A DataFrame or named Series object.

right: Another DataFrame or named Series object.

on: Column names to join on. Must be found in both the left and right DataFrame and/or Series objects.

how: One of 'left','right','outer', 'inner'. Defaults to 'inner'

}

| {**how**: inner} | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -**danfo.js** merge function is similar to Pandas merge and performs in-memory join operations idiomatically very similar to relational databases like SQL. - -danfo.js provides a single function, [`merge()`](danfo.merge.md), as the entry point for all standard database join operations between `DataFrame` or named `Series` objects. - -For a more intuitive understanding, this [guide](https://pandas.pydata.org/pandas-docs/stable/user\_guide/merging.html#brief-primer-on-merge-methods-relational-algebra) on the [Pandas](https://pandas.pydata.org/pandas-docs/stable) doc is worth reading. - -### **Merging by a single key found in both axis** - -By default, danfo performs _**inner**_ join. An inner join requires each row in the two joined DataFrames to have matching column values. This is similar to the **intersection** of two sets. It returns a DataFrame with only those rows that have common characteristics. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ "left": df1, "right": df2, "on": ["Key1"]}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - //first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on column 'Key1' - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -### **Inner Join/Merge by multiple keys found in both axis** - -Merging by two keys takes into consideration the keys appearing in both`left` and `right DataFrame.` - -{% tabs %} -{% tab title="Node" %} -```javascript - -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", 'Key2'], how: "inner"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //After inner join on two keys - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -The how parameter takes other types of joins like left, right and outer join and these are similar to their SQL equivalent - -### Outer join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1"], how: "outer"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//First DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //Second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//After outer join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ Key2_1 │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Left join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "left"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - After left join -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 │ NaN │ NaN ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ K2 │ K2 │ A3 │ B3 │ NaN │ NaN ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Right join/merge on DataFrame - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data = [['K0', 'k0', 'A0', 'B0'], ['k0', 'K1', 'A1', 'B1'], - ['K1', 'K0', 'A2', 'B2'], ['K2', 'K2', 'A3', 'B3']] - -let data2 = [['K0', 'k0', 'C0', 'D0'], ['K1', 'K0', 'C1', 'D1'], - ['K1', 'K0', 'C2', 'D2'], ['K2', 'K0', 'C3', 'D3']] - -let colum1 = ['Key1', 'Key2', 'A', 'B'] -let colum2 = ['Key1', 'Key2', 'A', 'D'] - -let df1 = new dfd.DataFrame(data, { columns: colum1 }) -let df2 = new dfd.DataFrame(data2, { columns: colum2 }) -df1.print() -df2.print() - -let merge_df = dfd.merge({ left: df1, right: df2, - on: ["Key1", "Key2"], how: "right"}) -merge_df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -//first DataFrame -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ k0 │ K1 │ A1 │ B1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K2 │ A3 │ B3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - //second DataFrame - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - -//after right join - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ Key1 │ Key2 │ A │ B │ A_1 │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ K0 │ k0 │ A0 │ B0 │ C0 │ D0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ K1 │ K0 │ A2 │ B2 │ C1 │ D1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ K1 │ K0 │ A2 │ B2 │ C2 │ D2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ K2 │ K0 │ NaN │ NaN │ C3 │ D3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -See also [danfo.concat ](danfo.concat.md)for joining objects based on axis. -{% endhint %} diff --git a/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md b/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md deleted file mode 100644 index d58af8b..0000000 --- a/api-reference-v1-stable/general-functions/danfo.minmaxscaler.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -description: Transform features by scaling each feature to a range of max and min values. ---- - -# danfo.MinMaxScaler - -class danfo.**MinMaxScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the MinMaxScaler class for standardization of DataFrame and Series. This estimator scales and translates each feature individually such that it is in the given range on the training set, e.g. between zero and one. - -This transformation is often used as an alternative to zero mean, unit variance scaling like [Standardscaler](danfo.standardscaler.md). - -The API is similar to sklearn's [MinMaxScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html?highlight=minmaxscaler#sklearn.preprocessing.MinMaxScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize DataFrame Object using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 1 │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0.19191919267... │ 0.02902902849... │ 0.00950475223... │ 0.00333333341... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize Series Object Using MinMaxScaler - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.MinMaxScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 20, 10], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -let sf = df.iloc({columns: ["0"]}) - -scaler.fit(sf) - -let df_enc = scaler.transform(sf) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - - Shape: (3,1) - -╔═══╤═══════════════════╗ -║ │ 0 ║ -╟───┼───────────────────╢ -║ 0 │ 1 ║ -╟───┼───────────────────╢ -║ 1 │ 0.19191919267... ║ -╟───┼───────────────────╢ -║ 2 │ 0 ║ -╚═══╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.onehotencoder.md b/api-reference-v1-stable/general-functions/danfo.onehotencoder.md deleted file mode 100644 index 81c913d..0000000 --- a/api-reference-v1-stable/general-functions/danfo.onehotencoder.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -description: Encode categorical features as a one-hot numeric array. ---- - -# danfo.OneHotEncoder - -class danfo.**OneHotEncoder** \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/preprocessing/encodings.js#L6)] - -danfo.js provides the OneHotEncoder class for encoding values in Series and Arrays to one-hot numeric arrays. This is mostly used as a preprocessing step before most machine learning tasks. - -The API is similar to scikit-learn's [OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html?highlight=onehotencoder#sklearn.preprocessing.OneHotEncoder), and provides a fit and transform method. - -## **Examples** - -### **Convert Series to Dummy codes** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"], - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","bean"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -**Labels not found in the original data used for fitting are represented with 0s all through** -{% endhint %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { fruits: ['pear', 'mango', "pawpaw", "mango", "bean"] , - Count: [20, 30, 89, 12, 30], - Country: ["NG", "NG", "GH", "RU", "RU"]} - - -let df = new dfd.DataFrame(data) -let encode = new dfd.OneHotEncoder() - -encode.fit(df['fruits']) -console.log(encode); - -let sf_enc = encode.transform(df['fruits'].values) -sf_enc.print() - -let new_sf = encode.transform(["mango","woman", "cup"]) -new_sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 1 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ 0 │ 0 │ 0 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ pear │ mango │ pawpaw │ bean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 0 │ 1 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 0 │ 0 │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 0 │ 0 │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -``` -{% endtab %} -{% endtabs %} - -See also [LabelEncoder](danfo.labelencoder.md) and[ danfo.get\_dummies](danfo.get\_dummies.md) diff --git a/api-reference-v1-stable/general-functions/danfo.standardscaler.md b/api-reference-v1-stable/general-functions/danfo.standardscaler.md deleted file mode 100644 index 89ce861..0000000 --- a/api-reference-v1-stable/general-functions/danfo.standardscaler.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: Standardize features by removing the mean and scaling to unit variance. ---- - -# danfo.StandardScaler - -class danfo.**StandScaler** \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -danfo.js provides the StandardScaler class for the standardization of DataFrame and Series. The standard score of a sample `x` is calculated as: - -> z = (x - u) / s - -where `u` is the mean of the training samples or zero if `with_mean=False`, and `s` is the standard deviation of the training samples or one if `with_std=False`. - -The API is similar to sklearn's [StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html?highlight=standardscaler#sklearn.preprocessing.StandardScaler), and provides a fit and transform method. - -## **Examples** - -### Standardize Series Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let scaler = new dfd.StandardScaler() - -let sf = new dfd.Series([100,1000,2000, 3000]) -sf.print() - -scaler.fit(sf) - -let sf_enc = scaler.transform(sf) -sf_enc.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 100 ║ -╟───┼──────────────────────╢ -║ 1 │ 1000 ║ -╟───┼──────────────────────╢ -║ 2 │ 2000 ║ -╟───┼──────────────────────╢ -║ 3 │ 3000 ║ -╚═══╧══════════════════════╝ - -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1.1375757455825806 ║ -╟───┼──────────────────────╢ -║ 1 │ -0.4191068708896637 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.37919193506240845 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.1774907112121582 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Standardize DataFrame Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let scaler = new dfd.StandardScaler() - -let data = [[100,1000,2000, 3000] , - [20, 30, 89, 12], - [1, 1, 1, 0]] - -let df = new dfd.DataFrame(data) -df.print() - -scaler.fit(df) - -let df_enc = scaler.transform(df) -df_enc.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 100 │ 1000 │ 2000 │ 3000 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 20 │ 30 │ 20 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 1 │ 1 │ 1 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ 0 │ 1 │ 2 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -0.4185734987... │ 0.48862975835... │ 1.49663341045... │ 2.50463700294... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ -0.4992137849... │ -0.4891337454319 │ -0.4992137849... │ -0.5092938542... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -0.5183658599... │ -0.5183658599... │ -0.5183658599... │ -0.5193738341... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -See also [MinMaxScaler](danfo.minmaxscaler.md) diff --git a/api-reference-v1-stable/general-functions/danfo.to_datetime.md b/api-reference-v1-stable/general-functions/danfo.to_datetime.md deleted file mode 100644 index 7012100..0000000 --- a/api-reference-v1-stable/general-functions/danfo.to_datetime.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -description: Converts an array of Date time string to Date object. ---- - -# danfo.toDateTime - -danfo.**toDateTime**(data) \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | -| **data** | Array, Series |

data: Array | Series with Date strings to convert to Date time.

| | - -**Returns:** - - **** return **DataFrame** - -## **Examples** - -Converts a **Series** of Date strings to Date time and get time properties - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = new dfd.date_range({"start":'1/1/2018',period:12, freq:'M'}) -let sf = new dfd.Series(data) -sf.print() - -let dt = dfd.toDateTime(data) - -dt.month().print() -dt.month_name().print() -dt.weekdays().print() -dt.day().print() -dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - 0 -0 1/1/2018, 12:00:00 AM -1 2/1/2018, 12:00:00 AM -2 3/1/2018, 12:00:00 AM -3 4/1/2018, 12:00:00 AM -4 5/1/2018, 12:00:00 AM -5 6/1/2018, 12:00:00 AM -6 7/1/2018, 12:00:00 AM -7 8/1/2018, 12:00:00 AM -8 9/1/2018, 12:00:00 AM -9 10/1/2018, 12:00:00 AM -10 11/1/2018, 12:00:00 AM -11 12/1/2018, 12:00:00 AM - -//Int representation for month - 0 -0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 - -//string representation for month -0 -0 Jan -1 Feb -2 Mar -3 Apr -4 May -5 Jun -6 Jul -7 Aug -8 Sep -9 Oct -10 Nov -11 Dec - -//string representation for day of the week -0 -0 Mon -1 Thur -2 Thur -3 Sun -4 Tue -5 Fri -6 Sun -7 Wed -8 Sat -9 Mon -10 Thur -11 Sat - -0 -0 1 -1 4 -2 4 -3 0 -4 2 -5 5 -6 0 -7 3 -8 6 -9 1 -10 4 -11 6 - -//Hour of the day -0 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 -10 0 -11 0 - -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Date time properties of Series or datetime-like columns in DataFrame can be accessed via accessors in the **dt** name-space. See [Accessors](https://app.gitbook.com/@jsdata/s/danfojs/\~/drafts/-MEMaWwva1cjt8CxnG-b/api-reference/series#accessors) -{% endhint %} diff --git a/api-reference-v1-stable/groupby.md b/api-reference-v1-stable/groupby.md deleted file mode 100644 index 1db2e52..0000000 --- a/api-reference-v1-stable/groupby.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -description: >- - GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby(), - danfo.Series.groupby() ---- - -# Groupby - -### Indexing, iteration - -| [`GroupBy.__iter__`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.__iter__.html#pandas.core.groupby.GroupBy.__iter__)\(\) | Groupby iterator. | -| :--- | :--- | -| [`GroupBy.groups`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups) | Dict {group name -> group labels}. | -| [`GroupBy.indices`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.indices.html#pandas.core.groupby.GroupBy.indices) | Dict {group name -> group indices}. | -| [`GroupBy.get_group`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.get_group.html#pandas.core.groupby.GroupBy.get_group)\(name\[, obj\]\) | Construct DataFrame from group with provided name. | - -| [`Grouper`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Grouper.html#pandas.Grouper)\(\*args, \*\*kwargs\) | A Grouper allows the user to specify a groupby instruction for an object. | -| :--- | :--- | - - -### Function application - -| [`GroupBy.apply`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.apply.html#pandas.core.groupby.GroupBy.apply)\(func, \*args, \*\*kwargs\) | Apply function func group-wise and combine the results together. | -| :--- | :--- | -| [`GroupBy.agg`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.agg.html#pandas.core.groupby.GroupBy.agg)\(func, \*args, \*\*kwargs\) | | -| [`SeriesGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.aggregate.html#pandas.core.groupby.SeriesGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`DataFrameGroupBy.aggregate`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html#pandas.core.groupby.DataFrameGroupBy.aggregate)\(\[func, engine, …\]\) | Aggregate using one or more operations over the specified axis. | -| [`SeriesGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.transform.html#pandas.core.groupby.SeriesGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed Series on each group and return a Series having the same indexes as the original object filled with the transformed values | -| [`DataFrameGroupBy.transform`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.transform.html#pandas.core.groupby.DataFrameGroupBy.transform)\(func, \*args\[, …\]\) | Call function producing a like-indexed DataFrame on each group and return a DataFrame having the same indexes as the original object filled with the transformed values | -| [`GroupBy.pipe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pipe.html#pandas.core.groupby.GroupBy.pipe)\(func, \*args, \*\*kwargs\) | Apply a function func with arguments to this GroupBy object and return the function’s result. | - -### Computations / descriptive stats - -| [`GroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.all.html#pandas.core.groupby.GroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`GroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.any.html#pandas.core.groupby.GroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`GroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.bfill.html#pandas.core.groupby.GroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.backfill.html#pandas.core.groupby.GroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`GroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.count.html#pandas.core.groupby.GroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`GroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumcount.html#pandas.core.groupby.GroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`GroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummax.html#pandas.core.groupby.GroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`GroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cummin.html#pandas.core.groupby.GroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`GroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumprod.html#pandas.core.groupby.GroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`GroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.cumsum.html#pandas.core.groupby.GroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`GroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ffill.html#pandas.core.groupby.GroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.first`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html#pandas.core.groupby.GroupBy.first)\(\[numeric\_only, min\_count\]\) | Compute first of group values. | -| [`GroupBy.head`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.head.html#pandas.core.groupby.GroupBy.head)\(\[n\]\) | Return first n rows of each group. | -| [`GroupBy.last`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html#pandas.core.groupby.GroupBy.last)\(\[numeric\_only, min\_count\]\) | Compute last of group values. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max)\(\[numeric\_only, min\_count\]\) | Compute max of group values. | -| [`GroupBy.mean`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.mean.html#pandas.core.groupby.GroupBy.mean)\(\[numeric\_only\]\) | Compute mean of groups, excluding missing values. | -| [`GroupBy.median`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.median.html#pandas.core.groupby.GroupBy.median)\(\[numeric\_only\]\) | Compute median of groups, excluding missing values. | -| [`GroupBy.min`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.min.html#pandas.core.groupby.GroupBy.min)\(\[numeric\_only, min\_count\]\) | Compute min of group values. | -| [`GroupBy.ngroup`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ngroup.html#pandas.core.groupby.GroupBy.ngroup)\(\[ascending\]\) | Number each group from 0 to the number of groups - 1. | -| [`GroupBy.nth`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.nth.html#pandas.core.groupby.GroupBy.nth)\(n\[, dropna\]\) | Take the nth row from each group if n is an int, or a subset of rows if n is a list of ints. | -| [`GroupBy.ohlc`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.ohlc.html#pandas.core.groupby.GroupBy.ohlc)\(\) | Compute open, high, low and close values of a group, excluding missing values. | -| [`GroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pad.html#pandas.core.groupby.GroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`GroupBy.prod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.prod.html#pandas.core.groupby.GroupBy.prod)\(\[numeric\_only, min\_count\]\) | Compute prod of group values. | -| [`GroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html#pandas.core.groupby.GroupBy.rank)\(\[method, ascending, na\_option, …\]\) | Provide the rank of values within each group. | -| [`GroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.pct_change.html#pandas.core.groupby.GroupBy.pct_change)\(\[periods, fill\_method, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`GroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.size.html#pandas.core.groupby.GroupBy.size)\(\) | Compute group sizes. | -| [`GroupBy.sem`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sem.html#pandas.core.groupby.GroupBy.sem)\(\[ddof\]\) | Compute standard error of the mean of groups, excluding missing values. | -| [`GroupBy.std`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.std.html#pandas.core.groupby.GroupBy.std)\(\[ddof\]\) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum)\(\[numeric\_only, min\_count\]\) | Compute sum of group values. | -| [`GroupBy.var`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.var.html#pandas.core.groupby.GroupBy.var)\(\[ddof\]\) | Compute variance of groups, excluding missing values. | -| [`GroupBy.tail`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.tail.html#pandas.core.groupby.GroupBy.tail)\(\[n\]\) | Return last n rows of each group. | - -The following methods are available in both `SeriesGroupBy` and `DataFrameGroupBy` objects, but may differ slightly, usually in that the `DataFrameGroupBy` version usually permits the specification of an axis argument, and often an argument indicating whether to restrict application to columns of a specific data type. - -| [`DataFrameGroupBy.all`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.all.html#pandas.core.groupby.DataFrameGroupBy.all)\(\[skipna\]\) | Return True if all values in the group are truthful, else False. | -| :--- | :--- | -| [`DataFrameGroupBy.any`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.any.html#pandas.core.groupby.DataFrameGroupBy.any)\(\[skipna\]\) | Return True if any value in the group is truthful, else False. | -| [`DataFrameGroupBy.backfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.backfill.html#pandas.core.groupby.DataFrameGroupBy.backfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.bfill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.bfill.html#pandas.core.groupby.DataFrameGroupBy.bfill)\(\[limit\]\) | Backward fill the values. | -| [`DataFrameGroupBy.corr`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corr.html#pandas.core.groupby.DataFrameGroupBy.corr) | Compute pairwise correlation of columns, excluding NA/null values. | -| [`DataFrameGroupBy.count`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.count.html#pandas.core.groupby.DataFrameGroupBy.count)\(\) | Compute count of group, excluding missing values. | -| [`DataFrameGroupBy.cov`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cov.html#pandas.core.groupby.DataFrameGroupBy.cov) | Compute pairwise covariance of columns, excluding NA/null values. | -| [`DataFrameGroupBy.cumcount`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumcount.html#pandas.core.groupby.DataFrameGroupBy.cumcount)\(\[ascending\]\) | Number each item in each group from 0 to the length of that group - 1. | -| [`DataFrameGroupBy.cummax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummax.html#pandas.core.groupby.DataFrameGroupBy.cummax)\(\[axis\]\) | Cumulative max for each group. | -| [`DataFrameGroupBy.cummin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cummin.html#pandas.core.groupby.DataFrameGroupBy.cummin)\(\[axis\]\) | Cumulative min for each group. | -| [`DataFrameGroupBy.cumprod`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumprod.html#pandas.core.groupby.DataFrameGroupBy.cumprod)\(\[axis\]\) | Cumulative product for each group. | -| [`DataFrameGroupBy.cumsum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.cumsum.html#pandas.core.groupby.DataFrameGroupBy.cumsum)\(\[axis\]\) | Cumulative sum for each group. | -| [`DataFrameGroupBy.describe`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.describe.html#pandas.core.groupby.DataFrameGroupBy.describe)\(\*\*kwargs\) | Generate descriptive statistics. | -| [`DataFrameGroupBy.diff`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.diff.html#pandas.core.groupby.DataFrameGroupBy.diff) | First discrete difference of element. | -| [`DataFrameGroupBy.ffill`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.ffill.html#pandas.core.groupby.DataFrameGroupBy.ffill)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.fillna`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.fillna.html#pandas.core.groupby.DataFrameGroupBy.fillna) | Fill NA/NaN values using the specified method. | -| [`DataFrameGroupBy.filter`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.filter.html#pandas.core.groupby.DataFrameGroupBy.filter)\(func\[, dropna\]\) | Return a copy of a DataFrame excluding filtered elements. | -| [`DataFrameGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.hist.html#pandas.core.groupby.DataFrameGroupBy.hist) | Make a histogram of the DataFrame’s. | -| [`DataFrameGroupBy.idxmax`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmax.html#pandas.core.groupby.DataFrameGroupBy.idxmax) | Return index of first occurrence of maximum over requested axis. | -| [`DataFrameGroupBy.idxmin`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.idxmin.html#pandas.core.groupby.DataFrameGroupBy.idxmin) | Return index of first occurrence of minimum over requested axis. | -| [`DataFrameGroupBy.mad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.mad.html#pandas.core.groupby.DataFrameGroupBy.mad) | Return the mean absolute deviation of the values for the requested axis. | -| [`DataFrameGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.nunique.html#pandas.core.groupby.DataFrameGroupBy.nunique)\(\[dropna\]\) | Return DataFrame with counts of unique elements in each position. | -| [`DataFrameGroupBy.pad`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pad.html#pandas.core.groupby.DataFrameGroupBy.pad)\(\[limit\]\) | Forward fill the values. | -| [`DataFrameGroupBy.pct_change`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.pct_change.html#pandas.core.groupby.DataFrameGroupBy.pct_change)\(\[periods, …\]\) | Calculate pct\_change of each value to previous entry in group. | -| [`DataFrameGroupBy.plot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.plot.html#pandas.core.groupby.DataFrameGroupBy.plot) | Class implementing the .plot attribute for groupby objects. | -| [`DataFrameGroupBy.quantile`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.quantile.html#pandas.core.groupby.DataFrameGroupBy.quantile)\(\[q, interpolation\]\) | Return group values at the given quantile, a la numpy.percentile. | -| [`DataFrameGroupBy.rank`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.rank.html#pandas.core.groupby.DataFrameGroupBy.rank)\(\[method, ascending, …\]\) | Provide the rank of values within each group. | -| [`DataFrameGroupBy.resample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.resample.html#pandas.core.groupby.DataFrameGroupBy.resample)\(rule, \*args, \*\*kwargs\) | Provide resampling when using a TimeGrouper. | -| [`DataFrameGroupBy.sample`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.sample.html#pandas.core.groupby.DataFrameGroupBy.sample)\(\[n, frac, replace, …\]\) | Return a random sample of items from each group. | -| [`DataFrameGroupBy.shift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.shift.html#pandas.core.groupby.DataFrameGroupBy.shift)\(\[periods, freq, …\]\) | Shift each group by periods observations. | -| [`DataFrameGroupBy.size`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.size.html#pandas.core.groupby.DataFrameGroupBy.size)\(\) | Compute group sizes. | -| [`DataFrameGroupBy.skew`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.skew.html#pandas.core.groupby.DataFrameGroupBy.skew) | Return unbiased skew over requested axis. | -| [`DataFrameGroupBy.take`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.take.html#pandas.core.groupby.DataFrameGroupBy.take) | Return the elements in the given _positional_ indices along an axis. | -| [`DataFrameGroupBy.tshift`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.tshift.html#pandas.core.groupby.DataFrameGroupBy.tshift) | \(DEPRECATED\) Shift the time index, using the index’s frequency if available. | - -The following methods are available only for `SeriesGroupBy` objects. - -| [`SeriesGroupBy.hist`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.hist.html#pandas.core.groupby.SeriesGroupBy.hist) | Draw histogram of the input series using matplotlib. | -| :--- | :--- | -| [`SeriesGroupBy.nlargest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nlargest.html#pandas.core.groupby.SeriesGroupBy.nlargest) | Return the largest n elements. | -| [`SeriesGroupBy.nsmallest`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nsmallest.html#pandas.core.groupby.SeriesGroupBy.nsmallest) | Return the smallest n elements. | -| [`SeriesGroupBy.nunique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.nunique.html#pandas.core.groupby.SeriesGroupBy.nunique)\(\[dropna\]\) | Return number of unique elements in the group. | -| [`SeriesGroupBy.unique`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.unique.html#pandas.core.groupby.SeriesGroupBy.unique) | Return unique values of Series object. | -| [`SeriesGroupBy.value_counts`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.value_counts.html#pandas.core.groupby.SeriesGroupBy.value_counts)\(\[normalize, …\]\) | | -| [`SeriesGroupBy.is_monotonic_increasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_increasing) | Alias for is\_monotonic. | -| [`SeriesGroupBy.is_monotonic_decreasing`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing.html#pandas.core.groupby.SeriesGroupBy.is_monotonic_decreasing) | Return boolean if values in the object are monotonic\_decreasing. | - -The following methods are available only for `DataFrameGroupBy` objects. - -| [`DataFrameGroupBy.corrwith`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.corrwith.html#pandas.core.groupby.DataFrameGroupBy.corrwith) | Compute pairwise correlation. | -| :--- | :--- | -| [`DataFrameGroupBy.boxplot`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.boxplot.html#pandas.core.groupby.DataFrameGroupBy.boxplot)\(\[subplots, column, …\]\) | Make box plots from DataFrameGroupBy data. | - diff --git a/api-reference-v1-stable/groupby/README.md b/api-reference-v1-stable/groupby/README.md deleted file mode 100644 index 9a1db65..0000000 --- a/api-reference-v1-stable/groupby/README.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: 'GroupBy objects are returned by groupby calls: danfo.DataFrame.groupby()' ---- - -# Groupby - -### Indexing, iteration - -| | | -| :--- | :--- | -| [`GroupBy.get_group`](groupby.get_groups.md) | Construct DataFrame from group with provided name. | - -### Function application - -| | | -| :--- | :--- | -| [`GroupBy.agg`](groupby.agg.md) | Aggregate using one or more operations over the specified axis. | - -### Computations / descriptive stats - -| | | -| :--- | :--- | -| [`GroupBy.count`](groupby.count.md) | Compute count of group, excluding missing values. | -| [`GroupBy.cummax`](groupby.cummax.md) | Cumulative max for each group. | -| [`GroupBy.cummin`](groupby.cummin.md) | Cumulative min for each group. | -| [`GroupBy.cumprod`](groupby.cumprod.md) | Cumulative product for each group. | -| [`GroupBy.cumsum`](groupby.cumsum.md) | Cumulative sum for each group. | -| [`GroupBy.max`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.max.html#pandas.core.groupby.GroupBy.max) | Compute max of group values. | -| [`GroupBy.mean`](groupby.mean.md) | Compute mean of groups, excluding missing values. | -| [`GroupBy.min`](groupby.min.md) | Compute min of group values. | -| [`GroupBy.std`](groupby.std.md) | Compute standard deviation of groups, excluding missing values. | -| [`GroupBy.sum`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.sum.html#pandas.core.groupby.GroupBy.sum) | Compute sum of group values. | -| [`GroupBy.var`](groupby.var.md) | Compute variance of groups, excluding missing values. | - diff --git a/api-reference-v1-stable/groupby/groupby.agg.md b/api-reference-v1-stable/groupby/groupby.agg.md deleted file mode 100644 index fae8802..0000000 --- a/api-reference-v1-stable/groupby/groupby.agg.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -description: Obtain data aggregate per groups for each column ---- - -# Groupby.agg - -> danfo.Groupby.**agg**(kwargs) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L349)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | -| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | - -**Return:** DataFrame - -**Examples** - -Using mean and sum aggregate - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Mean and Sum aggregate on dataframe groupby two column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.agg({"C":"mean","D":"sum"}).print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/groupby/groupby.apply.md b/api-reference-v1-stable/groupby/groupby.apply.md deleted file mode 100644 index 2150a21..0000000 --- a/api-reference-v1-stable/groupby/groupby.apply.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -description: Apply custom aggregate function to grouped data ---- - -# Groupby.apply - -danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function \| function to be applied to grouped data | Undefined | | - -**Returns:** - - ****return **DataFrame** - -## **Examples** - -Using apply to create a custom function that subtract the minimum value of each grouped data from each of its values - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - 'A': ['foo', 'bar', 'foo', 'bar', - - 'foo', 'bar', 'foo', 'foo'], - - 'B': ['one', 'one', 'two', 'three', - - 'two', 'two', 'one', 'three'], - - 'C': [1, 3, 2, 4, 5, 2, 6, 7], - - 'D': [3, 2, 4, 1, 5, 6, 7, 8] - }; -let df = new dfd.DataFrame(data); -let group_df = df.groupby(["A", "B"]); - -const subMin = (x) => { - return x.sub(x.min()); -}; - -group_df.apply(subMin).print(); - -``` -{% endtab %} - -{% tab title="Browser" %} -``` - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_apply │ D_apply ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 5 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 3 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` -{% endtab %} -{% endtabs %} - -\*\*\*\* diff --git a/api-reference-v1-stable/groupby/groupby.col.md b/api-reference-v1-stable/groupby/groupby.col.md deleted file mode 100644 index 02e7cdd..0000000 --- a/api-reference-v1-stable/groupby/groupby.col.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -description: Obtain the column(s) per groups ---- - -# Groupby.col - -> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| col\_names | Array | List of column | | - -Returns: Groupby Data structure - -Note: This is similar to pandas `df.groupby(["column"])["col_names"]` - -**Examples** - -Obtain a column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]) - -//for more coumns -grp.col(["C","D"]) -``` -{% endtab %} -{% endtabs %} - -Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. - -```text -//it returns the groupby data structure -GroupBy { - key_col: [ 'A' ], - col_dict: { - foo: [ [Array], [Array], [Array], [Array], [Array] ], - bar: [ [Array], [Array], [Array] ] - }, - data: [ - [ 'foo', 'one', 1, 3 ], - [ 'bar', 'one', 3, 2 ], - [ 'foo', 'two', 2, 4 ], - [ 'bar', 'three', 4, 1 ], - [ 'foo', 'two', 5, 5 ], - [ 'bar', 'two', 2, 6 ], - [ 'foo', 'one', 6, 7 ], - [ 'foo', 'three', 7, 8 ] - ], - column_name: [ 'A', 'B', 'C', 'D' ], - data_tensors: { - foo: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - }, - bar: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - } - }, - group_col_name: [ 'C' ], - group_col: { foo: [ [Series] ], bar: [ [Series] ] } -} -``` - - - diff --git a/api-reference-v1-stable/groupby/groupby.count.md b/api-reference-v1-stable/groupby/groupby.count.md deleted file mode 100644 index 36733be..0000000 --- a/api-reference-v1-stable/groupby/groupby.count.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Count the occurrence of values in columns per groups ---- - -# Groupby.count - -> danfo.Groupby.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L249)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).count().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).count().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.cummax.md b/api-reference-v1-stable/groupby/groupby.cummax.md deleted file mode 100644 index 8231a61..0000000 --- a/api-reference-v1-stable/groupby/groupby.cummax.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative max per groups for each column ---- - -# Groupby.cummax - -> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative max of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 4 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummax │ D_cummax ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 4 │ 6 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 4 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 4 │ 6 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummax for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummax │ D_cummax ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cummin.md b/api-reference-v1-stable/groupby/groupby.cummin.md deleted file mode 100644 index 7fd9ed6..0000000 --- a/api-reference-v1-stable/groupby/groupby.cummin.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cummulative minimum per groups for each column ---- - -# Groupby.cummin - -> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative min of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 1 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cummin │ D_cummin ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 2 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 3 │ 1 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 2 │ 1 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cummin for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cummin │ D_cummin ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cumprod.md b/api-reference-v1-stable/groupby/groupby.cumprod.md deleted file mode 100644 index af46123..0000000 --- a/api-reference-v1-stable/groupby/groupby.cumprod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cumulative product per group for each column ---- - -# Groupby.cumprod - -> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative product of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 │ 420 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 │ 3360 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 24 │ 12 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 24 │ 12 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 21 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.cumsum.md b/api-reference-v1-stable/groupby/groupby.cumsum.md deleted file mode 100644 index 3b2b0e6..0000000 --- a/api-reference-v1-stable/groupby/groupby.cumsum.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -description: Obtain the cumulative sum per groups for each column ---- - -# Groupby.cumsum - -> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative sum of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 │ 19 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 │ 27 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 9 │ 9 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 9 │ 9 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.get_groups.md b/api-reference-v1-stable/groupby/groupby.get_groups.md deleted file mode 100644 index 0cdf912..0000000 --- a/api-reference-v1-stable/groupby/groupby.get_groups.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -description: Obtain the data for each element of the groupby column ---- - -# Groupby.get\_groups - -> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] - -| Parameters | Type | Description | default | -| :--- | :--- | :--- | :--- | -| key | Array | element of the groupby column | | - -**Returns**: DataFrame - -**Example** - -Group the dataframe by column A and obtain the group belonging to the values in column A - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) - -grp.get_groups(["foo"]).print() - -grp.get_groups(["bar"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get groups for key "foo" - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get groups for key "bar" - - Shape: (3,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ three │ 4 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) - -grp.get_groups(["foo","one"]).print() - -grp.get_groups(["bar","one"]).print() -``` -{% endtab %} -{% endtabs %} - -```text -//get_groups(["foo","one"] - - - Shape: (2,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - -//get_groups(["bar","one"]) - - - Shape: (1,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C │ D ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ bar │ one │ 3 │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference-v1-stable/groupby/groupby.max.md b/api-reference-v1-stable/groupby/groupby.max.md deleted file mode 100644 index 43470f6..0000000 --- a/api-reference-v1-stable/groupby/groupby.max.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -description: Obtain the maximum value of columns per groups ---- - -# Groupby.max - -> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] - -**Parameters:** None - -**Returns**: DataFrame - -**Example** - -Obtain the maximum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 4 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).max().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_max │ D_max ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 6 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` diff --git a/api-reference-v1-stable/groupby/groupby.mean.md b/api-reference-v1-stable/groupby/groupby.mean.md deleted file mode 100644 index add6958..0000000 --- a/api-reference-v1-stable/groupby/groupby.mean.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -description: Obtain the mean per groups for each column(s) ---- - -# Groupby.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the mean of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 5.40000009536... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 3 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the mean for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).mean().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_mean ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.min.md b/api-reference-v1-stable/groupby/groupby.min.md deleted file mode 100644 index 0151e64..0000000 --- a/api-reference-v1-stable/groupby/groupby.min.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -description: Obtain the minimum value per groups for a coumn(s) ---- - -# Groupby.min - -> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the minimum value for a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the minimum value for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 2 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the maximum value for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).min().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.std.md b/api-reference-v1-stable/groupby/groupby.std.md deleted file mode 100644 index c792a8e..0000000 --- a/api-reference-v1-stable/groupby/groupby.std.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the standard deviation per groups for specified columns ---- - -# Groupby.std - -> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the standard deviation of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 2.58843582110... │ 2.07364413533... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 2.64575131106... ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).std().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the std for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).std().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_std │ D_std ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.53553390593... │ 2.82842712474... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2.12132034355... │ 0.70710678118... ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.sum.md b/api-reference-v1-stable/groupby/groupby.sum.md deleted file mode 100644 index f6f2900..0000000 --- a/api-reference-v1-stable/groupby/groupby.sum.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -description: Obtain the sum per groups for columns ---- - -# Groupby.sum - -> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the sum of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 21 │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 9 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the sum for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).sum().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/groupby/groupby.var.md b/api-reference-v1-stable/groupby/groupby.var.md deleted file mode 100644 index 373109f..0000000 --- a/api-reference-v1-stable/groupby/groupby.var.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -description: Obtain the variance per groups for a specified column ---- - -# Groupby.var - -> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the variance of a column for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - - -let grp = df.groupby(["A"]) -grp.col(["C"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (2,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (2,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 6.7 │ 4.3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 1 │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).var().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the var for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).var().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_var │ D_var ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 12.5 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 4.5 │ 0.5 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference-v1-stable/input-output/README.md b/api-reference-v1-stable/input-output/README.md deleted file mode 100644 index e86d5de..0000000 --- a/api-reference-v1-stable/input-output/README.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Functions for reading tabular/structured data into DataFrame/Series Objects ---- - -# Input/Output - -## CSV - -| \`\` | | -| ----------------------------------- | -------------------------------------------------------- | -| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | -| [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | -| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | -| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | -| [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | - -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference-v1-stable/input-output/danfo.read_csv.md b/api-reference-v1-stable/input-output/danfo.read_csv.md deleted file mode 100644 index a291533..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_csv.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -description: >- - Reads a comma-separated values (CSV) file into DataFrame. Also supports the - reading of CSV files in chunks. ---- - -# danfo.read\_csv - -> danfo.**read\_csv**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)] - -| | | | | -| -------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**source**_ | File object, File path, URL |

Any valid string path is acceptable. The string could be a URL or a valid local file path.

A browser input file object is also supported.

| | -| **configs**: | object, optional | Supports all Papaparse config parameters. See [https://www.papaparse.com/docs#config](https://www.papaparse.com/docs#config). |

{

dynamicTyping: true,

header: true

}

| - -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_csv** method can read a CSV file from a local disk, or over the internet (URL). Reading of local files is only supported in Nodejs, while reading of input file objects is only supported in the browser. - -### **Reading files from local disk** - -By specifying a valid file path, you can load CSV files from local disk: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("./user_names.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading files from a URL** - -By specifying a valid URL, you can load CSV files from any location into Danfo\*\*'\*\*s data structure: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") //assumes file is in CWD - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - - Document - - - - -
- - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load CSV files in the browser in DataFrames/Series - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_excel.md b/api-reference-v1-stable/input-output/danfo.read_excel.md deleted file mode 100644 index 459aa30..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_excel.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -description: Reads an excel file into DataFrame. ---- - -# danfo.read_excel - -> danfo.**read_excel**(source, configs) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L89)] - -| Parameters | Type | Description | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| source | string | **source** : string, URL or local file path to retreive Excel file. | -| configs | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| - -> **Returns:** -> -> ** **return** **{**Promise**} DataFrame structure of parsed Excel data - -### Example - -The **read_excel** method can read excel files saved on a local disk, or over the internet. - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") -const path = require("path") - -let local_xcel = path.join(process.cwd(), "data", "testexcel.xlxs") - -async function load_process_data() { - let df = await dfd.read_excel(local_xcel) - df.head().print() -} - -load_process_data() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.read_json.md b/api-reference-v1-stable/input-output/danfo.read_json.md deleted file mode 100644 index 3c17457..0000000 --- a/api-reference-v1-stable/input-output/danfo.read_json.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -description: Reads a JSON file into DataFrame. ---- - -# danfo.read\_json - -> danfo.**read\_json**(source,) [\[source](https://github.com/opensource9ja/danfojs/blob/849d14c8e7fa79bce4ffa9d0d177639047313520/danfojs/src/io/reader.js#L47)] - -| | | | | -| -------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**source**_ | Input file object, string file\*\* \*\*path or URL |

Any valid string path is acceptable. The string could be a URL. Valid URL schemes include http, https, ftp, s3, gs, or a local path. Both relative and absolute paths are supported

An input file object is also supported in the browser.

| | -| options | Object |

Configuration options for reading JSON files. Supported options:

{
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

|

{
method: "GET"
}

| - -**Returns:** - -\*\* \*\*_**Promise**_. Resolves to DataFrame - -The **read\_json** method can read JSON files from a local disk, over the internet, or directly from input file objects. - -### **Reading JSON files from local disk** - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("./user_names.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} -{% endtabs %} - -### **Reading JSON files from a URL** - -By specifying a valid URL, you can load JSON files from any location: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -dfd.read_json("https://raw.githubusercontentdatasets/master/finance-charts-apple.json") - .then(df => { - - df.head().print() - - }).catch(err=>{ - console.log(err); - }) -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### **Reading an input file object in the browser** - -By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load a JSON file in the browser: - -{% tabs %} -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/input-output/danfo.to_csv.md b/api-reference-v1-stable/input-output/danfo.to_csv.md deleted file mode 100644 index c3403cf..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_csv.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -description: Writes a DataFrame or Series to CSV format. ---- - -# danfo.to\_csv - -> danfo.**to\_csv**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.csv.js#L106)] - -| | | | | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

}

|

{
download: true,
sep: ","

}

| - -The **to\_csv** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. - -### Convert DataFrame to CSV string and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const csv = dfd.to_csv(df, { download: false }); -console.log(csv); - -//output -Abs,Count,country code -20.2,34,NG -30,4,FR -47.3,5,GH -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and write to file path - -Writing a CSV file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { filePath: "testOut.csv"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to CSV string and download file in Client-side lib - -You can automatically convert and download a CSV file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -const dfd = require("danfojs") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_csv(df, { fileName: "testOut.csv", download: true}); -``` diff --git a/api-reference-v1-stable/input-output/danfo.to_excel.md b/api-reference-v1-stable/input-output/danfo.to_excel.md deleted file mode 100644 index 1fe1adf..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_excel.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Converts a DataFrame or Series to Excel file and write file to disk or - download in browser. ---- - -# danfo.to_excel - -> danfo.**to_excel**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.excel.js#L97)] - -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| - -The **to_excel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. - -### Convert DataFrame to Excel and write to file path - -Writing an Excel file to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { filePath: "testOut.xlsx"}); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame to Excel and download the file in Client-side lib - -You can automatically convert and download an Excel file in a browser environment, by specifying a `fileName`. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_excel(df, { fileName: "testOut.xlsx"}); -``` diff --git a/api-reference-v1-stable/input-output/danfo.to_json.md b/api-reference-v1-stable/input-output/danfo.to_json.md deleted file mode 100644 index baac615..0000000 --- a/api-reference-v1-stable/input-output/danfo.to_json.md +++ /dev/null @@ -1,124 +0,0 @@ -# danfo.to\_json - -> danfo.**to\_json**(data, options) [\[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/io/io.json.js#L92)] - -| | | | | -| -------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in browser environment.
format: The format of the JSON. Can be one of row or column.

}

|

{
format: "column"
}

| - -The **to\_json** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. - -### Convert DataFrame/Series to JSON and return value - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -const jsonObj = dfd.to_json(df, { download: false }); //column format -console.log(jsonObj); - -//output -[ - { Abs: 20.2, Count: 34, 'country code': 'NG' }, - { Abs: 30, Count: 4, 'country code': 'FR' }, - { Abs: 47.3, Count: 5, 'country code': 'GH' } -] - -//row format -const jsonObj = dfd.to_json(df, { - download: false, - format: "row" -}); - -console.log(jsonObj); -//output -{ - Abs: [ 20.2, 30, 47.3 ], - Count: [ 34, 4, 5 ], - 'country code': [ 'NG', 'FR', 'GH' ] -} -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and write to file path - -Writing a DataFrame/Series as JSON, to a local file path is only supported in the Nodejs environment - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { filePath: "./testOutput.json" }); -``` -{% endtab %} -{% endtabs %} - -### Convert DataFrame/Series to JSON and download file in browser - -You can automatically convert and download a DataFrame/Series as a JSON file in a browser environment, by specifying a `fileName` and setting `download` to **true**. - -```javascript -let data = { - Abs: [20.2, 30, 47.3], - Count: [34, 4, 5], - "country code": ["NG", "FR", "GH"], -}; - -let df = new dfd.DataFrame(data); - -dfd.to_json(df, { fileName: "test_out.json" }); -``` diff --git a/api-reference-v1-stable/input-output/read.md b/api-reference-v1-stable/input-output/read.md deleted file mode 100644 index c38778e..0000000 --- a/api-reference-v1-stable/input-output/read.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -description: >- - The generic read function loads a tabular data using the Frictionless - specification. ---- - -# read - -> danfo.**read**\(source, configs\) [\[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/io/reader.js#L21)\] - - - - - - - - - - - - - - - - - - - - - - - - -
Parameters - TypeDescriptionDefault
source - stringA path to the file/resources. It can be a local file, a URL to tabular - data (CSV, EXCEL) or Datahub.io Data Resource.
configs - object -

-

Configuration options. Supported params are:

-

data_num (Defaults => 0): The specific dataset to load, when - reading data from a datapackage.json,

-

header (Defaults => true): Whether the dataset contains a header - or not.

-

sheet (Defaults => 0): Number of the excel sheet which u want - to load.

-

}

-
- -**Returns:** - - ****_**Promise**_. Resolves to DataFrame - -The **read** function uses [frictionless.js](https://github.com/frictionlessdata/frictionless-js) underhood.[`frictionless.js`](https://github.com/frictionlessdata/frictionless-js) is a lightweight, standardized "stream-plus-metadata" interface for accessing files and datasets, especially tabular ones \(CSV, Excel\). It follows the [Frictionless spec](https://frictionlessdata.io/specs/) - -> ### **Note**: The `read` method is only available in danfojs-node at the moment. - -### Read a CSV file - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("file.csv") - let sample = await df.sample(10) - sample.print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### **Loading Files from URL** - -By specifying a valid URL, you can load CSV/EXCEL file: - -{% tabs %} -{% tab title="Node.js" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let df = await dfd.read("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") - df.head().print() -} - -load_data() -``` -{% endtab %} -{% endtabs %} - -### Loading Data from a Data Package Descriptor - -You can load data from a frictionless data package [descriptor](https://specs.frictionlessdata.io/data-package/#descriptor). A data package descriptor is a central file in a Data Package. It is a JSON file that provides: - -* General metadata such as the package’s title, license, publisher etc -* A list of the data “resources” that make up the package including their location on disk or online and other relevant information \(including, possibly, schema information about these data resources in a structured form\) - -For instance, in the example below, we load the first resource in the [Natural Gas dataset](https://datahub.io/core/natural-gas) from datahub.io. - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - const package_url = - "https://datahub.io/core/natural-gas/datapackage.json"; - - const df = await dfd.read(package_url, { data_num: 1 }); - df.head().print(); - -load_data() -``` -{% endtab %} -{% endtabs %} - -```bash -╔═══╤═══════════════════╤═══════════════════╗ -║ │ Date │ Price ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ 1997-01-07 │ 3.81999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ 1997-01-08 │ 3.79999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ 1997-01-09 │ 3.60999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ 1997-01-10 │ 3.91999999999... ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ 1997-01-13 │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - - - diff --git a/api-reference-v1-stable/plotting/README.md b/api-reference-v1-stable/plotting/README.md deleted file mode 100644 index 93161e3..0000000 --- a/api-reference-v1-stable/plotting/README.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: >- - DataFrame and Series have inbuilt support for plotting using Plotly's backend. - All customization can be done using Plotly's parameter passed to the config - object. ---- - -# Plotting - -* [Line Charts](line-charts.md) -* [Bar Charts](bar-charts.md) -* [Scatter Plots](scatter-plots.md) -* [Histograms](histograms.md) -* [Pie Charts](pie-charts.md) -* [Tables](tables.md) -* [Box Plots](box-plots.md) -* [Violin Plots](violin-plots.md) -* [Timeseries Plots](timeseries-plots.md) - diff --git a/api-reference-v1-stable/plotting/bar-charts.md b/api-reference-v1-stable/plotting/bar-charts.md deleted file mode 100644 index 6606bdc..0000000 --- a/api-reference-v1-stable/plotting/bar-charts.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Makes a vertical bar plot. ---- - -# Bar Charts - -A bar plot presents categorical data with rectangular bars with lengths proportional to the values that they represent. - -## Examples - -The **bar** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the bars drawn can be passed through the config parameter. - -### Bar plot on Series - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (6).png>) - -### Bar plot on DataFrame - -```markup - - - - - - - - - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (7).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/box-plots.md b/api-reference-v1-stable/plotting/box-plots.md deleted file mode 100644 index 2adb60a..0000000 --- a/api-reference-v1-stable/plotting/box-plots.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -description: Make a box plot from DataFrame columns. ---- - -# Box Plots - -Make a box-and-whisker plot from DataFrame columns, optionally grouped by some other columns. A box plot is a method for graphically depicting groups of numerical data through their quartiles. - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (23).png>) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (24).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/configuring-your-plots.md b/api-reference-v1-stable/plotting/configuring-your-plots.md deleted file mode 100644 index 4cedbb2..0000000 --- a/api-reference-v1-stable/plotting/configuring-your-plots.md +++ /dev/null @@ -1,68 +0,0 @@ -# Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example, in the line plot below, we define a layout for our plot and give it a name. - -For example in the following code, we show how to set some basic configuration as well as layout for a line plot. - -```markup - - - - - - - - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (32).png>) diff --git a/api-reference-v1-stable/plotting/histograms.md b/api-reference-v1-stable/plotting/histograms.md deleted file mode 100644 index adabd84..0000000 --- a/api-reference-v1-stable/plotting/histograms.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -description: Draw one histogram of the DataFrame’s columns, or single histogram for Series ---- - -# Histograms - -A histogram is a representation of the distribution of data. This function groups the values of all given Series in the DataFrame into bins - -## Examples - -### Histogram of a Column in a DataFrame - -In the example below, we use the titanic dataset, to show a close to a real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (10).png>) - -### Customized Histogram plots on DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (20).png>) - -### Configuring your plots - -danfo.js plotting uses [Plotly.js](https://plotly.com/javascript) as its backend for plotting. This means you have all the configuration, flexibility and interactiveness of Plotly. - -All [customization](https://plotly.com/javascript/line-charts/) on the plot can be passed as an object of key-value pairs to the config parameter. For example: - -```javascript -var layout = { - title: 'A sample plot', - xaxis: { - title: 'X', - }, - yaxis: { - title: 'Y', - } -} - -df.plot("div_tag").histogram({layout: layout}) -``` - -{% hint style="info" %} -For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) style doc. -{% endhint %} diff --git a/api-reference-v1-stable/plotting/line-charts.md b/api-reference-v1-stable/plotting/line-charts.md deleted file mode 100644 index 79fe4d3..0000000 --- a/api-reference-v1-stable/plotting/line-charts.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -description: >- - Plot Series or DataFrame as lines. This function is useful to plot lines using - DataFrame’s values as coordinates. ---- - -# Line Charts - -## Examples - -### Basic Line plot on Series - -The **line** plot is exposed by the .**plot()** function called on a Series or DataFrame. The **.plot()** method accepts an HTML Div id where it renders the plot, while configuration options for the lines drawn can be passed through the config parameter. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (4).png>) - -### Line plots on DataFrame - -The example below shows the plot of column values against a common x-axis (index) - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (2).png>) - -The example below shows how to plot two columns in a DataFrame against each other. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (3).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/pie-charts.md b/api-reference-v1-stable/plotting/pie-charts.md deleted file mode 100644 index 6dce73d..0000000 --- a/api-reference-v1-stable/plotting/pie-charts.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -description: Generate a pie plot. ---- - -# Pie Charts - -A pie plot is a proportional representation of the numerical data in a column - -## Examples - -### Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (12).png>) - -### Multiple Pie Chart from Columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (21).png>) - -### Configure Position of Pie Charts - -If you have more than one pie charts displayed, you can set the grid parameter, and also the position of each pie. For example, in the snippet below, we set our grid to 2 by 2 and also pass a set of row and column index position. Each row/column position index correspond to each pie. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (22).png>) - -{% hint style="info" %} -For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. -{% endhint %} diff --git a/api-reference-v1-stable/plotting/scatter-plots.md b/api-reference-v1-stable/plotting/scatter-plots.md deleted file mode 100644 index 77649d1..0000000 --- a/api-reference-v1-stable/plotting/scatter-plots.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -description: Create a scatter plot of columns in a DataFrame ---- - -# Scatter Plots - -The coordinates of each point are defined by two DataFrame columns and filled circles are used to represent each point. Scatter plot is useful for visualizing complex correlations between two variables. - -## Examples - -### Scatter Plots on Columns in a DataFrame - -In the example below, we use the titanic dataset, to show a close to real-world use case of danfo.js - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot-8- (1) (1).png>) - -### More Examples - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (19).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/tables.md b/api-reference-v1-stable/plotting/tables.md deleted file mode 100644 index c67f0e2..0000000 --- a/api-reference-v1-stable/plotting/tables.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Turn DataFrame/Series in D3.js-based tables ---- - -# Tables - -## Examples - -### Create Interactive Tables from DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) - -### Configure the header and cell of a table - -To configure the header and cell of a table, you can pass header/cell styles to the **header\_style** and **cell\_style** parameter. The [Plotly table](https://plotly.com/javascript/table/) doc shows numerous configuration options you can pass. - -```markup - - - - - - - - - Document - - - - -
- - - - - -``` - -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference-v1-stable/plotting/timeseries-plots.md b/api-reference-v1-stable/plotting/timeseries-plots.md deleted file mode 100644 index 7bbb089..0000000 --- a/api-reference-v1-stable/plotting/timeseries-plots.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Timeseries plot are based on date index ---- - -# Timeseries Plots - -## Examples - -In the example below, we plot the yearly trend of a financial dataset. First, we reset the index to the Date column. - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot-29- (2) (1).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/plotting/violin-plots.md b/api-reference-v1-stable/plotting/violin-plots.md deleted file mode 100644 index a3e6c11..0000000 --- a/api-reference-v1-stable/plotting/violin-plots.md +++ /dev/null @@ -1,112 +0,0 @@ -# Violin Plots - -Make a violin plot from DataFrame columns, optionally grouped by some other columns. A violin plot is a method for graphically depicting groups of numerical data through their quartiles. See also [Box Plot](box-plots.md) - -## Examples - -### Boxplot for a Series Object - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (25).png>) - -### Box plots on a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (26).png>) - -### Box plot for selected columns in a DataFrame - -```markup - - - - - - - - - Document - - - - -
- - - - -``` - -![](<../../.gitbook/assets/newplot (27).png>) - -{% hint style="info" %} -To set configuration for your plots, see the [Configuring your plot page](configuring-your-plots.md) -{% endhint %} diff --git a/api-reference-v1-stable/series/README.md b/api-reference-v1-stable/series/README.md deleted file mode 100644 index 421bc63..0000000 --- a/api-reference-v1-stable/series/README.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -description: One-dimensional ndarray with axis labels (including time series). ---- - -# Series - -> `Series`(data, {**columns:** \[ Array ], **dtypes:** \[ Array ], **index:** \[Array]}) \[[source](https://github.com/opensource9ja/danfojs/blob/3398c2f540c16ac95599a05b6f2db4eff8a258c9/danfojs/src/core/series.js#L28)] - -### Attributes - -| [`Series.index`](series.index.md) | The index (axis labels) of the Series. | -| --------------------------------- | ------------------------------------------- | - -| [`Series.tensor`](series.tensor.md) | The Tensorflow tensor of the data backing this Series or Index. | -| ----------------------------------- | ---------------------------------------------------------------- | -| [`Series.values`](series.values.md) | Return Series as ndarray or ndarray-like depending on the dtype. | -| [`Series.dtype`](series.dtype.md) | Return the dtype object of the underlying data. | -| [`Series.shape`](series.shape.md) | Return a tuple of the shape of the underlying data. | -| [`Series.ndim`](series.ndim.md) | Number of dimensions of the underlying data, by definition 1. | -| [`Series.size`](broken-reference) | Return the number of elements in the underlying data. | - -### Conversion - -| [`Series.astype`](../dataframe/dataframe.astype.md) | Cast a Series object to a specified dtype | -| --------------------------------------------------- | ---------------------------------------------- | -| [`Series.copy`](series.copy.md) | Make a copy of this object’s indices and data. | - -### Indexing, iteration - -| | | -| ------------------------------------------------------- | ------------------------------------------------------------------ | -| ``[`Series.loc`](../dataframe/danfo.dataframe.loc.md)`` | Access a group of rows and columns by label(s) or a boolean array. | -| [`Series.iloc`](series.iloc.md) | Purely integer-location based indexing for selection by position. | - -### Binary operator functions - -| [`Series.add`](series.add.md) | Return Addition of series and other, element-wise (binary operator add). | -| --------------------------------- | --------------------------------------------------------------------------------------- | -| [`Series.sub`](series.sub.md) | Return Subtraction of series and other, element-wise (binary operator sub). | -| [`Series.mul`](series.mul.md) | Return Multiplication of series and other, element-wise (binary operator mul). | -| [`Series.div`](series.div.md) | Return Floating division of series and other, element-wise (binary operator truediv). | -| [`Series.mod`](series.mod.md) | Return Modulo of series and other, element-wise (binary operator mod). | -| [`Series.pow`](series.pow.md) | Return Exponential power of series and other, element-wise (binary operator pow). | -| [`Series.round`](series.round.md) | Round each value in a Series to the given number of decimals. | -| [`Series.lt`](series.lt.md) | Return Less than of series and other, element-wise (binary operator lt). | -| [`Series.gt`](series.gt.md) | Return Greater than of series and other, element-wise (binary operator gt). | -| [`Series.le`](series.le.md) | Return Less than or equal to of series and other, element-wise (binary operator le). | -| [`Series.ge`](series.ge.md) | Return Greater than or equal to of series and other, element-wise (binary operator ge). | -| [`Series.ne`](series.ne.md) | Return Not equal to of series and other, element-wise (binary operator ne). | -| [`Series.eq`](series.eq.md) | Return Equal to of series and other, element-wise (binary operator eq). | -| [`Series.dot`](broken-reference) | Compute the dot product between the Series and the columns of other. | - -### Function application & GroupBy - -| [`Series.apply`](series.apply.md) | Invoke function on values of Series. | -| --------------------------------- | ------------------------------------------------------- | -| [`Series.map`](series.map.md) | Map values of Series according to input correspondence. | - -### Computations / descriptive stats - -| [`Series.abs`](series.abs.md) | Return a Series with absolute numeric value of each element. | -| ----------------------------------------------------------- | ---------------------------------------------------------------- | -| [`Series.corr`](broken-reference) | Compute correlation with other Series, excluding missing values. | -| [`Series.count`](series.count.md) | Return number of non-NaN observations in the Series. | -| [`Series.cummax`](../dataframe/danfo.dataframe.cummax.md) | Return cumulative maximum over a DataFrame or Series axis. | -| [`Series.cummin`](../dataframe/danfo.dataframe.cummin.md) | Return cumulative minimum over a DataFrame or Series axis. | -| [`Series.cumprod`](../dataframe/danfo.dataframe.cumprod.md) | Return cumulative product over a DataFrame or Series axis. | -| [`Series.cumsum`](../dataframe/danfo.dataframe.cumsum.md) | Return cumulative sum over a DataFrame or Series axis. | -| [`Series.describe`](series.describe.md) | Generate descriptive statistics. | -| [`Series.max`](series.max.md) | Return the maximum of the values for the requested axis. | -| [`Series.mean`](series.mean.md) | Return the mean of the values for the requested axis. | -| [`Series.median`](series.median.md) | Return the median of the values for the requested axis. | -| [`Series.min`](series.min.md) | Return the minimum of the values for the requested axis. | -| [`Series.mode`](series.mode.md) | Return the mode(s) of the dataset. | -| [`Series.std`](series.std.md) | Return sample standard deviation over requested axis. | -| [`Series.sum`](series.sum.md) | Return the sum of the values for the requested axis. | -| [`Series.var`](series.var.md) | Return unbiased variance over requested axis. | -| [`Series.unique`](series.unique.md) | Return unique values of Series object. | -| [`Series.nunique`](series.nunique.md) | Return number of unique elements in the object. | -| [`Series.value_counts`](series.value\_counts.md) | Return a Series containing counts of unique values. | - -### Reindexing / selection / label manipulation - -| | | -| ------------------------------------------------------ | -------------------------------------------------------- | -| [`Series.drop_duplicates`](series.drop\_duplicates.md) | Return Series with duplicate values removed. | -| [`Series.head`](series.head.md) | Return the first n rows. | -| [`Series.reset_index`](series.reset\_index.md) | Generate a new DataFrame or Series with the index reset. | -| [`Series.sample`](series.sample.md) | Return a random sample of items from an axis of object. | -| [`Series.tail`](series.tail.md) | Return the last n rows. | - -### Missing data handling - -| | | -| ------------------------------------- | ------------------------------------------------ | -| [`Series.dropna`](series.dropna.md) | Return a new Series with missing values removed. | -| [`Series.fillna`](series.fillna.md) | Fill NaN values using the specified method. | -| [`Series.isna`](series.isna.md) | Detect missing values. | -| [`Series.replace`](series.replace.md) | Replace values given in to\_replace with value. | - -### Reshaping, sorting - -| [`Series.argsort`](series.argsort.md) | Return the integer indices that would sort the Series values. | -| ---------------------------------------------- | ------------------------------------------------------------- | -| [`Series.argmin`](series.argmin.md) | Return int position of the smallest value in the Series. | -| [`Series.argmax`](series.argmax.md) | Return int position of the largest value in the Series. | -| [`Series.sort_values`](series.sort\_values.md) | Sort by the values. | - -### Accessors - -Danfo provides dtype-specific methods under various accessors. These are separate namespaces within [`Series`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html#pandas.Series) that only apply to specific data types. - -| Data Type | Accessor | -| --------- | -------- | -| Datetime | dt | -| String | str | - -#### Datetimelike properties - -`Series.dt` can be used to access the values of the series as datetime and return several properties. These can be accessed like `Series.dt.`. - -**Datetime methods** - -| | | -| -------------------------------------------------- | ------------------------------------------------------------------ | -| [`Series.dt.year`](series.dt.year.md) | The year of the datetime. | -| [`Series.dt.month`](series.dt.month.md) | The month as January=1, December=12. | -| [`Series.dt.day`](series.dt.day.md) | The day of the datetime. | -| [`Series.dt.hour`](series.dt.hour.md) | The hours of the datetime. | -| [`Series.dt.minute`](series.dt.minute.md) | The minutes of the datetime. | -| [`Series.dt.second`](series.dt.second.md) | The seconds of the datetime. | -| [`Series.dt.weekdays`](series.dt.weekdays.md) | The day of the week with Monday=0, Sunday=6. | -| [`Series.dt.month_name`](series.dt.month\_name.md) | Return the month names of the DateTimeIndex with specified locale. | - -#### String handling - -`Series.str` can be used to access the values of the series as strings and apply several methods to it. These can be accessed like `Series.str.`. - -| [`Series.str.capitalize`](series.str.capitalize.md) | Capitalize the first character of each string | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| [`Series.str.toUpperCase`](series.str.touppercase.md) | Converts all characters to uppercase. | -| [`Series.str.toLowerCase`](series.str.tolowercase.md) | Converts all characters to lowercase. | -| [`Series.str.charAt`](series.str.charat.md) | Returns the character at the specified index (position). | -| [`Series.str.concat`](series.str.concat.md) | Joins two or more strings/arrays. | -| [`Series.str.startsWith`](series.str.startswith.md) | Checks whether a string begins with specified characters. | -| [`Series.str.endsWith`](series.str.endswith.md) | Checks whether a string ends with specified characters | -| [`Series.str.includes`](series.str.includes.md) | Checks whether a string contains the specified string/characters. | -| [`Series.str.indexOf`](series.str.indexof.md) | Returns the position of the first found occurrence of a specified value in a string. | -| [`Series.str.lastIndexOf`](series.str.lastindexof.md) | Returns the position of the last found occurrence of a specified value in a string. | -| [`Series.str.repeat`](series.str.repeat.md) | Returns a new string with a specified number of copies of an existing string. | -| [`Series.str.search`](series.str.search.md) | Searches a string for a specified value, or regular expression, and returns the position of the match. | -| [`Series.str.slice`](series.str.slice.md) | Extracts a part of a string and returns a new string. | -| [`Series.str.split`](series.str.split.md) | Splits a string into an array of substrings. | -| [`Series.str.substr`](series.str.substr.md) | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character. | -| [`Series.str.substring`](series.str.substring.md) | Extracts the characters from a string, between two specified indices. | -| [`Series.str.len`](series.str.len.md) | Counts the number of characters in each string. | -| [`Series.str.trim`](series.str.trim.md) | Removes whitespace from both ends of a string. | -| [`Series.str.join`](series.str.join.md) | Joins strings to specified value. | -| [`Series.str.replace`](series.str.replace.md) | Replace each occurrence of pattern/regex in the Series/Index. | - -### Plotting - -`Series.plot` is both a callable method and a namespace attribute for specific plotting methods of the form `Series.plot.`. - -| | | -| ----------------------------------------------------- | ------------------------------------------------------------- | -| [`Series.plot.bar`](../plotting/bar-charts.md) | Vertical bar plot. | -| [`Series.plot.box`](../plotting/box-plots.md) | Make a box plot of the DataFrame columns. | -| [`Series.plot.violin`](../plotting/box-plots.md) | Make a violin plot of the DataFrame columns. | -| [`Series.plot.hist`](../plotting/histograms.md) | Draw one histogram of the DataFrame’s columns. | -| [`Series.plot.scatter`](../plotting/scatter-plots.md) | Generate Kernel Density Estimate plot using Gaussian kernels. | -| [`Series.plot.line`](../plotting/line-charts.md) | Plot Series or DataFrame as lines. | -| [`Series.plot.pie`](../plotting/pie-charts.md) | Generate a pie plot. | -| [`Timeseries Plots`](../plotting/timeseries-plots.md) | Time series plots | -| [`Table`](../plotting/tables.md) | Display Series as Interactive table in Div | - -### Serialization / IO / conversion - -| | | -| ------------------------------------------------------ | ---------------------------------------------------- | -| [`Series.to_csv`](../dataframe/dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | -| [`Series.to_json`](../dataframe/dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference-v1-stable/series/creating-a-series.md b/api-reference-v1-stable/series/creating-a-series.md deleted file mode 100644 index 3c8e4ba..0000000 --- a/api-reference-v1-stable/series/creating-a-series.md +++ /dev/null @@ -1,210 +0,0 @@ -# Creating a Series - -new danfo.**Series**\(data, options\) - - - - - - - - - - - - - - - - - - - - - -
ParametersTypeDescription
data1D Array, 1D Tensor, JSON object.Flat data structure to load into DataFrame
optionsObject -

Optional configuration object. Supported properties are: -
-

-

index: Array of numeric or string names for subseting array. If - not specified, indexes are auto-generated. -
-

-

dtypes: Array of data types for each the column. If not specified, - dtypes are/is inferred. -
-

-

config: General configuration object for extending or setting NDframe - behavior. See full options here

-
- -In order to create a Series, you need to call the new Keyword and pass a flat data structure. In the following examples, we show you how to create a Series by specifying different config options. - -### Creating a Series from an object: - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = { 'B': ["bval1", "bval2", "bval3", "bval4"] } -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```javascript -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series from an array - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -obj_data = ["bval1", "bval2", "bval3", "bval4"] -df = new dfd.Series(obj_data) -df.print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══════╗ -║ 0 │ bval1 ║ -╟───┼───────╢ -║ 1 │ bval2 ║ -╟───┼───────╢ -║ 2 │ bval3 ║ -╟───┼───────╢ -║ 3 │ bval4 ║ -╚═══╧═══════╝ -``` - -### Creating a Series and specifying index and dtypes - -You can create a Series and specify options like index, dtypes, as well as configuration options for display, and memory mode etc. - -> Note: Specifing dtypes, and index on Series creation makes the process slightly faster. - -{% tabs %} -{% tab title="Node" %} -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2, 3, 4, 5]; -let index = ["a", "b", "c", "d", "e"]; -let dtypes = ["int32",] - -let df = new Series(data1, { index, dtypes }); -df.print() -``` -{% endtab %} -{% endtabs %} - -```text -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╚═══╧═══╝ -``` - -### Creating a Series and specifying memory mode - -To use less space on Series creation, you can set the low memory mode as demonstrated below: - -```javascript -import { Series } from "danfojs" - -let data1 = [1, 2.3, 3, 4, 5, "girl"]; - -let df = new Series(data1, { - config: { lowMemoryMode: true } -}); -df.print() -``` - -{% hint style="info" %} -**Note**: In low memory mode, less space is used by the Series. -{% endhint %} - diff --git a/api-reference-v1-stable/series/danfo.series.add.md b/api-reference-v1-stable/series/danfo.series.add.md deleted file mode 100644 index 7cd6150..0000000 --- a/api-reference-v1-stable/series/danfo.series.add.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: 'Return Addition of series and other, element-wise (binary operator add).' ---- - -# danfo.Series.add - -Return Addition of series and other, element-wise \(binary operator add\). - - **parameter:** {other} Series or Number to add - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 6] -let data2 = [30, 40, 39, 1, 2, 1] -let sf = new Series(data) -let sf2 = new Series(data2) -sf.add(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.apply.md b/api-reference-v1-stable/series/danfo.series.apply.md deleted file mode 100644 index d59a99c..0000000 --- a/api-reference-v1-stable/series/danfo.series.apply.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -description: invoke a function on Series Value ---- - -# danfo.Series.apply - -> danfo.series.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function | Function \(can be anonymous\) to apply | | - -**Returns:** - - ****return **Series** - -\*\*\*\* - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` - -**OUTPUT:** - -![](../../.gitbook/assets/series_apply1.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_apply2.png) - - - diff --git a/api-reference-v1-stable/series/danfo.series.copy.md b/api-reference-v1-stable/series/danfo.series.copy.md deleted file mode 100644 index c610c04..0000000 --- a/api-reference-v1-stable/series/danfo.series.copy.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.copy - -Make a new copy of Series - - - -**parameter:** - - **return:** {Series} - -**Example** - -```javascript -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf_copy = sf.copy() - - -let sf = new Series([30.21091, 40.190901, 3.564, 5.0212]) -sf = sf.set_index({ "index": ["a", "b", "c", "d"] }) -sf_copy = sf.copy() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.count.md b/api-reference-v1-stable/series/danfo.series.count.md deleted file mode 100644 index 50a5789..0000000 --- a/api-reference-v1-stable/series/danfo.series.count.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.count - -Return number of non-NA/null observations in the Series. - -This is equivalent to the method numpy.sum - - **parameter:** - - **return:** {Number}, sum of values in Series - -**Example** - -```javascript -let data = ["boy", "gitl", "woman", NaN] -let sf = new Series(data) -sf.count() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.describe.md b/api-reference-v1-stable/series/danfo.series.describe.md deleted file mode 100644 index 184dbe9..0000000 --- a/api-reference-v1-stable/series/danfo.series.describe.md +++ /dev/null @@ -1,26 +0,0 @@ -# danfo.Series.describe - - - -Generate descriptive statistics. Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding NaN values - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three"] }) - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -df.reset_index() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.div.md b/api-reference-v1-stable/series/danfo.series.div.md deleted file mode 100644 index ae2731b..0000000 --- a/api-reference-v1-stable/series/danfo.series.div.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# danfo.Series.div - -Return division of series and other, element-wise \(binary operator div\). - -Equivalent to series / other - - **parameter:** {other} Series, Number to divide with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.div(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.head.md b/api-reference-v1-stable/series/danfo.series.head.md deleted file mode 100644 index 1bc9d5e..0000000 --- a/api-reference-v1-stable/series/danfo.series.head.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -description: This function returns the first n rows for the object based on position. ---- - -# danfo.Series.head - - - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let cols = ["A"] -let sf = new Series(data, { columns: cols }) -sf.head() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.map.md b/api-reference-v1-stable/series/danfo.series.map.md deleted file mode 100644 index 9d7cad4..0000000 --- a/api-reference-v1-stable/series/danfo.series.map.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: Map the value of a series to it representation ---- - -# danfo.Series.map - -> danfo.series.**map**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)\] - -| Parameter | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| callable | Function or Object | callable can either be a function or an object\({}\) | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map) - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map.png) - -```javascript -const dfd = require("danfojs") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_map1.png) - diff --git a/api-reference-v1-stable/series/danfo.series.max.md b/api-reference-v1-stable/series/danfo.series.max.md deleted file mode 100644 index cac4ba1..0000000 --- a/api-reference-v1-stable/series/danfo.series.max.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.max - diff --git a/api-reference-v1-stable/series/danfo.series.maximum.md b/api-reference-v1-stable/series/danfo.series.maximum.md deleted file mode 100644 index 9082120..0000000 --- a/api-reference-v1-stable/series/danfo.series.maximum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.maximum - -Return maximum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check maximum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.maximum(sf2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.mean.md b/api-reference-v1-stable/series/danfo.series.mean.md deleted file mode 100644 index 6ace487..0000000 --- a/api-reference-v1-stable/series/danfo.series.mean.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mean - diff --git a/api-reference-v1-stable/series/danfo.series.median.md b/api-reference-v1-stable/series/danfo.series.median.md deleted file mode 100644 index 077c0ec..0000000 --- a/api-reference-v1-stable/series/danfo.series.median.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.median - diff --git a/api-reference-v1-stable/series/danfo.series.min.md b/api-reference-v1-stable/series/danfo.series.min.md deleted file mode 100644 index 22f3589..0000000 --- a/api-reference-v1-stable/series/danfo.series.min.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.min - diff --git a/api-reference-v1-stable/series/danfo.series.minimum.md b/api-reference-v1-stable/series/danfo.series.minimum.md deleted file mode 100644 index 2a9d9c6..0000000 --- a/api-reference-v1-stable/series/danfo.series.minimum.md +++ /dev/null @@ -1,22 +0,0 @@ -# danfo.Series.minimum - - - -Return minimum of series and other, element-wise \(binary operator div\). - - - - **parameter:** {other} Series, Numbers to check minimum against - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.minimum(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.mod.md b/api-reference-v1-stable/series/danfo.series.mod.md deleted file mode 100644 index 577014d..0000000 --- a/api-reference-v1-stable/series/danfo.series.mod.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Modulo of series and other, element-wise (binary operator mod).' ---- - -# danfo.Series.mod - -Return Modulo of series and other, element-wise \(binary operator mod\). - -Equivalent to series % other - - **parameter:** {other} Series, Number - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mod(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.mode.md b/api-reference-v1-stable/series/danfo.series.mode.md deleted file mode 100644 index 8d86e6e..0000000 --- a/api-reference-v1-stable/series/danfo.series.mode.md +++ /dev/null @@ -1,2 +0,0 @@ -# danfo.Series.mode - diff --git a/api-reference-v1-stable/series/danfo.series.mul.md b/api-reference-v1-stable/series/danfo.series.mul.md deleted file mode 100644 index 6cdac92..0000000 --- a/api-reference-v1-stable/series/danfo.series.mul.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: 'Return Multiplication of series and other, element-wise (binary operator mul).' ---- - -# danfo.Series.mul - -Return Multiplication of series and other, element-wise \(binary operator mul\). - -Equivalent to series \* other, but with support to substitute a fill\_value for missing data in one of the inputs. - - **parameter:** {Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.mul(sf2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.pow.md b/api-reference-v1-stable/series/danfo.series.pow.md deleted file mode 100644 index 291a993..0000000 --- a/api-reference-v1-stable/series/danfo.series.pow.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# danfo.Series.pow - -Return Exponential power of series and other, element-wise \(binary operator pow\). - -Equivalent to series \*\* other - - **parameter:** {other} Series, Number to multiply with. - - **return:** Series - -**Example** - -```javascript -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.pow(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.reset_index.md b/api-reference-v1-stable/series/danfo.series.reset_index.md deleted file mode 100644 index 7a908a9..0000000 --- a/api-reference-v1-stable/series/danfo.series.reset_index.md +++ /dev/null @@ -1,31 +0,0 @@ -# danfo.Series.reset\_index - - - -Generate a new Series with the index reset. This is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to the default before another operation. - - - -**parameter:** {kwargs} {inplace: Modify the Series in place \(do not create a new object, drop: Just reset the index, without inserting it as a column in the new DataFrame.} - - **return:** {Series} - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -let df_reset = df_new.reset_index() -df_reset.print() - - -let data = [1,2,3,4,5,6] -let df = new Series(data) -df.set_index({ "index": ["one", "two", "three", "four", "five", "six"], "inplace": true }) -let df_new = df.reset_index() -df_new -``` - diff --git a/api-reference-v1-stable/series/danfo.series.round.md b/api-reference-v1-stable/series/danfo.series.round.md deleted file mode 100644 index 2bbacbb..0000000 --- a/api-reference-v1-stable/series/danfo.series.round.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.round - -Round each value in a Series to the given number of decimals. - - - - **parameter:** {dp} Number, Numbers of Decimal places to round to - - **return:** {Series} - -**Example** - -```javascript -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf = new Series(data1) -sf.round(1) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.sample.md b/api-reference-v1-stable/series/danfo.series.sample.md deleted file mode 100644 index fa8f326..0000000 --- a/api-reference-v1-stable/series/danfo.series.sample.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# danfo.Series.sample - -Gets \[num\] number of random rows in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.sample(2) -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.set_index.md b/api-reference-v1-stable/series/danfo.series.set_index.md deleted file mode 100644 index 5cb3d28..0000000 --- a/api-reference-v1-stable/series/danfo.series.set_index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# danfo.Series.set\_index - -> danfo.series.**set\_index\(**kwargs**\)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| kwargs | Object {} | The object contains the key **index** and assigned an array value of equal length to the Series. format {"index": \[Array\] } | | - -**Example** - -```javascript -const dfd = require("danfojs") - -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["one", "two", "three"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series.reset_index.png) - -```javascript -const dfd = require("danfojs") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let df = new dfd.Series(data) -let df_new = df.set_index({ "index": ["H", "L", "M","F","T"] }) -df_new.print() -``` - -**OUTPUT** - -![](../../.gitbook/assets/series_reset_index2.png) - diff --git a/api-reference-v1-stable/series/danfo.series.sort_values.md b/api-reference-v1-stable/series/danfo.series.sort_values.md deleted file mode 100644 index 0a0c4e7..0000000 --- a/api-reference-v1-stable/series/danfo.series.sort_values.md +++ /dev/null @@ -1,27 +0,0 @@ -# danfo.Series.sort\_values - - - -Sort a Series in ascending or descending order by some criterion. - - - - **parameter:** {kwargs} Object, {ascending \(Bool\): Whether to return sorted values in ascending order or not, inplace \(Bool\): Whether to perform sorting on the original Series or not} - - **return:** {Number} - -**Example** - -```javascript -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values() - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "inplace": true }) - - -let sf = new Series([20, 30, 1, 2, 4, 57, 89, 0, 4]) -sf.sort_values({ "ascending": false, "inplace": true }) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.std.md b/api-reference-v1-stable/series/danfo.series.std.md deleted file mode 100644 index 8f48ef2..0000000 --- a/api-reference-v1-stable/series/danfo.series.std.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.std - -Return sample standard deviation over requested axis. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.std() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.sub.md b/api-reference-v1-stable/series/danfo.series.sub.md deleted file mode 100644 index 8867c14..0000000 --- a/api-reference-v1-stable/series/danfo.series.sub.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -description: 'Return Subtraction of series and other, element-wise (binary operator sub).' ---- - -# danfo.Series.sub - -Returns the subtraction between a series and other, element-wise \(binary operator subtraction\). - -Equivalent to series - other - - **parameter:** {other} Series, Number to subtract - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 39, 1, 2, 1] -let data2 = [1, 2, 3, 4, 5, 6] -let sf1 = new Series(data1) -let sf2 = new Series(data2) -sf1.sub(sf2) -``` - diff --git a/api-reference-v1-stable/series/danfo.series.sum-1.md b/api-reference-v1-stable/series/danfo.series.sum-1.md deleted file mode 100644 index 6ec14cb..0000000 --- a/api-reference-v1-stable/series/danfo.series.sum-1.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# danfo.Series.sum - -Return the sum of the values for the requested axis. - -This is equivalent to the method numpy.sum. - - **parameter:** - - **return:** Series - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.sum() -``` - diff --git a/api-reference-v1-stable/series/danfo.series.tail.md b/api-reference-v1-stable/series/danfo.series.tail.md deleted file mode 100644 index e83307d..0000000 --- a/api-reference-v1-stable/series/danfo.series.tail.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# danfo.Series.tail - -Prints the first n values in a Series - - **parameter:** {rows} Number of rows to return - - **return:** Series - -**Example** - -```javascript -let data = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf = new Series(data) -sf.tail() -``` - - - diff --git a/api-reference-v1-stable/series/danfo.series.tostring.md b/api-reference-v1-stable/series/danfo.series.tostring.md deleted file mode 100644 index 5807850..0000000 --- a/api-reference-v1-stable/series/danfo.series.tostring.md +++ /dev/null @@ -1,18 +0,0 @@ -# danfo.Series.toString - - - -Prints the data in a Series as a grid of row and columns - - - -**parameter:** - - **return:** {frame} - -**Example** - -```javascript - -``` - diff --git a/api-reference-v1-stable/series/danfo.series.var.md b/api-reference-v1-stable/series/danfo.series.var.md deleted file mode 100644 index 822edc7..0000000 --- a/api-reference-v1-stable/series/danfo.series.var.md +++ /dev/null @@ -1,20 +0,0 @@ -# danfo.Series.var - - - -Return unbiased variance of Series. - - - - **parameter:** - - **return:** {Number} - -**Example** - -```javascript -let data1 = [30, 40, 3, 5] -let sf = new Series(data1) -sf.var() -``` - diff --git a/api-reference-v1-stable/series/series.abs.md b/api-reference-v1-stable/series/series.abs.md deleted file mode 100644 index 843dd5e..0000000 --- a/api-reference-v1-stable/series/series.abs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Returns the absolute value in a Series ---- - -# Series.abs - -> danfo.Series.**abs**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L793)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object | **inplace**: Boolean indicating whether to perform the operation in-place or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [-10, 45, 56, -25, 23, -20, 10] -let sf = new dfd.Series(data1) - -sf.abs().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 25 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 6 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.add.md b/api-reference-v1-stable/series/series.add.md deleted file mode 100644 index e55b1b8..0000000 --- a/api-reference-v1-stable/series/series.add.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Addition of series and other, element-wise (binary operator add). ---- - -# Series.add - -> danfo.Series.add(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L129)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.add(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 31 ║ -╟───┼──────────────────────╢ -║ 1 │ 42 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 9 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.add(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 3 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 5 ║ -╟───┼──────────────────────╢ -║ 3 │ 6 ║ -╟───┼──────────────────────╢ -║ 4 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.and.md b/api-reference-v1-stable/series/series.and.md deleted file mode 100644 index 85c22cb..0000000 --- a/api-reference-v1-stable/series/series.and.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical AND between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.and - -> danfo.Series.and\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical AND between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.and(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical AND between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.and(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ false ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ false ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.append.md b/api-reference-v1-stable/series/series.append.md deleted file mode 100644 index 53e8f03..0000000 --- a/api-reference-v1-stable/series/series.append.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -description: Add a new value or values to the end of a Series. ---- - -# Series.append - -danfo.Series.**append**(newValue, index, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1120)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | -| newValue | Array, Series | Object to append | | -| index | Array | The new index value(s) to append to the Series. Must contain the same number of values as `newValues` as they map `1 - 1`. | | -| options | Object |

{
inplace: Whether to perform operation in-place or not.

}

| false | - -**Returns:** - - **** return **Series** - -**** - -### **Append new Series to the end of a Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) - -new_sf = sf1.append(sf2, ["f5", "f6", "f7"]) -new_sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` -{% endtab %} -{% endtabs %} - -### **Append new Series to the end of a Series in-place** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sf2 = new dfd.Series(["a", "b", "c"]) -let newIndex = ["f5", "f6", "f7"] - -sf1.append(sf2, newIndex, { inplace: true }) -sf1.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ -``` - -### **Append an array to the end of Series** - -{% tabs %} -{% tab title="Node" %} -```javascript -let sf1 = new dfd.Series([1, 2, 3, 4], { index: ['f1', 'f2', 'f3', 'f4'] }) -let sfArr = ["a", "b", "c"] - -new_sf = sf1.append(sfArr, ["f5", "f6", "f7"]) -new_sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤═══╗ -║ f1 │ 1 ║ -╟────┼───╢ -║ f2 │ 2 ║ -╟────┼───╢ -║ f3 │ 3 ║ -╟────┼───╢ -║ f4 │ 4 ║ -╟────┼───╢ -║ f5 │ a ║ -╟────┼───╢ -║ f6 │ b ║ -╟────┼───╢ -║ f7 │ c ║ -╚════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.apply.md b/api-reference-v1-stable/series/series.apply.md deleted file mode 100644 index 7f7050e..0000000 --- a/api-reference-v1-stable/series/series.apply.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -description: Invoke a function on each value in a Series. ---- - -# Series.apply - -> danfo.series.**apply**(callable, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L718)] - -| Parameters | Type | Description | Default | -| ---------- | -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function | Function (can be anonymous) to apply | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** - - **** return **Series** - -**** - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -let apply_func = (x) => { - return x + x -} -sf.apply(apply_func).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╟───┼──────────────────────╢ -║ 5 │ 12 ║ -╟───┼──────────────────────╢ -║ 6 │ 14 ║ -╟───┼──────────────────────╢ -║ 7 │ 16 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4, 5, 6, 7, 8]) - -sf.apply(Math.log).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 0.6931471805599453 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.0986122886681096 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.3862943611198906 ║ -╟───┼──────────────────────╢ -║ 4 │ 1.6094379124341003 ║ -╟───┼──────────────────────╢ -║ 5 │ 1.791759469228055 ║ -╟───┼──────────────────────╢ -║ 6 │ 1.9459101490553132 ║ -╟───┼──────────────────────╢ -║ 7 │ 2.0794415416798357 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series(["Rice","Beans","Yam","Banana","Wheat"]) - -sf.apply((x)=>{ - return x.toLocaleLowerCase() -}).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ rice ║ -╟───┼──────────────────────╢ -║ 1 │ beans ║ -╟───┼──────────────────────╢ -║ 2 │ yam ║ -╟───┼──────────────────────╢ -║ 3 │ banana ║ -╟───┼──────────────────────╢ -║ 4 │ wheat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argmax.md b/api-reference-v1-stable/series/series.argmax.md deleted file mode 100644 index d7927d2..0000000 --- a/api-reference-v1-stable/series/series.argmax.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the largest value in the series ---- - -# Series.argmax - -> danfo.Series.argmax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L975)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmax() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -7 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argmin.md b/api-reference-v1-stable/series/series.argmin.md deleted file mode 100644 index dfc661f..0000000 --- a/api-reference-v1-stable/series/series.argmin.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Returns the int position of the smallest value in the series ---- - -# Series.argmin - -> danfo.Series.**argmin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L987)\] - -**Parameters**: None - -**Returns**: int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,30,20,40,50,70,90,200,10,20,12] -let sf = new dfd.Series(data) - -sf.argmin() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -0 -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.argsort.md b/api-reference-v1-stable/series/series.argsort.md deleted file mode 100644 index b4608a4..0000000 --- a/api-reference-v1-stable/series/series.argsort.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Return the integer indices that would sort the Series values ---- - -# Series.argsort - -> danfo.Series.**argsort**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L965\\)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------- | ----------------------------------------------------- | -| options | Object | **ascending**: How to sort the indices |

{
ascending: true

}

| - -**Returns:** Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [10, 45, 20, 10, 23, 20, 30, 11] -let sf = new dfd.Series(data) - -sf.argsort().print() //defaults to ascending order -sf.argsort({ ascending: false }).print() - -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 3 ║ -╟───┼──────────────────────╢ -║ 2 │ 7 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 4 ║ -╟───┼──────────────────────╢ -║ 6 │ 6 ║ -╟───┼──────────────────────╢ -║ 7 │ 1 ║ -╚═══╧══════════════════════╝ - -//sorted in descending order -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 6 ║ -╟───┼───╢ -║ 2 │ 4 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╟───┼───╢ -║ 6 │ 0 ║ -╟───┼───╢ -║ 7 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.astype.md b/api-reference-v1-stable/series/series.astype.md deleted file mode 100644 index 15a61ae..0000000 --- a/api-reference-v1-stable/series/series.astype.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.astype - diff --git a/api-reference-v1-stable/series/series.copy.md b/api-reference-v1-stable/series/series.copy.md deleted file mode 100644 index 9bbdb47..0000000 --- a/api-reference-v1-stable/series/series.copy.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Makes a deep copy of a Series ---- - -# Series.copy - -> danfo.Series.copy() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L569)] - -**parameter:** - -**Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.copy() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21091 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.190901 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.564 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.0212 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.corr.md b/api-reference-v1-stable/series/series.corr.md deleted file mode 100644 index ee3263f..0000000 --- a/api-reference-v1-stable/series/series.corr.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.corr - diff --git a/api-reference-v1-stable/series/series.count.md b/api-reference-v1-stable/series/series.count.md deleted file mode 100644 index 832c794..0000000 --- a/api-reference-v1-stable/series/series.count.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the total number of values in a series ---- - -# Series.count - -> danfo.Series.count() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L350)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.count()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -9 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.cummax.md b/api-reference-v1-stable/series/series.cummax.md deleted file mode 100644 index 8aded1a..0000000 --- a/api-reference-v1-stable/series/series.cummax.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns cumulative maximum over a series ---- - -# Series.cummax - -> danfo.Series.**cummax**(options)\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L730)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummax().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 3 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 56 ║ -╟───┼──────────────────────╢ -║ 5 │ 56 ║ -╟───┼──────────────────────╢ -║ 6 │ 56 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cummin.md b/api-reference-v1-stable/series/series.cummin.md deleted file mode 100644 index 736cee5..0000000 --- a/api-reference-v1-stable/series/series.cummin.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Returns the cumulative min of a Series ---- - -# Series.cummin - -> danfo.Series.**cummin**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L721)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 5, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cummin().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ 10 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 5 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumprod.md b/api-reference-v1-stable/series/series.cumprod.md deleted file mode 100644 index 84ec0e7..0000000 --- a/api-reference-v1-stable/series/series.cumprod.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Return the cumulative product of a series ---- - -# Series.cumprod - -> danfo.Series.**cumprod**()\[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L738)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumprod().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 450 ║ -╟───┼──────────────────────╢ -║ 2 │ 25200 ║ -╟───┼──────────────────────╢ -║ 3 │ 630000 ║ -╟───┼──────────────────────╢ -║ 4 │ 14490000 ║ -╟───┼──────────────────────╢ -║ 5 │ 289800000 ║ -╟───┼──────────────────────╢ -║ 6 │ 2898000000 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.cumsum.md b/api-reference-v1-stable/series/series.cumsum.md deleted file mode 100644 index 7b7a19a..0000000 --- a/api-reference-v1-stable/series/series.cumsum.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: Return a cumulative sum of a series ---- - -# Series.cumsum - -> danfo.Series.**cumsum**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L713)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.cumsum().print() -``` -{% endtab %} - -{% tab title="Browser" %} -```markup - - - - - - - - Document - - - - - - - - - -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 55 ║ -╟───┼──────────────────────╢ -║ 2 │ 111 ║ -╟───┼──────────────────────╢ -║ 3 │ 136 ║ -╟───┼──────────────────────╢ -║ 4 │ 159 ║ -╟───┼──────────────────────╢ -║ 5 │ 179 ║ -╟───┼──────────────────────╢ -║ 6 │ 189 ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference-v1-stable/series/series.describe.md b/api-reference-v1-stable/series/series.describe.md deleted file mode 100644 index ce52246..0000000 --- a/api-reference-v1-stable/series/series.describe.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -description: >- - Generate descriptive statistics. Descriptive statistics include those that - summarize the central tendency, dispersion and shape of a dataset’s - distribution, excluding NaN values ---- - -# Series.describe - -> danfo.Series.describe() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L583)] - -**Parameters:** No parameter - -**return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = [1,2,3,4,5,6] -let sf = new dfd.Series(data) -sf.describe().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔══════════╤══════════════════════╗ -║ │ 0 ║ -╟──────────┼──────────────────────╢ -║ count │ 6 ║ -╟──────────┼──────────────────────╢ -║ mean │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ std │ 1.8708286933869707 ║ -╟──────────┼──────────────────────╢ -║ min │ 1 ║ -╟──────────┼──────────────────────╢ -║ median │ 3.5 ║ -╟──────────┼──────────────────────╢ -║ max │ 6 ║ -╟──────────┼──────────────────────╢ -║ variance │ 3.5 ║ -╚══════════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.div.md b/api-reference-v1-stable/series/series.div.md deleted file mode 100644 index 656a796..0000000 --- a/api-reference-v1-stable/series/series.div.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Floating division of series and other, element-wise (binary operator - truediv). ---- - -# Series.div - -> danfo.Series.div(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L188)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -divide with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.div(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 20 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 1.25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### divide with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.div(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.5 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 1.5 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 2.5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dot.md b/api-reference-v1-stable/series/series.dot.md deleted file mode 100644 index 61a8bc2..0000000 --- a/api-reference-v1-stable/series/series.dot.md +++ /dev/null @@ -1,2 +0,0 @@ -# Series.dot - diff --git a/api-reference-v1-stable/series/series.drop_duplicates.md b/api-reference-v1-stable/series/series.drop_duplicates.md deleted file mode 100644 index 08edf09..0000000 --- a/api-reference-v1-stable/series/series.drop_duplicates.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -description: Remove duplicate rows ---- - -# Series.drop\_duplicates - -> danfo.Series.**drop\_duplicates**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L1007)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | -| options | Object |

keep: "first" | "last", which duplicate value to keep. Defaults to "first".
inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

|

{

inplace: false

}

| - -**Returns:** Series - -**Examples** - -### Drop duplicate by keeping the first occurrence of the duplicate value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates() - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop duplicate and keep only the last duplicated value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 10, 23, 20, 10, 10] -let sf = new dfd.Series(data1) -let sf_drop = sf.drop_duplicates({keep:"last"}) - -sf_drop.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 2 │ 56 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Remove duplicate value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = ["A", "A", "A", "B", "B", "C", "C", "D"] -let sf = new dfd.Series(data1) -sf.drop_duplicates({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ A ║ -╟───┼──────────────────────╢ -║ 3 │ B ║ -╟───┼──────────────────────╢ -║ 5 │ C ║ -╟───┼──────────────────────╢ -║ 7 │ D ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dropna.md b/api-reference-v1-stable/series/series.dropna.md deleted file mode 100644 index 2fab716..0000000 --- a/api-reference-v1-stable/series/series.dropna.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -description: Remove missing values from Series ---- - -# Series.dropna - -> danfo.Series.**dropna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L931)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ----------------------------------- | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{
inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Drop all nan value and then return New Series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.dropna() - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Drop nan values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, undefined, 10, 23, 20, undefined, 10] -let sf = new dfd.Series(data1) -sf.dropna({inplace:true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 45 ║ -╟───┼──────────────────────╢ -║ 3 │ 10 ║ -╟───┼──────────────────────╢ -║ 4 │ 23 ║ -╟───┼──────────────────────╢ -║ 5 │ 20 ║ -╟───┼──────────────────────╢ -║ 7 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.day.md b/api-reference-v1-stable/series/series.dt.day.md deleted file mode 100644 index 6461fa5..0000000 --- a/api-reference-v1-stable/series/series.dt.day.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the numerical representation of the week day. ---- - -# Series.dt.day - -> danfo.Series.dt.**day**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L216)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2018-01-08'}) -let sf = new dfd.Series(data) - -sf.dt.day().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═══╗ -║ 0 │ 6 ║ -╟───┼───╢ -║ 1 │ 0 ║ -╟───┼───╢ -║ 2 │ 1 ║ -╟───┼───╢ -║ 3 │ 2 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 4 ║ -╟───┼───╢ -║ 6 │ 5 ║ -╟───┼───╢ -║ 7 │ 6 ║ -╟───┼───╢ -║ 8 │ 0 ║ -╟───┼───╢ -║ 9 │ 1 ║ -╚═══╧═══╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.hour.md b/api-reference-v1-stable/series/series.dt.hour.md deleted file mode 100644 index 16369bb..0000000 --- a/api-reference-v1-stable/series/series.dt.hour.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the hours in a time series ---- - -# Series.dt.hour - -> danfo.Series.dt.**hour**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L205)] - -**Parameters:** None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"H"}) -let sf = new dfd.Series(data) -// print series -sf.print() -// print hour series -sf.dt.hours().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 2:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.minute.md b/api-reference-v1-stable/series/series.dt.minute.md deleted file mode 100644 index ea8bfee..0000000 --- a/api-reference-v1-stable/series/series.dt.minute.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the minutes in a Time Series ---- - -# Series.dt.minutes - -> danfo.Series.dt.**minutes**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L292)] - -**Parameters**: None - -**Returns:** Series (int Elements) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"m"}) -let sf = new dfd.Series(data) -//print the series -sf.print() -//print the minutes series -sf.dt.minutes().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:01:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:02:00 AM ║ -╚═══╧══════════════════════╝ - -//print the minutes series -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.month.md b/api-reference-v1-stable/series/series.dt.month.md deleted file mode 100644 index e21eeda..0000000 --- a/api-reference-v1-stable/series/series.dt.month.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: Obtain the month in a date time series ---- - -# Series.dt.month - -> danfo.Series.dt.**month**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L193)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-7-31', "end":'2016-12-08', freq:"M"}) -let sf = new dfd.Series(data) - -sf.dt.month().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 0 │ 6 ║ -╟───┼────╢ -║ 1 │ 7 ║ -╟───┼────╢ -║ 2 │ 9 ║ -╟───┼────╢ -║ 3 │ 9 ║ -╟───┼────╢ -║ 4 │ 11 ║ -╟───┼────╢ -║ 5 │ 11 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.month_name.md b/api-reference-v1-stable/series/series.dt.month_name.md deleted file mode 100644 index 4e83618..0000000 --- a/api-reference-v1-stable/series/series.dt.month_name.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: obtain the month name in a Time Series ---- - -# Series.dt.month\_name - -> danfo.Series.dt.month\_name() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L241)] - -**Parameters**: None - -**Returns:** Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2018-01', freq:'M', period:3}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print month names -sf.dt.month_name().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 2/1/2018, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 3/1/2018, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═════╗ -║ 0 │ Jan ║ -╟───┼─────╢ -║ 1 │ Feb ║ -╟───┼─────╢ -║ 2 │ Mar ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.monthday.md b/api-reference-v1-stable/series/series.dt.monthday.md deleted file mode 100644 index b385f17..0000000 --- a/api-reference-v1-stable/series/series.dt.monthday.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the day of the month ---- - -# Series.dt.monthday - -> danfo.Series.dt.**monthday**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L268)] - -**Parameters:** None - -**Returns**: Series (Int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:4, freq:"D"}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print monthdays -sf.dt.monthday().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/2/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/3/2000, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.second.md b/api-reference-v1-stable/series/series.dt.second.md deleted file mode 100644 index 43330be..0000000 --- a/api-reference-v1-stable/series/series.dt.second.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Obtain the seconds in Date series ---- - -# Series.dt.seconds - -> danfo.Series.dt.**seconds**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L280)] - -**Parameters**: None - -**Returns:** Series (Int elements) - -**Example** - -Obtain the seconds of the datetime - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"s"}) -let sf = new dfd.Series(data) -//print the series frame -sf.print() - -//print the seconds obtained -sf.dt.seconds().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` - -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2000, 1:00:01 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2000, 1:00:02 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤═══╗ -║ 0 │ 0 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 2 ║ -╚═══╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.dt.weekdays.md b/api-reference-v1-stable/series/series.dt.weekdays.md deleted file mode 100644 index 04dbe18..0000000 --- a/api-reference-v1-stable/series/series.dt.weekdays.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -description: Obtain the days of the weeks ---- - -# Series.dt.weekdays - -> danfo.Series.dt.**weekdays**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L255)] - -**Parameters**: None - -**Returns:** Series (String elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":'2016-12-31', "end":'2017-01-08'}) -let sf = new dfd.Series(data) -//print series -sf.print() -//print days of the week -sf.dt.weekdays().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════════════════════════╗ -║ 0 │ 12/31/2016, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 1 │ 1/1/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 2 │ 1/2/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 3 │ 1/3/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 4 │ 1/4/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 5 │ 1/5/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 6 │ 1/6/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 7 │ 1/7/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 8 │ 1/8/2017, 1:00:00 AM ║ -╟───┼────────────────────────╢ -║ 9 │ 1/9/2017, 1:00:00 AM ║ -╚═══╧════════════════════════╝ - -╔═══╤══════╗ -║ 0 │ Sat ║ -╟───┼──────╢ -║ 1 │ Sun ║ -╟───┼──────╢ -║ 2 │ Mon ║ -╟───┼──────╢ -║ 3 │ Tue ║ -╟───┼──────╢ -║ 4 │ Wed ║ -╟───┼──────╢ -║ 5 │ Thur ║ -╟───┼──────╢ -║ 6 │ Fri ║ -╟───┼──────╢ -║ 7 │ Sat ║ -╟───┼──────╢ -║ 8 │ Sun ║ -╟───┼──────╢ -║ 9 │ Mon ║ -╚═══╧══════╝ -``` diff --git a/api-reference-v1-stable/series/series.dt.year.md b/api-reference-v1-stable/series/series.dt.year.md deleted file mode 100644 index ed1117f..0000000 --- a/api-reference-v1-stable/series/series.dt.year.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Obtain the year in a date time series ---- - -# Series.dt.year - -> danfo.Series.dt.**year**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/timeseries.js#L228)] - -**Parameters**: None - -**Returns:** Series (int elements) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = new dfd.date_range({"start":"2000-01-01", period:3, freq:"Y"}) -let sf = new dfd.Series(data) -sf.print() -sf.dt.year().print() -``` -{% endtab %} -{% endtabs %} - -``` -//print date time series -╔═══╤══════════════════════╗ -║ 0 │ 1/1/2000, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 1 │ 1/1/2001, 1:00:00 AM ║ -╟───┼──────────────────────╢ -║ 2 │ 1/1/2002, 1:00:00 AM ║ -╚═══╧══════════════════════╝ - -╔═══╤══════╗ -║ 0 │ 2000 ║ -╟───┼──────╢ -║ 1 │ 2001 ║ -╟───┼──────╢ -║ 2 │ 2002 ║ -╚═══╧══════╝ -``` diff --git a/api-reference-v1-stable/series/series.dtype.md b/api-reference-v1-stable/series/series.dtype.md deleted file mode 100644 index 75b4614..0000000 --- a/api-reference-v1-stable/series/series.dtype.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dtype of a series ---- - -# Series.dtype - -> danfo.Series.dtype \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L197)] - -**Parameters**: None - -**Returns:** String - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.dtype) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -float32 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.eq.md b/api-reference-v1-stable/series/series.eq.md deleted file mode 100644 index 43a3ece..0000000 --- a/api-reference-v1-stable/series/series.eq.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check all the values in a series is equal to another value ---- - -# Series.eq - -> danfo.Series.eq(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L894)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Examples** - -Compare all the values in a series to another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.eq(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check it all the values are equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.eq(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.fillna.md b/api-reference-v1-stable/series/series.fillna.md deleted file mode 100644 index a1db3a8..0000000 --- a/api-reference-v1-stable/series/series.fillna.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -description: Replace all NaN value with specified value ---- - -# Series.fillna - -> danfo.Series.**fillna**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L470)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

value: The value to replace all missing value with.

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

inplace: false

}

| - -**Examples** - -### Fill nan value and then return new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) - -let sf_rep = sf.fillna({ value: -999}) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Fill nan value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, 1, 2, 33, 4, NaN, 5, 6, 7, 8] -let sf = new dfd.Series(data1) -sf.fillna({ value: -999, inplace: true }) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -999 ║ -╟───┼──────────────────────╢ -║ 1 │ 1 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 33 ║ -╟───┼──────────────────────╢ -║ 4 │ 4 ║ -╟───┼──────────────────────╢ -║ 5 │ -999 ║ -╟───┼──────────────────────╢ -║ 6 │ 5 ║ -╟───┼──────────────────────╢ -║ 7 │ 6 ║ -╟───┼──────────────────────╢ -║ 8 │ 7 ║ -╟───┼──────────────────────╢ -║ 9 │ 8 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ge.md b/api-reference-v1-stable/series/series.ge.md deleted file mode 100644 index 0fb1aeb..0000000 --- a/api-reference-v1-stable/series/series.ge.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the values in a series is greater than or equal a value ---- - -# Series.ge - -> danfo.Series.ge(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L874)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns:** Series (Boolean element) - -**Example** - -Compare all the value in a Series to the values in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ge(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Check if all the value in a Series is greater than or equal a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ge(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.gt.md b/api-reference-v1-stable/series/series.gt.md deleted file mode 100644 index 184ca28..0000000 --- a/api-reference-v1-stable/series/series.gt.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all the value in a series is greater than a value ---- - -# Series.gt - -> danfo.Series.gt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L856)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are greater than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.gt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are greater than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.gt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.head.md b/api-reference-v1-stable/series/series.head.md deleted file mode 100644 index 2892263..0000000 --- a/api-reference-v1-stable/series/series.head.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Obtain the first n rows for the object based on position. ---- - -# Series.head - -> danfo.Series.head\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of first n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.head().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.iloc.md b/api-reference-v1-stable/series/series.iloc.md deleted file mode 100644 index ab7d1f3..0000000 --- a/api-reference-v1-stable/series/series.iloc.md +++ /dev/null @@ -1,158 +0,0 @@ -# Series.iloc - -danfo.Series.**iloc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** - -## **Examples** - -`.iloc()` is primarily integer position based (from `0` to `length-1` of the axis). - -Allowed inputs are: - -* An integer, e.g. `5`. -* A list or array of integers, e.g. `[4, 3, 0]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `"1:7"` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.iloc` will raise`IndexError` if a requested indexer is out-of-bounds. - -### **Indexing specific rows by index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc([0,5]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The [**iloc**](../dataframe/danfo.dataframe.iloc.md) function also accepts string slices of the form \[start: end], e.g "\[0: 5]". This will return all values from index positions 0 to 4. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["0:5"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 12 ║ -╟───┼──────────────────────╢ -║ 1 │ 34 ║ -╟───┼──────────────────────╢ -║ 2 │ 2.2 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 30 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(["5:"]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 5 │ 30 ║ -╟───┼──────────────────────╢ -║ 6 │ 2.1 ║ -╟───┼──────────────────────╢ -║ 7 │ 7 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.iloc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.index.md b/api-reference-v1-stable/series/series.index.md deleted file mode 100644 index 1cc95da..0000000 --- a/api-reference-v1-stable/series/series.index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -description: Obtain the index of a Series ---- - -# Series.index - -> danfo.Series.index \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L234)\] - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.index) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 0, 1, 2, 3 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.isna.md b/api-reference-v1-stable/series/series.isna.md deleted file mode 100644 index cdf6343..0000000 --- a/api-reference-v1-stable/series/series.isna.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: Detect Missing values ---- - -# Series.isna - -> danfo.Series.**isna**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L449)\] - -**Parameters**: None - -**Returns**: Series \(Boolean element\) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [NaN, undefined, "girl", "Man"] -let sf = new dfd.Series(data1) - -sf.isna().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.le.md b/api-reference-v1-stable/series/series.le.md deleted file mode 100644 index 44006e2..0000000 --- a/api-reference-v1-stable/series/series.le.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all the values in a series is less than or equal to a value ---- - -# Series.le - -> danfo.Series.le(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L865)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns:** Series (Boolean Element) - -**Example** - -Check if all the values in a series is less than or equal to a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.le(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ false ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than equal to values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.le(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ true ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.loc.md b/api-reference-v1-stable/series/series.loc.md deleted file mode 100644 index 13772ab..0000000 --- a/api-reference-v1-stable/series/series.loc.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -description: Access a group of rows by label(s) or a boolean array. ---- - -# Series.loc - -danfo.Series.**loc**() \[[source](https://github.com/opensource9ja/danfojs/blob/fe56860b0a303d218d60ba71dee6abf594401556/danfojs/src/core/frame.js#L254)] - -| Parameters | Type | Description | Default | -| ---------- | -------------- | ----------------------------------------------------------------------- | ------- | -| rows | Array, String | Array, string slice, index of row positions boolean mask to filter by. | | - -**Returns:** - - **** return **Series** - -## **Examples** - -`.loc()` is label position based (from `0` to `length-1` of the row axis). - -Allowed inputs are: - -* An integer, e.g. `"r1"`. -* A list or array of integers, e.g. `["a", "b", "d"]`. -* A boolean mask. E.g \[ true, false, false ] -* A string slice object with ints, e.g. `[`'`"a":"d"'], ["1:4"]` - -_**Note:** only **** the start label is included, and the end label is ignored._ - -`.loc` will raise a `ValueEror` if a requested label is not found. - -### **Indexing by specific row index** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc(["a", "g"]).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╟───┼─────╢ -║ e │ 30 ║ -╟───┼─────╢ -║ f │ 30 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╟───┼─────╢ -║ h │ 7 ║ -╚═══╧═════╝ - -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ g │ 2.1 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -### **Index by a slice of row** - -The **loc** function also accepts string slices of the form \[start: end], e.g **\[\`"a":"e"\`]**. This will return all values from label positions `a` to `e`. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -const index = ["a", "b", "c", "d", "e", "f", "g", "h"] -let s = new dfd.Series(data, { index }) -s.print() - -s.loc([`"a":"e"`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ a │ 12 ║ -╟───┼─────╢ -║ b │ 34 ║ -╟───┼─────╢ -║ c │ 2.2 ║ -╟───┼─────╢ -║ d │ 2 ║ -╚═══╧═════╝ -``` -{% endtab %} -{% endtabs %} - -{% hint style="info" %} -Note that when using loc. We expect you to pass labels in the correct format. That is, string labels must be explicitly quoted. For example, the following loc slice will throw an error:\ -`s.loc([a:e]).print()`\ -For the slice above to work, you must quote each slice, e.g:\ -`s.loc(["a":"e"]).print()`\ -\ -_**Inner quotes are not needed for numeric indices!**_ -{% endhint %} - -### By specifying a start index in a slice, all values after that index are returned. - -{% tabs %} -{% tab title="Node" %} -```javascript -const data = [12, 34, 2.2, 2, 30, 30, 2.1, 7] -let s = new dfd.Series(data) - -s.loc([`1:`]).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 1 │ 34 ║ -╟───┼─────╢ -║ 2 │ 2.2 ║ -╟───┼─────╢ -║ 3 │ 2 ║ -╟───┼─────╢ -║ 4 │ 30 ║ -╟───┼─────╢ -║ 5 │ 30 ║ -╟───┼─────╢ -║ 6 │ 2.1 ║ -╟───┼─────╢ -║ 7 │ 7 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Slice Series by boolean condition - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let s = new dfd.Series([12, 34, 2.2, 2, 30, 30, 2.1, 7]) -s.loc(s.gt(20)).print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤════╗ -║ 1 │ 34 ║ -╟───┼────╢ -║ 4 │ 30 ║ -╟───┼────╢ -║ 5 │ 30 ║ -╚═══╧════╝ -``` diff --git a/api-reference-v1-stable/series/series.lt.md b/api-reference-v1-stable/series/series.lt.md deleted file mode 100644 index 7af18bc..0000000 --- a/api-reference-v1-stable/series/series.lt.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -description: Check if all values in a Series are less than a value. ---- - -# Series.lt - -> danfo.Series.lt(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L847)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ------------------- | ------- | -| other | Series, Array or number | value(s) to compare | | - -**Returns**: Series (boolean element) - -**Example** - -Check if all the values in a series are less than a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.lt(20).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -check if all the values in a series are less than values in another series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.lt(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ false ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ false ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.map.md b/api-reference-v1-stable/series/series.map.md deleted file mode 100644 index 0e0850a..0000000 --- a/api-reference-v1-stable/series/series.map.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -description: Map the value of a series to a function or Object ---- - -# Series.map - -> danfo.series.**map**(callable) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L685)] - -| Parameter | Type | Description | Default | -| --------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| callable | Function or Object | A function or object({}) | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Example** - -Mapping the element in a Series words in an Object - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1, 2, 3, 4]) -let map = { 1: "ok", 2: "okie", 3: "frit", 4: "gop" } -sf.map(map).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ ok ║ -╟───┼──────────────────────╢ -║ 1 │ okie ║ -╟───┼──────────────────────╢ -║ 2 │ frit ║ -╟───┼──────────────────────╢ -║ 3 │ gop ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Mapping values in a Series to a representation using functions. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let sf = new dfd.Series([1,2,3,4]) - -sf.map((x)=>{ - return `I have ${x} cat(s)` -}).print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ I have 1 cat(s) ║ -╟───┼──────────────────────╢ -║ 1 │ I have 2 cat(s) ║ -╟───┼──────────────────────╢ -║ 2 │ I have 3 cat(s) ║ -╟───┼──────────────────────╢ -║ 3 │ I have 4 cat(s) ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.max.md b/api-reference-v1-stable/series/series.max.md deleted file mode 100644 index 4f7193a..0000000 --- a/api-reference-v1-stable/series/series.max.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the maximum value in a Series ---- - -# Series.max - -> danfo.Series.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L317)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.max()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -89 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.maximum.md b/api-reference-v1-stable/series/series.maximum.md deleted file mode 100644 index afc5a48..0000000 --- a/api-reference-v1-stable/series/series.maximum.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Obtain the maximum number between two series ---- - -# Series.maximum - -> danfo.Series.maximum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L363)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.maximum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 41 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 5 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.mean.md b/api-reference-v1-stable/series/series.mean.md deleted file mode 100644 index 17d97e6..0000000 --- a/api-reference-v1-stable/series/series.mean.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the mean of a series ---- - -# Series.mean - -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L253)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mean()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -23.000001907348633 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.median.md b/api-reference-v1-stable/series/series.median.md deleted file mode 100644 index d1cde75..0000000 --- a/api-reference-v1-stable/series/series.median.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the median of a series ---- - -# Series.median - -> danfo.Series.median() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L274)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.median()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -4 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.min.md b/api-reference-v1-stable/series/series.min.md deleted file mode 100644 index 6e11a67..0000000 --- a/api-reference-v1-stable/series/series.min.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the minimum value in a series ---- - -# Series.min - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.min()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -0 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.minimum.md b/api-reference-v1-stable/series/series.minimum.md deleted file mode 100644 index a06ba69..0000000 --- a/api-reference-v1-stable/series/series.minimum.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Obtain the minimum value between two series (element wise) ---- - -# Series.minimum - -> danfo.Series.minimum\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L383)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series | series to match | | - -**Return:** {Series} - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [10, 41, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.minimum(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 10 ║ -╟───┼──────────────────────╢ -║ 1 │ 40 ║ -╟───┼──────────────────────╢ -║ 2 │ 2 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.mod.md b/api-reference-v1-stable/series/series.mod.md deleted file mode 100644 index fdf0555..0000000 --- a/api-reference-v1-stable/series/series.mod.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -description: Return Modulo of series and other, element-wise (binary operator mod). ---- - -# Series.mod - -> danfo.Series.mod(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\|float | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Modulus with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 30, 4, 5] -let data2 = [1.1, 2.2, 3.3, 2.4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mod(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 0.8999999761581421 ║ -╟───┼──────────────────────╢ -║ 1 │ 1.3999993801116943 ║ -╟───┼──────────────────────╢ -║ 2 │ 0.7000000476837158 ║ -╟───┼──────────────────────╢ -║ 3 │ 0.19999980926513672 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Modulo with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mod(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 0 ║ -╟───┼──────────────────────╢ -║ 4 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.mode.md b/api-reference-v1-stable/series/series.mode.md deleted file mode 100644 index 6077686..0000000 --- a/api-reference-v1-stable/series/series.mode.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Obtain the center value in a series ---- - -# Series.mode - -> danfo.Series.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L303)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.mode()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -[ 4 ] -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.mul.md b/api-reference-v1-stable/series/series.mul.md deleted file mode 100644 index d5d33de..0000000 --- a/api-reference-v1-stable/series/series.mul.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Multiplication of series and other, element-wise (binary operator mul). ---- - -# Series.mul - -> danfo.Series.mul(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L168)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -multiplication with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.mul(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30 ║ -╟───┼──────────────────────╢ -║ 1 │ 80 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 20 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -multiply with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.mul(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 6 ║ -╟───┼──────────────────────╢ -║ 3 │ 8 ║ -╟───┼──────────────────────╢ -║ 4 │ 10 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.ndim.md b/api-reference-v1-stable/series/series.ndim.md deleted file mode 100644 index 8623e80..0000000 --- a/api-reference-v1-stable/series/series.ndim.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Obtain the dimension of a series ---- - -# Series.ndim - -> danfo.Series.ndim \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L209)] - -**Parameters:** None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.ndim) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -1 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.ne.md b/api-reference-v1-stable/series/series.ne.md deleted file mode 100644 index 16cf1dc..0000000 --- a/api-reference-v1-stable/series/series.ne.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -description: Check if all values in a series is not equal to a value(s) ---- - -# Series.ne - -> danfo.Series.ne(other) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L883)] - -| Parameters | Type | Description | Default | -| ---------- | ----------------------- | ----------------- | ------- | -| other | Series, Array or number | value to compare | | - -**Returns**: Series (Boolean element) - -**Example** - -Compare all the values in a series to that in another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let data2 = [10, 450, 56, 5, 25, 2, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) - -sf1.ne(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Compare all the values in a Series to a value. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf1 = new dfd.Series(data1) - -sf1.ne(10).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╟───┼──────────────────────╢ -║ 4 │ true ║ -╟───┼──────────────────────╢ -║ 5 │ true ║ -╟───┼──────────────────────╢ -║ 6 │ false ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.nunique.md b/api-reference-v1-stable/series/series.nunique.md deleted file mode 100644 index 092a2eb..0000000 --- a/api-reference-v1-stable/series/series.nunique.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Returns the number of unique values in a series ---- - -# Series.nunique - -> danfo.Series.**nunique**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters**: None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -console.log(sf.nunique()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Ouptut" %} -``` -9 -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.or.md b/api-reference-v1-stable/series/series.or.md deleted file mode 100644 index 948c61d..0000000 --- a/api-reference-v1-stable/series/series.or.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -description: >- - Returns the logical OR between Series and other. Supports element wise - operations and broadcasting. ---- - -# Series.or - -> danfo.Series.**or**\(other\) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/series.js#L1243)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| other | Series, Scalar, Array of Scalars | Data to compare with | | - - **Return:** Series - -### **Logical OR between two Series object** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let sf2 = new dfd.Series(data2); -let res = sf.or(sf2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between Series and Array of the same length** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [false, false, false, true, false, false, true]; -let data2 = [false, false, false, false, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(data2) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - -### **Logical OR between a Series and single value with broadcasting** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data1 = [false, false, false, true, false, false, true]; - -let sf = new dfd.Series(data1); -let res = sf.or(false) -res.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤═══════╗ -║ 0 │ false ║ -╟───┼───────╢ -║ 1 │ false ║ -╟───┼───────╢ -║ 2 │ false ║ -╟───┼───────╢ -║ 3 │ true ║ -╟───┼───────╢ -║ 4 │ false ║ -╟───┼───────╢ -║ 5 │ false ║ -╟───┼───────╢ -║ 6 │ true ║ -╚═══╧═══════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.pow.md b/api-reference-v1-stable/series/series.pow.md deleted file mode 100644 index 2fbe542..0000000 --- a/api-reference-v1-stable/series/series.pow.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -description: >- - Return Exponential power of series and other, element-wise (binary operator - pow). ---- - -# Series.pow - -> danfo.Series.pow(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L216)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -Exponential power with values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [2, 3, 4, 5] -let data2 = [1, 2, 3, 0] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.pow(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 2 ║ -╟───┼──────────────────────╢ -║ 1 │ 9 ║ -╟───┼──────────────────────╢ -║ 2 │ 64 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Exponential value with a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.pow(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 4 ║ -╟───┼──────────────────────╢ -║ 2 │ 9 ║ -╟───┼──────────────────────╢ -║ 3 │ 16 ║ -╟───┼──────────────────────╢ -║ 4 │ 25 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.replace.md b/api-reference-v1-stable/series/series.replace.md deleted file mode 100644 index 8a1f48b..0000000 --- a/api-reference-v1-stable/series/series.replace.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -description: Replace values given in replace param with value ---- - -# Series.replace - -> danfo.Series.**replace**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L892)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| options | Object |

oldValue: The value you want to replace

newValue: The new value you want to replace the old value with

inplace: Boolean indicating whether to perform the operation inplace or not

|

{

inplace: false

}

| - -**Returns**: Series - -**Examples** - -### Replace a value in a series and return a new series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -let sf_rep = sf.replace({ oldValue: 10, newValue: -50 }) - -sf_rep.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` -{% endtab %} -{% endtabs %} - -### Replace a value in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [10, 45, 56, 25, 23, 20, 10] -let sf = new dfd.Series(data1) -sf.replace({ oldValue: 10, newValue: -50, inplace: true}) - -sf.print() -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤═════╗ -║ 0 │ -50 ║ -╟───┼─────╢ -║ 1 │ 45 ║ -╟───┼─────╢ -║ 2 │ 56 ║ -╟───┼─────╢ -║ 3 │ 25 ║ -╟───┼─────╢ -║ 4 │ 23 ║ -╟───┼─────╢ -║ 5 │ 20 ║ -╟───┼─────╢ -║ 6 │ -50 ║ -╚═══╧═════╝ - -``` diff --git a/api-reference-v1-stable/series/series.reset_index.md b/api-reference-v1-stable/series/series.reset_index.md deleted file mode 100644 index c51497a..0000000 --- a/api-reference-v1-stable/series/series.reset_index.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -description: Reset the index of a series. ---- - -# Series.reset\_index - -> danfo.series.reset\_index(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L614)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------- | ---------------- | -| options | Object | **inplace:** Boolean indicating whether to perform the operation inplace or not. Defaults to false | { inplace:false} | - -**Returns :** Series - -`reset_index` is useful when the index needs to be treated as a column, or when the index is meaningless and needs to be reset to default, before another operation. - -### **Reset index to default values** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [20, 30, 40] -let sf = new dfd.Series(data, { index: ["a", "b", "c"] }) -sf.print() - -let sf_reset = sf.reset_index() -sf_reset.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ a │ 20 ║ -╟───┼────╢ -║ b │ 30 ║ -╟───┼────╢ -║ c │ 40 ║ -╚═══╧════╝ - -╔═══╤════╗ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 2 │ 40 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Reset index to new values in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data, { index: ['a', 'b', 'c', 'd', 'e', 'f'] }) -sf.print() - -sf.reset_index({ inplace: true }) -sf.print() - -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ a │ 1 ║ -╟───┼───╢ -║ b │ 2 ║ -╟───┼───╢ -║ c │ 3 ║ -╟───┼───╢ -║ d │ 4 ║ -╟───┼───╢ -║ e │ 5 ║ -╟───┼───╢ -║ f │ 6 ║ -╚═══╧═══╝ - -╔═══╤═══╗ -║ 0 │ 1 ║ -╟───┼───╢ -║ 1 │ 2 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 4 ║ -╟───┼───╢ -║ 4 │ 5 ║ -╟───┼───╢ -║ 5 │ 6 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.round.md b/api-reference-v1-stable/series/series.round.md deleted file mode 100644 index b6f0d82..0000000 --- a/api-reference-v1-stable/series/series.round.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: round off floating values in series ---- - -# Series.round - -> danfo.Series.round(dp, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L404)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| dp | int | decimal place to round off to | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -sf1.round(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 30.21 ║ -╟───┼──────────────────────╢ -║ 1 │ 40.19 ║ -╟───┼──────────────────────╢ -║ 2 │ 3.56 ║ -╟───┼──────────────────────╢ -║ 3 │ 5.02 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.sample.md b/api-reference-v1-stable/series/series.sample.md deleted file mode 100644 index a28298d..0000000 --- a/api-reference-v1-stable/series/series.sample.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -description: Return a random sample of items from an axis of object. ---- - -# Series.sample - -> danfo.Series.sample(num) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L98)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -| num | Int | The number of rows to return. | | -| options | Object | **seed**: An integer specifying the random seed that will be used to create the distribution. Ensures reproducibility of generated samples. |

{

seed: 1

}

| - -**Returns:** - - **** return **{Promies} resolves to Series** - -**Example** - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5) - sample.print() - -} -load_data() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤════╗ -║ 2 │ 3 ║ -╟───┼────╢ -║ 4 │ 5 ║ -╟───┼────╢ -║ 0 │ 1 ║ -╟───┼────╢ -║ 7 │ 40 ║ -╟───┼────╢ -║ 6 │ 30 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Specify a seed when sampling - -```javascript -const dfd = require("danfojs-node") - -async function load_data() { - let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78]; - let sf1 = new dfd.Series(data1); - let sample = await sf1.sample(5, { seed: 2 }) - sample.print() - -} -load_data() - -``` diff --git a/api-reference-v1-stable/series/series.set_index.md b/api-reference-v1-stable/series/series.set_index.md deleted file mode 100644 index 3de352f..0000000 --- a/api-reference-v1-stable/series/series.set_index.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -description: Assign new Index to Series ---- - -# Series.set\_index - -> danfo.series.**set\_index(**options**)** \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L635)] - -| Parameter | Type | Description | Default | -| --------- | ------ | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| index | Array | new index values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") -let data = [{ alpha: "A", count: 1 }, { alpha: "B", count: 2 }, { alpha: "C", count: 3 }] -let sf = new dfd.Series(data) -sf.print() - -let sf_new = sf.set_index({ "index": ["one", "two", "three"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═════════════════════════╗ -║ 0 │ {"alpha":"A","count":1} ║ -╟───┼─────────────────────────╢ -║ 1 │ {"alpha":"B","count":2} ║ -╟───┼─────────────────────────╢ -║ 2 │ {"alpha":"C","count":3} ║ -╚═══╧═════════════════════════╝ - -╔═══════╤═════════════════════════╗ -║ one │ {"alpha":"A","count":1} ║ -╟───────┼─────────────────────────╢ -║ two │ {"alpha":"B","count":2} ║ -╟───────┼─────────────────────────╢ -║ three │ {"alpha":"C","count":3} ║ -╚═══════╧═════════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["Humans","Life","Meaning","Fact","Truth"] -let sf = new dfd.Series(data) -let sf_new = sf.set_index({ "index": ["H", "L", "M","F","T"] }) -sf_new.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ H │ Humans ║ -╟───┼──────────────────────╢ -║ L │ Life ║ -╟───┼──────────────────────╢ -║ M │ Meaning ║ -╟───┼──────────────────────╢ -║ F │ Fact ║ -╟───┼──────────────────────╢ -║ T │ Truth ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -### Set index in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs") - -let data = [1, 2, 3, 4, 5, 6] -let sf = new dfd.Series(data) -sf.set_index({ index: ["one", "two", "three", "four", "five", "six"], inplace: true }) -sf.print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══════╤═══╗ -║ one │ 1 ║ -╟───────┼───╢ -║ two │ 2 ║ -╟───────┼───╢ -║ three │ 3 ║ -╟───────┼───╢ -║ four │ 4 ║ -╟───────┼───╢ -║ five │ 5 ║ -╟───────┼───╢ -║ six │ 6 ║ -╚═══════╧═══╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.shape.md b/api-reference-v1-stable/series/series.shape.md deleted file mode 100644 index 9eb5031..0000000 --- a/api-reference-v1-stable/series/series.shape.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the shape of a Series ---- - -# Series.shape - -> danfo.Series.shape \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L266)\] - -**Parameters**: None - -**Returns**: Array \[int, int\] - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.shape) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 4, 1 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.size.md b/api-reference-v1-stable/series/series.size.md deleted file mode 100644 index 9665b65..0000000 --- a/api-reference-v1-stable/series/series.size.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Obtain the size of a series ---- - -# Series.size - -> danfo.Series.size \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L305)\] - -**Parameters**: None - -**Returns:** int - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.size) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -4 -``` -{% endtab %} -{% endtabs %} - - - diff --git a/api-reference-v1-stable/series/series.sort_values.md b/api-reference-v1-stable/series/series.sort_values.md deleted file mode 100644 index 5c7e5fa..0000000 --- a/api-reference-v1-stable/series/series.sort_values.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -description: Sorts a Series in ascending or descending order ---- - -# Series.sort_values - -> danfo.Series.sort_values(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L511)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| options | Object |

inplace: Boolean indicating whether to perform the operation in-place or not. Defaults to false

ascending: Whether to return sorted values in ascending order or not. Defaults to true

|

{
ascending: true,

inplace: false

}

| - - **Return:** Series - -### Sort values in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -let sf2 = sf1.sort_values() - -sf2.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} - -### Sort Series in-place - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ inplace: true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 7 │ 0 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 6 │ 89 ║ -╚═══╧════╝ - -``` -{% endtab %} -{% endtabs %} - -Sort Series values in descending order - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) -sf1.sort_values({ "ascending": false, "inplace": true }) - -sf1.print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════╗ -║ 6 │ 89 ║ -╟───┼────╢ -║ 5 │ 57 ║ -╟───┼────╢ -║ 1 │ 30 ║ -╟───┼────╢ -║ 0 │ 20 ║ -╟───┼────╢ -║ 4 │ 4 ║ -╟───┼────╢ -║ 8 │ 4 ║ -╟───┼────╢ -║ 3 │ 2 ║ -╟───┼────╢ -║ 2 │ 1 ║ -╟───┼────╢ -║ 7 │ 0 ║ -╚═══╧════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.std.md b/api-reference-v1-stable/series/series.std.md deleted file mode 100644 index aa05018..0000000 --- a/api-reference-v1-stable/series/series.std.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Obtain the standard deviation for a series ---- - -# Series.std - -> danfo.Series.std() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L422)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.std()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -31.11671576500322 -``` -{% endtab %} -{% endtabs %} - - **** - diff --git a/api-reference-v1-stable/series/series.str.capitalize.md b/api-reference-v1-stable/series/series.str.capitalize.md deleted file mode 100644 index aea9e91..0000000 --- a/api-reference-v1-stable/series/series.str.capitalize.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Capitalize the first character of each string ---- - -# Series.str.capitalize - -> danfo.Series.str.**capitalize**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L46)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert the first character of a string to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'capitals', 'sentence', 'swApCaSe'] -let sf = new dfd.Series(data) -sf.str.capitalize().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ Lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ Capitals ║ -╟───┼──────────────────────╢ -║ 2 │ Sentence ║ -╟───┼──────────────────────╢ -║ 3 │ Swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.charat.md b/api-reference-v1-stable/series/series.str.charat.md deleted file mode 100644 index 931bb48..0000000 --- a/api-reference-v1-stable/series/series.str.charat.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: Obtain the character at the specified index (position) ---- - -# Series.str.charAt - -> danfo.Series.str.**charAt**(index) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L64)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| index | int | the index at which to obtain the character | 0 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Character element) - -**Example** - -Obtain the character at index 2 of all string elements in the series. - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.charAt(2).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ w ║ -╟───┼──────────────────────╢ -║ 1 │ P ║ -╟───┼──────────────────────╢ -║ 2 │ n ║ -╟───┼──────────────────────╢ -║ 3 │ A ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.concat.md b/api-reference-v1-stable/series/series.str.concat.md deleted file mode 100644 index e3abe54..0000000 --- a/api-reference-v1-stable/series/series.str.concat.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -description: Joins two or more strings/arrays ---- - -# Series.str.concat - -> danfo.Series.str.**concat**(other, position, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L80)] - -| Parameters | Type | Description | Default | -| ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -| other | string or Array | string or list of strings to add to each string element of the series | "" | -| position | Int | The position to add the **other** (string or array) is either 0 or 1. 0 is to add the other at the beginning of each of the string element, and 1 is to add to the end of the string element | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series (String element) - -**Examples** - -Add the strings from an Array to the start of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ XXlower boy ║ -╟───┼──────────────────────╢ -║ 1 │ YYCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ BBsentence ║ -╟───┼──────────────────────╢ -║ 3 │ 01SwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add the strings from an Array to the end of each of the String element in Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat(data2,1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boyXX ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSYY ║ -╟───┼──────────────────────╢ -║ 2 │ sentenceBB ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSe01 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the start of each string element in a Series - -{% tabs %} -{% tab title="Output" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("pre",0).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ prelower boy ║ -╟───┼──────────────────────╢ -║ 1 │ preCAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ presentence ║ -╟───┼──────────────────────╢ -║ 3 │ preSwApCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Add a string to the end of each string element in a series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let data2 = ['XX', 'YY', 'BB', '01'] -let sf = new dfd.Series(data) -sf.str.concat("post",1).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boypost ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALSpost ║ -╟───┼──────────────────────╢ -║ 2 │ sentencepost ║ -╟───┼──────────────────────╢ -║ 3 │ SwApCaSepost ║ -╚═══╧══════════════════════╝ -``` diff --git a/api-reference-v1-stable/series/series.str.endswith.md b/api-reference-v1-stable/series/series.str.endswith.md deleted file mode 100644 index 2fb44cc..0000000 --- a/api-reference-v1-stable/series/series.str.endswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string ends with specified characters ---- - -# Series.str.endsWith - -> danfo.Series.str.**endsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L133)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (Boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.endsWith("e").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ true ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.includes.md b/api-reference-v1-stable/series/series.str.includes.md deleted file mode 100644 index 8918773..0000000 --- a/api-reference-v1-stable/series/series.str.includes.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Checks whether a string contains the specified string/characters ---- - -# Series.str.includes - -> danfo.Series.str.includes(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L147)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (boolean element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.includes("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ true ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.indexof.md b/api-reference-v1-stable/series/series.str.indexof.md deleted file mode 100644 index 1d9e64f..0000000 --- a/api-reference-v1-stable/series/series.str.indexof.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: the position of the first found occurrence of a specified value in a string ---- - -# Series.str.indexOf - -> danfo.Series.str.indexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L161)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to obtain its index | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.indexOf("C").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.join.md b/api-reference-v1-stable/series/series.str.join.md deleted file mode 100644 index 5bb77fe..0000000 --- a/api-reference-v1-stable/series/series.str.join.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Join a new string value to all string elements in a Series. ---- - -# Series.str.join - -> danfo.Series.str.**join**(valToJoin, joinChar, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L308)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| valToJoin | String | the string value you want to | "" | -| joinChar | String | The delimiter to specify the joining | " " | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return **Series** - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part', 'CAPITALS city', 'this is a sentence', 'SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.join("new", "_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤════════════════════════╗ -║ 0 │ lower part_new ║ -╟───┼────────────────────────╢ -║ 1 │ CAPITALS city_new ║ -╟───┼────────────────────────╢ -║ 2 │ this is a sentence_new ║ -╟───┼────────────────────────╢ -║ 3 │ SwAp CaSe_new ║ -╚═══╧════════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.lastindexof.md b/api-reference-v1-stable/series/series.str.lastindexof.md deleted file mode 100644 index 889a1f4..0000000 --- a/api-reference-v1-stable/series/series.str.lastindexof.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: >- - Obtain the position of the last found occurrence of a specified value in a - string ---- - -# Series.str.lastIndexOf - -danfo.Series.str.lastIndexOf(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L175)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.lastIndexOf("r").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 4 ║ -╟───┼──────────────────────╢ -║ 1 │ -1 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.str.len.md b/api-reference-v1-stable/series/series.str.len.md deleted file mode 100644 index 0ef06b2..0000000 --- a/api-reference-v1-stable/series/series.str.len.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Obtain the length of each string element in a Series ---- - -# Series.str.len - -> danfo.Series.str.**len**(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L324)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Examples** - -Returns the length (number of character) of a string, and also return the length (number of elements) of Array - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["dog", 5,"cat","fog","mug","animals"] -let sf = new dfd.Series(data) -sf.str.len().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤═══╗ -║ 0 │ 3 ║ -╟───┼───╢ -║ 1 │ 1 ║ -╟───┼───╢ -║ 2 │ 3 ║ -╟───┼───╢ -║ 3 │ 3 ║ -╟───┼───╢ -║ 4 │ 3 ║ -╟───┼───╢ -║ 5 │ 7 ║ -╚═══╧═══╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.repeat.md b/api-reference-v1-stable/series/series.str.repeat.md deleted file mode 100644 index 703be26..0000000 --- a/api-reference-v1-stable/series/series.str.repeat.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Repeat the the character(s) in a string for a specified number of time ---- - -# Series.str.repeat - -> danfo.Series.str.**repeat**(num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L205)] - -| Parameters | Type | Description | Default | -| ---------- | ------- | --------------------------------------------------------------- | ------------------------------------------------------ | -| num | integer | the string to search for | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['a', 'b', 'c', 'd'] -let sf = new dfd.Series(data) -sf.str.repeat(4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ aaaa ║ -╟───┼──────────────────────╢ -║ 1 │ bbbb ║ -╟───┼──────────────────────╢ -║ 2 │ cccc ║ -╟───┼──────────────────────╢ -║ 3 │ dddd ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.replace.md b/api-reference-v1-stable/series/series.str.replace.md deleted file mode 100644 index 2b06b1f..0000000 --- a/api-reference-v1-stable/series/series.str.replace.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Replace a word or character(s) in a String element ---- - -# Series.str.replace - -> danfo.Series.str.replace(searchValue, replaceValue, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L191)] - -| Parameters | Type | Description | Default | -| ------------ | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| searchValue | string | String \| Character value to replace. Supports regex. | "" | -| replaceValue | String | string to replace the searched string | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.replace("A", "XXX").print() -``` -{% endtab %} - -{% tab title="Browse" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower ║ -╟───┼──────────────────────╢ -║ 1 │ CXXXPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwXXXpCaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.search.md b/api-reference-v1-stable/series/series.str.search.md deleted file mode 100644 index 99fc428..0000000 --- a/api-reference-v1-stable/series/series.str.search.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -description: Obtain the index position of a searched character in a String ---- - -# Series.str.search - -> danfo.Series.str.**search**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L220)] - - - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | String | the string to search for | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series: Series of index position - -**Example** - -obtain the index position for a character - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 8 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -Obtain the index position for a searched word - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower city ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.search("city").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 6 ║ -╟───┼──────────────────────╢ -║ 1 │ 10 ║ -╟───┼──────────────────────╢ -║ 2 │ -1 ║ -╟───┼──────────────────────╢ -║ 3 │ -1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.slice.md b/api-reference-v1-stable/series/series.str.slice.md deleted file mode 100644 index cef7a86..0000000 --- a/api-reference-v1-stable/series/series.str.slice.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.slice - -> danfo.Series.str.slice(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L235)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series. - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.slice(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.split.md b/api-reference-v1-stable/series/series.str.split.md deleted file mode 100644 index 006795d..0000000 --- a/api-reference-v1-stable/series/series.str.split.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: >- - Split string around a given separator/delimiter. The array of strings are then - converted to a string. ---- - -# Series.str.split - -> danfo.Series.str.**split**(splitVal, options) \[[source](https://github.com/opensource9ja/danfojs/blob/e25010c26d9c423412613d820015a48ad03d5c6d/danfojs-node/src/core/strings.js#L553)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | ---------------------------------------------------------- | ------------------------------- | -| splitVal | String | separator or delimiter used to split the string | " " | -| options | Object | **inplace**: Whether to perform operation in-place or not. |

{
inplace: false
}

| - -**Returns** - - return **Series** - -**Examples** - -Split the string value in the Series by space and obtain the Series values - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king of the music","the lamba queen","I love the hat"] -let sf = new dfd.Series(data) -console.log(sf.str.split().values) -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -**OUTPUT:** `[ 'king,of,the,music', 'the,lamba,queen', 'I,love,the,hat' ]` - -{% tabs %} -{% tab title="JavaScript" %} -```javascript -const dfd = require("danfojs-node") - -let data = ["king_of_the_music","the_lamba_queen","I_love_the_hat"] -let sf = new dfd.Series(data) -sf.str.split("_").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ king,of,the,music ║ -╟───┼──────────────────────╢ -║ 1 │ the,lamba,queen ║ -╟───┼──────────────────────╢ -║ 2 │ I,love,the,hat ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.startswith.md b/api-reference-v1-stable/series/series.str.startswith.md deleted file mode 100644 index 835809e..0000000 --- a/api-reference-v1-stable/series/series.str.startswith.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Test whether a string begins with specified characters ---- - -# Series.str.startsWith - -> danfo.Series.str.**startsWith**(str, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L119)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| str | string | the character(s) to check | "" | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** Series (Boolean element) - -**Examples** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.startsWith("S").print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ false ║ -╟───┼──────────────────────╢ -║ 1 │ false ║ -╟───┼──────────────────────╢ -║ 2 │ false ║ -╟───┼──────────────────────╢ -║ 3 │ true ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substr.md b/api-reference-v1-stable/series/series.str.substr.md deleted file mode 100644 index 0a391bb..0000000 --- a/api-reference-v1-stable/series/series.str.substr.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: >- - Obtain the substring from a String element in a Series, by specifying the - number of string to obtain starting from a specific index. ---- - -# Series.str.substr - -> danfo.Series.str.substr(startIndex, num, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L265)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| num | Number | The number of character to obtain starting from the startIndex | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series - -**Example** - -Obtain substring( containing 4 characters) starting from the third character (2nd index). - -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substr(2, 4).print() -``` - -{% tabs %} -{% tab title="Output" %} -```javascript -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ wer ║ -╟───┼──────────────────────╢ -║ 1 │ APIT ║ -╟───┼──────────────────────╢ -║ 2 │ his ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp ║ -╚═══╧══════════════════════╝ - -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.substring.md b/api-reference-v1-stable/series/series.str.substring.md deleted file mode 100644 index b54702e..0000000 --- a/api-reference-v1-stable/series/series.str.substring.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -description: Obtain the substring of each element in a series ---- - -# Series.str.substring - -> danfo.Series.str.**substring**(startIndex, endIndex, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L280)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| startIndex | Number | specify the index to start obtaining the substring | 0 | -| endIndex | Number | specify the index to end the substring | 1 | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns** - - **** return **Series** - -**Example** - -Obtain the substring from index 2 to index 4 of the string elements in a Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.substring(2, 4).print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ we ║ -╟───┼──────────────────────╢ -║ 1 │ AP ║ -╟───┼──────────────────────╢ -║ 2 │ hi ║ -╟───┼──────────────────────╢ -║ 3 │ Sw ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.tolowercase.md b/api-reference-v1-stable/series/series.str.tolowercase.md deleted file mode 100644 index 9abe0f5..0000000 --- a/api-reference-v1-stable/series/series.str.tolowercase.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Converts all characters to lower case. ---- - -# Series.str.toLowerCase - -> danfo.Series.str.toLowerCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L20)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Example** - -Convert all characters in each string element to small letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['LOWER BOY', 'CAPITALS', 'SENTENCE', 'SWAPCASE'] -let sf = new dfd.Series(data) -sf.str.toLowerCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower boy ║ -╟───┼──────────────────────╢ -║ 1 │ capitals ║ -╟───┼──────────────────────╢ -║ 2 │ sentence ║ -╟───┼──────────────────────╢ -║ 3 │ swapcase ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.touppercase.md b/api-reference-v1-stable/series/series.str.touppercase.md deleted file mode 100644 index f484390..0000000 --- a/api-reference-v1-stable/series/series.str.touppercase.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -description: Converts all characters to uppercase. ---- - -# Series.str.toUpperCase - -> danfo.Series.str.toUpperCase(options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L33)] - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns**: Series (String element) - -**Example** - -Convert all characters in each string element to capital letter - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower boy', 'CAPITALS', 'sentence', 'SwApCaSe'] -let sf = new dfd.Series(data) -sf.str.toUpperCase().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ LOWER BOY ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS ║ -╟───┼──────────────────────╢ -║ 2 │ SENTENCE ║ -╟───┼──────────────────────╢ -║ 3 │ SWAPCASE ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.str.trim.md b/api-reference-v1-stable/series/series.str.trim.md deleted file mode 100644 index 58b7b16..0000000 --- a/api-reference-v1-stable/series/series.str.trim.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: Remove leading and trailing Whitespace from a String element ---- - -# Series.str.trim - -> danfo.Series.str.**trim**(options) **\[**[**source**](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/strings.js#L293)**]** - -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------ | -| options | Object | **inplace**: Whether to perform the operation in-place or not. |

{

inplace: false

}

| - -**Returns:** - - **** return Series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data = ['lower part ', ' CAPITALS city', ' this is a sentence', ' SwAp CaSe'] -let sf = new dfd.Series(data) -sf.str.trim().print() -``` -{% endtab %} - -{% tab title="Browser" %} -``` -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ lower part ║ -╟───┼──────────────────────╢ -║ 1 │ CAPITALS city ║ -╟───┼──────────────────────╢ -║ 2 │ this is a sentence ║ -╟───┼──────────────────────╢ -║ 3 │ SwAp CaSe ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.sub.md b/api-reference-v1-stable/series/series.sub.md deleted file mode 100644 index e281d06..0000000 --- a/api-reference-v1-stable/series/series.sub.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: Return Subtraction of series and other, element-wise (binary operator sub). ---- - -# Series.sub - -> danfo.Series.sub(other, options) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L148)] - -| Parameters | Type | Description | Default | -| ---------- | ------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------- | -| other | Series\|int\| | values | | -| options | Object | inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false |

{

inplace: false

}

| - -**Return:** Series - -**Example** - -subtract from values of another series - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30, 40, 3, 5] -let data2 = [1, 2, 3, 4] -let sf1 = new dfd.Series(data1) -let sf2 = new dfd.Series(data2) -sf1.sub(sf2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 29 ║ -╟───┼──────────────────────╢ -║ 1 │ 38 ║ -╟───┼──────────────────────╢ -║ 2 │ 0 ║ -╟───┼──────────────────────╢ -║ 3 │ 1 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - -subtract from a value - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5] -let sf1 = new dfd.Series(data1) - -sf1.sub(2).print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ -1 ║ -╟───┼──────────────────────╢ -║ 1 │ 0 ║ -╟───┼──────────────────────╢ -║ 2 │ 1 ║ -╟───┼──────────────────────╢ -║ 3 │ 2 ║ -╟───┼──────────────────────╢ -║ 4 │ 3 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.sum.md b/api-reference-v1-stable/series/series.sum.md deleted file mode 100644 index fabcba7..0000000 --- a/api-reference-v1-stable/series/series.sum.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: Return the sum of the values in a series. ---- - -# Series.sum - -> danfo.Series.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L333)] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.sum()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -207 -``` -{% endtab %} -{% endtabs %} - -**** diff --git a/api-reference-v1-stable/series/series.tail.md b/api-reference-v1-stable/series/series.tail.md deleted file mode 100644 index 7f986a1..0000000 --- a/api-reference-v1-stable/series/series.tail.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -description: Prints the last n values in a Series ---- - -# Series.tail - -> danfo.Series.tail\(rows\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L76)\] - -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| rows | Int | number of last n values | 5 | - - **Return:** Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 620, 30, 40, 39, 89, 78] -let sf1 = new dfd.Series(data1) - -sf1.tail().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 6 │ 30 ║ -╟────┼──────────────────────╢ -║ 7 │ 40 ║ -╟────┼──────────────────────╢ -║ 8 │ 39 ║ -╟────┼──────────────────────╢ -║ 9 │ 89 ║ -╟────┼──────────────────────╢ -║ 10 │ 78 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.tensor.md b/api-reference-v1-stable/series/series.tensor.md deleted file mode 100644 index a5c112c..0000000 --- a/api-reference-v1-stable/series/series.tensor.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -description: Obtain the tensor representation of the values in a Series ---- - -# Series.tensor - -> danfo.Series.tensor \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L45)\] - -**Parameters**: None - -**Returns**: Tensorflow tensor - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.tensor) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -Tensor { - kept: false, - isDisposedInternal: false, - shape: [ 4 ], - dtype: 'float32', - size: 4, - strides: [], - dataId: {}, - id: 2, - rankType: '1', - scopeId: 0 -} -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.unique.md b/api-reference-v1-stable/series/series.unique.md deleted file mode 100644 index c89d187..0000000 --- a/api-reference-v1-stable/series/series.unique.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Obtain the unique value in a Series ---- - -# Series.unique - -> danfo.Series.**unique**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L736)\] - -**Parameters**: None - -**Returns**: Series - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.unique().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -╔═══╤══════════════════════╗ -║ │ 0 ║ -╟───┼──────────────────────╢ -║ 0 │ 1 ║ -╟───┼──────────────────────╢ -║ 1 │ 2 ║ -╟───┼──────────────────────╢ -║ 2 │ 3 ║ -╟───┼──────────────────────╢ -║ 3 │ 4 ║ -╟───┼──────────────────────╢ -║ 4 │ 5 ║ -╟───┼──────────────────────╢ -║ 5 │ 6 ║ -╟───┼──────────────────────╢ -║ 6 │ 7 ║ -╟───┼──────────────────────╢ -║ 7 │ 8 ║ -╟───┼──────────────────────╢ -║ 8 │ 22 ║ -╚═══╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.value_counts.md b/api-reference-v1-stable/series/series.value_counts.md deleted file mode 100644 index 338064f..0000000 --- a/api-reference-v1-stable/series/series.value_counts.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -description: Count the number of occurrence for each element in a Series ---- - -# Series.value\_counts - -> danfo.Series.value\_counts() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L750)] - -**Parameters:** None - -**Returns:** Series (int element) - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 22, 8, 5, 5, 5] -let sf = new dfd.Series(data1) - -sf.value_counts().print() -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -``` -╔════╤══════════════════════╗ -║ │ 0 ║ -╟────┼──────────────────────╢ -║ 1 │ 3 ║ -╟────┼──────────────────────╢ -║ 2 │ 1 ║ -╟────┼──────────────────────╢ -║ 3 │ 1 ║ -╟────┼──────────────────────╢ -║ 4 │ 1 ║ -╟────┼──────────────────────╢ -║ 5 │ 4 ║ -╟────┼──────────────────────╢ -║ 6 │ 1 ║ -╟────┼──────────────────────╢ -║ 7 │ 1 ║ -╟────┼──────────────────────╢ -║ 8 │ 2 ║ -╟────┼──────────────────────╢ -║ 22 │ 1 ║ -╚════╧══════════════════════╝ -``` -{% endtab %} -{% endtabs %} diff --git a/api-reference-v1-stable/series/series.values.md b/api-reference-v1-stable/series/series.values.md deleted file mode 100644 index 4857487..0000000 --- a/api-reference-v1-stable/series/series.values.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Obtain the values in a series ---- - -# Series.values - -> danfo.Series.values \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/generic.js#L279)\] - -**Parameters:** None - -**Returns**: Array - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [30.21091, 40.190901, 3.564, 5.0212] -let sf1 = new dfd.Series(data1) - -console.log(sf1.values) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -[ 30.21091, 40.190901, 3.564, 5.0212 ] -``` -{% endtab %} -{% endtabs %} - diff --git a/api-reference-v1-stable/series/series.var.md b/api-reference-v1-stable/series/series.var.md deleted file mode 100644 index 4fdcbc2..0000000 --- a/api-reference-v1-stable/series/series.var.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: Calculate the variance of a Series ---- - -# Series.var - -> danfo.Series.var\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/series.js#L436)\] - -**Parameter:** None - -**Return:** Number - -**Example** - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - -let data1 = [20, 30, 1, 2, 4, 57, 89, 0, 4] -let sf1 = new dfd.Series(data1) - -console.log(sf1.var()) -``` -{% endtab %} -{% endtabs %} - -{% tabs %} -{% tab title="Output" %} -```text -968.25 -``` -{% endtab %} -{% endtabs %} - From 70a6bda320e186ee411d026279c135057cd3784a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Jan 2022 16:31:20 +0100 Subject: [PATCH 162/202] Update danfojs script version --- .../dataframe/creating-a-dataframe.md | 8 ++--- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +-- .../input-output/danfo.read_excel.md | 4 +-- api-reference/input-output/danfo.read_json.md | 4 +-- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +-- api-reference/plotting/histograms.md | 2 +- api-reference/plotting/line-charts.md | 6 ++-- api-reference/plotting/pie-charts.md | 4 +-- api-reference/plotting/scatter-plots.md | 4 +-- api-reference/plotting/violin-plots.md | 4 +-- api-reference/series/creating-a-series.md | 4 +-- getting-started.md | 36 +++++++++---------- release-notes.md | 2 +- 17 files changed, 47 insertions(+), 47 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index 2103b9d..e740d1c 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -40,7 +40,7 @@ df.print() - Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 504cbcc..b0ce43f 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index b1f043a..6b570f5 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 870f105..932b4b8 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 5359117..402e533 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index ecf32c7..ab6df99 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index e502326..d6d41a6 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index bdcafc9..bb79f1f 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index e62390c..d02452b 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 8a9a2e1..b1a1ed7 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index aa1cd50..d94edc2 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 8776b7f..5fc7981 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 92f239b..856fc43 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 3ea40a8..356342a 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index b957807..82bd9a7 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index de8a123..bf802c6 100644 --- a/getting-started.md +++ b/getting-started.md @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - Document + Document @@ -290,7 +290,7 @@ df.ctypes.print() - Document + Document @@ -368,7 +368,7 @@ df.print() - Document + Document @@ -459,7 +459,7 @@ df.print() - Document + Document @@ -567,7 +567,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -652,7 +652,7 @@ df.tensor.print() - Document + Document @@ -732,7 +732,7 @@ df.describe().print() - Document + Document @@ -805,7 +805,7 @@ df.print() - Document + Document @@ -875,7 +875,7 @@ df['A'].print() - Document + Document @@ -1292,7 +1292,7 @@ df.print() - Document + Document @@ -1381,7 +1381,7 @@ df_drop.print() - Document + Document @@ -1599,7 +1599,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2223,7 +2223,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2275,7 +2275,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2370,7 +2370,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 6bfac22..4998447 100644 --- a/release-notes.md +++ b/release-notes.md @@ -122,7 +122,7 @@ A simple example: - + Document From d9d60826ae7246682b3fb6a0dcac948b235e7c6b Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Fri, 14 Jan 2022 08:50:01 +0000 Subject: [PATCH 163/202] GitBook: [#214] No subject --- building-data-driven-applications-with-danfo.js-book.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index cf3e174..0a40dc9 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -1,6 +1,6 @@ # Building Data Driven Applications with Danfo.js - Book -## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) using _25Danfo_ code before 31st December 2020 and get 25% discount. +## Purchase on [Packt](https://www.packtpub.com/product/building-data-driven-applications-with-danfo-js/9781801070850) ## What this book is about @@ -38,4 +38,3 @@ This book is for data analysts, data scientists, and JavaScript developers who w 11. Building a Recommendation System with Danfo.js and TensorFlow.js 12. Building a Twitter Analysis Dashboard 13. Appendix: Essential JavaScript Concepts - From 59660f9e8e1bb5d33188d791c490fd8f4db57fd0 Mon Sep 17 00:00:00 2001 From: Stephen Oni Date: Sat, 15 Jan 2022 17:56:15 +0100 Subject: [PATCH 164/202] update groupby doc --- api-reference/groupby/groupby.agg.md | 93 ++++++++++----- api-reference/groupby/groupby.apply.md | 56 ++++----- api-reference/groupby/groupby.col.md | 123 ++++++++++--------- api-reference/groupby/groupby.count.md | 149 +++++++++++++++--------- api-reference/groupby/groupby.cummax.md | 50 ++++---- api-reference/groupby/groupby.cummin.md | 65 ++++++----- 6 files changed, 310 insertions(+), 226 deletions(-) diff --git a/api-reference/groupby/groupby.agg.md b/api-reference/groupby/groupby.agg.md index fae8802..fca7d03 100644 --- a/api-reference/groupby/groupby.agg.md +++ b/api-reference/groupby/groupby.agg.md @@ -8,13 +8,15 @@ description: Obtain data aggregate per groups for each column | Parameters | Type | Description | Default | | ---------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- | -| kwargs | Object | kwargs contain keys which are column names in the dataframe, and the values are operation to be performed | | +| ops | Object | keys are column names and `values` are aggregation operator | {} | **Return:** DataFrame **Examples** -Using mean and sum aggregate +**Aggregation using one aggregate operator per column** + +1) Assigning `mean` and `sum` aggregate to different column {% tabs %} {% tab title="Node" %} @@ -33,7 +35,7 @@ let data ={'A': ['foo', 'bar', 'foo', 'bar', let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.agg({"C":"mean","D":"sum"}).print() +grp.agg({C:"mean",D:"sum"}).print() ``` {% endtab %} {% endtabs %} @@ -41,16 +43,16 @@ grp.agg({"C":"mean","D":"sum"}).print() ``` Shape: (2,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 4.19999980926... │ 27 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ bar │ 3 │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ D_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.2 │ 27 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 9 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -Mean and Sum aggregate on dataframe groupby two column +2) Mean and Sum aggregate on dataframe grouped by two column {% tabs %} {% tab title="Node" %} @@ -69,25 +71,62 @@ let data ={'A': ['foo', 'bar', 'foo', 'bar', let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.agg({"C":"mean","D":"sum"}).print() +grp.agg({C:"mean",D:"sum"}).print() ``` {% endtab %} {% endtabs %} ``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_mean │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 3.5 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 3.5 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_mean │ D_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3.5 │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 3.5 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**Aggregation using two or more aggregate operator per column** + +Assigning `mean` and `sum`, `min`, `std`, `count` aggregate to different column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.agg({C:["mean", "sum", "min"], + D:["sum", "count", "std"]}).print() +``` +{% endtab %} +{% endtabs %} + ``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_mean │ C_sum │ C_min │ D_sum │ D_count │ D_std ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 4.2 │ 21 │ 1 │ 27 │ 5 │ 2.0736441353327… ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 9 │ 2 │ 9 │ 3 │ 2.6457513110645… ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` \ No newline at end of file diff --git a/api-reference/groupby/groupby.apply.md b/api-reference/groupby/groupby.apply.md index 2150a21..0fc1595 100644 --- a/api-reference/groupby/groupby.apply.md +++ b/api-reference/groupby/groupby.apply.md @@ -8,7 +8,7 @@ danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/ | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | -| callable | Function \| function to be applied to grouped data | Undefined | | +| callable | Function \| function to be applied to grouped data. the callable functons takes in DataFrame as argument adn returns DataFrame or Series | Undefined | | **Returns:** @@ -24,26 +24,28 @@ Using apply to create a custom function that subtract the minimum value of each const dfd = require("danfojs-node") let data = { - 'A': ['foo', 'bar', 'foo', 'bar', + A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1, 3, 2, 4, 5, 2, 6, 7], + C: [1, 3, 2, 4, 5, 2, 6, 7], - 'D': [3, 2, 4, 1, 5, 6, 7, 8] + D: [3, 2, 4, 1, 5, 6, 7, 8] }; + let df = new dfd.DataFrame(data); -let group_df = df.groupby(["A", "B"]); +let groupDf = df.groupby(["A", "B"]).col(['C', 'D']); const subMin = (x) => { - return x.sub(x.min()); + //find the min across column + return x.sub(x.min({axis:0})); }; -group_df.apply(subMin).print(); +groupDf.apply(subMin).print(); ``` {% endtab %} @@ -58,25 +60,25 @@ group_df.apply(subMin).print(); {% tabs %} {% tab title="Output" %} ```text -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_apply │ D_apply ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 5 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 3 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 0 │ 0 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 0 │ 0 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 5 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 3 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 0 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 0 │ 0 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` {% endtab %} {% endtabs %} diff --git a/api-reference/groupby/groupby.col.md b/api-reference/groupby/groupby.col.md index 02e7cdd..130b18f 100644 --- a/api-reference/groupby/groupby.col.md +++ b/api-reference/groupby/groupby.col.md @@ -12,33 +12,40 @@ description: Obtain the column(s) per groups Returns: Groupby Data structure -Note: This is similar to pandas `df.groupby(["column"])["col_names"]` +Note: This is similar to pandas `df.groupby(["column"])["colNames"]` **Examples** -Obtain a column +Obtain the column to perform group aggregate operation on {% tabs %} {% tab title="Node" %} ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] } let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]) -//for more coumns -grp.col(["C","D"]) +//select single column +let grpColumnC = grp.col(["C"]) + +// convert grouop internal data to dataFrame +grpColumnC.apply(x=> x).print() + +//select multiple column +let grpColumnBD = grp.col(["B", "D"]) + +grpColumnBD.apply(x=> x).print() ``` {% endtab %} {% endtabs %} @@ -46,59 +53,51 @@ grp.col(["C","D"]) Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. ```text -//it returns the groupby data structure -GroupBy { - key_col: [ 'A' ], - col_dict: { - foo: [ [Array], [Array], [Array], [Array], [Array] ], - bar: [ [Array], [Array], [Array] ] - }, - data: [ - [ 'foo', 'one', 1, 3 ], - [ 'bar', 'one', 3, 2 ], - [ 'foo', 'two', 2, 4 ], - [ 'bar', 'three', 4, 1 ], - [ 'foo', 'two', 5, 5 ], - [ 'bar', 'two', 2, 6 ], - [ 'foo', 'one', 6, 7 ], - [ 'foo', 'three', 7, 8 ] - ], - column_name: [ 'A', 'B', 'C', 'D' ], - data_tensors: { - foo: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - }, - bar: DataFrame { - kwargs: [Object], - series: false, - data: [Array], - row_data_tensor: [Tensor], - index_arr: [Array], - columns: [Array], - col_data: [Array], - col_data_tensor: [Tensor], - col_types: [Array], - A: [Getter/Setter], - B: [Getter/Setter], - C: [Getter/Setter], - D: [Getter/Setter] - } - }, - group_col_name: [ 'C' ], - group_col: { foo: [ [Series] ], bar: [ [Series] ] } -} +// select single column C + +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 6 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 7 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 4 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +// select multiple column: B and D + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 5 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ one │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + ``` diff --git a/api-reference/groupby/groupby.count.md b/api-reference/groupby/groupby.count.md index 36733be..020893b 100644 --- a/api-reference/groupby/groupby.count.md +++ b/api-reference/groupby/groupby.count.md @@ -12,7 +12,7 @@ description: Count the occurrence of values in columns per groups **Examples** -Obtain the variance of a column for each group, group by one column +Obtain the number of rows per groups {% tabs %} {% tab title="Node" %} @@ -20,27 +20,26 @@ Obtain the variance of a column for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).count().print() +let grpColumnC = grp.col(["C"]) +grpColumnC.count().print() ``` {% endtab %} {% endtabs %} ``` - Shape: (2,2) - ╔═══╤═══════════════════╤═══════════════════╗ ║ │ A │ C_count ║ ╟───┼───────────────────┼───────────────────╢ @@ -50,7 +49,7 @@ grp.col(["C"]).count().print() ╚═══╧═══════════════════╧═══════════════════╝ ``` -Obtain the var for two columns for each group, group by one column +Obtain the count for two columns for each group, group by one column {% tabs %} {% tab title="Node" %} @@ -58,17 +57,18 @@ Obtain the var for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) + grp.col(["C","D"]).count().print() ``` {% endtab %} @@ -86,6 +86,42 @@ grp.col(["C","D"]).count().print() ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` +Obtain the count for all columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) + +grp.count().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B_count │ C_count │ D_count ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 │ 5 │ 5 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 │ 3 │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + Obtain the count for a column for each group, group by two columns {% tabs %} @@ -94,13 +130,13 @@ Obtain the count for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -112,21 +148,23 @@ grp.col(["C"]).count().print() {% endtabs %} ``` - Shape: (5,3) -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` Obtain the count for two columns for each group, group by two columns @@ -137,13 +175,13 @@ Obtain the count for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -154,22 +192,23 @@ grp.col(["C","D"]).count().print() {% endtabs %} ``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_count │ D_count ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 1 │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 1 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_count │ D_count ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 1 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 1 │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` **** diff --git a/api-reference/groupby/groupby.cummax.md b/api-reference/groupby/groupby.cummax.md index 8231a61..38f6aee 100644 --- a/api-reference/groupby/groupby.cummax.md +++ b/api-reference/groupby/groupby.cummax.md @@ -2,9 +2,9 @@ description: Obtain the cummulative max per groups for each column --- -# Groupby.cummax +# Groupby.cumMax -> danfo.Groupby.cummax\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L285)\] +> danfo.Groupby.cumMax\(\) \[[source](https://github.com/javascriptdata/danfojs/blob/4993242be7847ba7583dd40ed0188929898b8fd6/src/danfojs-base/aggregators/groupby.ts#L481)\] **Parameters**: None @@ -20,19 +20,19 @@ Obtain the cumulative max of a column for each groups, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() +grp.col(["C"]).cumMax().head().print() +grp.col(["C"]).cumMax().tail().print() ``` {% endtab %} {% endtabs %} @@ -81,19 +81,19 @@ Obtain the cumsum for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() +grp.col(["C","D"]).cumMax().head().print() +grp.col(["C","D"]).cumMax().tail().print() ``` {% endtab %} {% endtabs %} @@ -142,19 +142,19 @@ Obtain the cummax for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummax().head().print() -grp.col(["C"]).cummax().tail().print() +grp.col(["C"]).cumMax().head().print() +grp.col(["C"]).cumMax().tail().print() ``` {% endtab %} @@ -214,8 +214,8 @@ let data ={'A': ['foo', 'bar', 'foo', 'bar', let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummax().head().print() -grp.col(["C","D"]).cummax().tail().print() +grp.col(["C","D"]).cumMax().head().print() +grp.col(["C","D"]).cumMax().tail().print() ``` {% endtab %} {% endtabs %} diff --git a/api-reference/groupby/groupby.cummin.md b/api-reference/groupby/groupby.cummin.md index 7fd9ed6..1b569fa 100644 --- a/api-reference/groupby/groupby.cummin.md +++ b/api-reference/groupby/groupby.cummin.md @@ -2,9 +2,9 @@ description: Obtain the cummulative minimum per groups for each column --- -# Groupby.cummin +# Groupby.cumMin -> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)\] +> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/javascriptdata/danfojs/blob/4993242be7847ba7583dd40ed0188929898b8fd6/src/danfojs-base/aggregators/groupby.ts#L497)\] **Parameters**: None @@ -20,19 +20,21 @@ Obtain the cumulative min of a column for each groups, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() +let grpColC = grp.col(["C"]) +grpColC.cumMin().head().print() +grpColC.cumMin().tail().print() + ``` {% endtab %} {% endtabs %} @@ -81,19 +83,20 @@ Obtain the cummin for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() +let grpCol = grp.col("C","D"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() ``` {% endtab %} {% endtabs %} @@ -142,19 +145,20 @@ Obtain the cummin for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() +let grpCol = grp.col(["C"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() ``` {% endtab %} @@ -203,19 +207,20 @@ Obtain the cummin for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() +let grpCol = grp.col(["C","D"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() ``` {% endtab %} {% endtabs %} From 28f9c9d0fae507ac70f735c7aadb61cac789f5c0 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 16 Jan 2022 12:52:31 +0100 Subject: [PATCH 165/202] Update package version number --- .../dataframe/creating-a-dataframe.md | 8 ++-- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +- .../input-output/danfo.read_excel.md | 4 +- api-reference/input-output/danfo.read_json.md | 4 +- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +- api-reference/plotting/histograms.md | 2 +- api-reference/plotting/line-charts.md | 6 +-- api-reference/plotting/pie-charts.md | 4 +- api-reference/plotting/scatter-plots.md | 4 +- api-reference/plotting/violin-plots.md | 4 +- api-reference/series/creating-a-series.md | 4 +- getting-started.md | 37 ++++++++++--------- release-notes.md | 2 +- 17 files changed, 48 insertions(+), 47 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index e740d1c..c58eb9e 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -40,7 +40,7 @@ df.print() - Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index b0ce43f..84e5946 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 6b570f5..91899d1 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 932b4b8..de61b55 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 402e533..0607420 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index ab6df99..9e67522 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index d6d41a6..ee9172e 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index bb79f1f..75a5b50 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index d02452b..5f2d02c 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index b1a1ed7..4468bcd 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index d94edc2..a792395 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 5fc7981..6d330f9 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 856fc43..561a333 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 356342a..861df13 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index 82bd9a7..1c97f23 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index bf802c6..583cabd 100644 --- a/getting-started.md +++ b/getting-started.md @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,8 @@ df.print() - Document + +Document @@ -290,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -368,7 +369,7 @@ df.print() - Document + Document @@ -459,7 +460,7 @@ df.print() - Document + Document @@ -567,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -652,7 +653,7 @@ df.tensor.print() - Document + Document @@ -732,7 +733,7 @@ df.describe().print() - Document + Document @@ -805,7 +806,7 @@ df.print() - Document + Document @@ -875,7 +876,7 @@ df['A'].print() - Document + Document @@ -1292,7 +1293,7 @@ df.print() - Document + Document @@ -1381,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1599,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2223,7 +2224,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2275,7 +2276,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2370,7 +2371,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 4998447..f1dd98e 100644 --- a/release-notes.md +++ b/release-notes.md @@ -122,7 +122,7 @@ A simple example: - + Document From fc4dc2e13e139e53c789842a2fa3e0f077fdf7d9 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 16 Jan 2022 13:04:02 +0100 Subject: [PATCH 166/202] Updated getting started --- getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started.md b/getting-started.md index 583cabd..016d9cc 100644 --- a/getting-started.md +++ b/getting-started.md @@ -9,7 +9,7 @@ description: >- {% hint style="info" %} A stable version of Danfojs (v1), has been released, and it comes with full Typescript support, new features, and many bug fixes. See release note [here](release-notes.md#latest-release-node-v1.0.0-browser-v1.0.0). -There are a couple of breaking changes, so we have prepared a short migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1.0.0 users. +There are a couple of breaking changes, so we have prepared a short migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1.0.1 users. {% endhint %} ## Installation From 1ce2b8d5f32d0f94dc0206666080401933c16352 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 16 Jan 2022 12:10:06 +0000 Subject: [PATCH 167/202] GitBook: [#215] No subject --- getting-started.md | 23 ++++++----------------- release-notes.md | 14 +++++++++++++- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/getting-started.md b/getting-started.md index 016d9cc..432d86f 100644 --- a/getting-started.md +++ b/getting-started.md @@ -7,9 +7,9 @@ description: >- # Getting Started {% hint style="info" %} -A stable version of Danfojs (v1), has been released, and it comes with full Typescript support, new features, and many bug fixes. See release note [here](release-notes.md#latest-release-node-v1.0.0-browser-v1.0.0). +A stable version of Danfojs (v1), has been released, and it comes with full Typescript support, new features, and many bug fixes. See release note [here](release-notes.md#latest-release-node-v1.0.0-browser-v1.0.0). -There are a couple of breaking changes, so we have prepared a short migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1.0.1 users. +There are a couple of breaking changes, so we have prepared a short migration [guide](examples/migrating-to-the-stable-version-of-danfo.js.md) for pre-v1 users. {% endhint %} ## Installation @@ -39,11 +39,11 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): ```markup - + ``` {% hint style="info" %} -To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) or the [VS-Code Nodejs notebook extension](https://marketplace.visualstudio.com/items?itemName=donjayamanne.typescript-notebook). +To play with Danfo.js in a Notebook-like environment, see [Dnotebooks](https://dnotebook.jsdata.org/getting-started) [here](https://playnotebook.jsdata.org/demo) or the [VS-Code Nodejs notebook extension](https://marketplace.visualstudio.com/items?itemName=donjayamanne.typescript-notebook). {% endhint %} ## 10 minutes to danfo.js @@ -1885,7 +1885,6 @@ com_df.print() ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 3 │ K2 │ K2 │ A3 │ B3 │ K2 │ K0 │ C3 │ D3 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` Concatenate along row axis (0). @@ -2203,20 +2202,10 @@ sf.dt.dayOfWeekName().print() See the [Plotting](api-reference/plotting/) docs. -We currently support [Plotly.js](https://plotly.com/javascript/) for plotting. In the future, we plan other JS plotting libraries like Vega, D3. +We currently support [Plotly.js](https://plotly.com/javascript/) for plotting. In the future, we plan other JS plotting libraries like Vega, D3. Using the `plot` API, you can make interactive plots from DataFrame and Series. Plotting only works in the browser/client-side version of Danfo.js, and requires an HTML div to display plots. -{% tabs %} -{% tab title="Browser" %} - -{% endtab %} - -{% tab title="Second Tab" %} - -{% endtab %} -{% endtabs %} - ```markup @@ -2303,7 +2292,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe [Writing to a CSV file.](api-reference/dataframe/dataframe.to\_csv.md) -Convert any DataFrame to csv format. +Convert any DataFrame to csv format. In NodeJs, if a file path is specified, then the CSV is saved to the path, else it is returned as a string. diff --git a/release-notes.md b/release-notes.md index f1dd98e..dc63e48 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,18 @@ # Release Notes -### \[LATEST] Release Node (v1.0.0), Browser (v1.0.0) +### \[LATEST] Release Node (v1.0.1), Browser (v1.0.1) + +**Date:** 16th Jan 2022 + +Minor bug fixes + +* [https://github.com/javascriptdata/danfojs/issues/354](https://github.com/javascriptdata/danfojs/issues/354) +* [https://github.com/javascriptdata/danfojs/issues/344](https://github.com/javascriptdata/danfojs/issues/344) +* [https://github.com/javascriptdata/danfojs/pull/347](https://github.com/javascriptdata/danfojs/pull/347) + +Contributors: @[**Devwulf**](https://github.com/Devwulf)**,** [@risenW](https://github.com/risenW) + +### Release Node (v1.0.0), Browser (v1.0.0) **Date:** 12th Jan 2022 From ebebc0fdd41658dea823d0de07db922bdd814bf7 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 16 Jan 2022 12:10:58 +0000 Subject: [PATCH 168/202] GitBook: [#216] No subject --- ...ating-to-the-stable-version-of-danfo.js.md | 41 ++++--------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/examples/migrating-to-the-stable-version-of-danfo.js.md b/examples/migrating-to-the-stable-version-of-danfo.js.md index 07c8206..c186782 100644 --- a/examples/migrating-to-the-stable-version-of-danfo.js.md +++ b/examples/migrating-to-the-stable-version-of-danfo.js.md @@ -10,13 +10,11 @@ We recently released the first stable version of Danfo.js. See release note here The following list summarizes some of these updates: -* **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increases the developer experience. -* **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. -* Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. +* **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increase the developer experience. +* **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. +* Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. * **New features**: We added lots of new features which users have been requesting for. For example: * Stream and process large CSV data - * Read JSON objects with key support - * Date time is now a first-class data type. * General bug fixes and improvements * Better error messages @@ -34,7 +32,7 @@ to_json ==> toCSV drop_duplicates ==> dropDuplicates ``` -**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. +**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. ### Functions and Methods argument structure @@ -42,7 +40,7 @@ Another major breaking change of v1, is that the structure of arguments/paramete In general, it is important to understand our thought process behind this, so, here goes: -Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: +Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: ``` rename( { mapper, axis, inplace } ) => DataFrame @@ -54,10 +52,10 @@ The structure above combines both required and optional arguments as a single ob rename(mapper, options: {axis, inplace}) //where mapper is required, and options argument is optional. ``` -Re-designing functions and methods to follow this intuitive format is the bulk of the breaking change in this new version, as such, when migrating, you have to make these updates. +Re-designing functions and methods to follow this intuitive format is the bulk of the breaking change in this new version, as such, when migrating, you have to make these updates. {% hint style="info" %} -If using Typescript, then the TS compiler will help in migration, else, you have to manually identify and update your function/method signature. +If using Typescript, then the TS compiler will help in migration, else, you have to manually identify and update your function/method signature. {% endhint %} ### Axis Order @@ -65,28 +63,7 @@ If using Typescript, then the TS compiler will help in migration, else, you have In this new version, we have flipped the result of the axis ordering for all operations. This ordering is now consistent with Pandas and Tensorflow.js. That is, the axis row (0), represents the operations carried out horizontally on a DataFrame, and the axis columns (1) represent operations carried out vertically down the DataFrame. {% hint style="info" %} -In short, when migrating to the new version, you should flip the axis number so as to get the same result. That is, change all `axis: 0` to `axis: 1`, to get the same result. +In short, when migrating to the new version, you should flip the axis number so as to get the same result. That is, change all `axis: 0` to `axis: 1`, to get the same result. {% endhint %} -All examples in this doc have been updated to reflect this update. - - - - - - - - - - - - - - - - - - - - - +All examples in this doc have been updated to reflect this update. From bf7505d0c2c84cb6d9dc1140da481054bf7b8d66 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 19 Jan 2022 14:50:11 +0100 Subject: [PATCH 169/202] Add new release note --- .../dataframe/creating-a-dataframe.md | 8 ++-- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +- .../input-output/danfo.read_excel.md | 4 +- api-reference/input-output/danfo.read_json.md | 4 +- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +- api-reference/plotting/histograms.md | 2 +- api-reference/plotting/line-charts.md | 6 +-- api-reference/plotting/pie-charts.md | 4 +- api-reference/plotting/scatter-plots.md | 4 +- api-reference/plotting/violin-plots.md | 4 +- api-reference/series/creating-a-series.md | 4 +- getting-started.md | 38 +++++++++---------- release-notes.md | 14 ++++++- 17 files changed, 59 insertions(+), 49 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index c58eb9e..989efe5 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -40,7 +40,7 @@ df.print() - Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 84e5946..bf824df 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 91899d1..1441bd1 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index de61b55..d8f9955 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 0607420..f966c10 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 9e67522..627dfdb 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index ee9172e..090526a 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 75a5b50..dd690d7 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index 5f2d02c..a39ecbf 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 4468bcd..181b055 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index a792395..3c8ceaa 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 6d330f9..4515a43 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 561a333..1b53f6a 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 861df13..fe04a29 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index 1c97f23..bc7c71a 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index 432d86f..2d6eb0c 100644 --- a/getting-started.md +++ b/getting-started.md @@ -39,7 +39,7 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): ```markup - + ``` {% hint style="info" %} @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - + Document @@ -291,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -369,7 +369,7 @@ df.print() - Document + Document @@ -460,7 +460,7 @@ df.print() - Document + Document @@ -568,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -653,7 +653,7 @@ df.tensor.print() - Document + Document @@ -733,7 +733,7 @@ df.describe().print() - Document + Document @@ -806,7 +806,7 @@ df.print() - Document + Document @@ -876,7 +876,7 @@ df['A'].print() - Document + Document @@ -1293,7 +1293,7 @@ df.print() - Document + Document @@ -1382,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1600,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2213,7 +2213,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2265,7 +2265,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2360,7 +2360,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index dc63e48..ff5907d 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,16 @@ # Release Notes -### \[LATEST] Release Node (v1.0.1), Browser (v1.0.1) +### \[LATEST] Release Node (v1.0.2), Browser (v1.0.2) +**Date:** 19th Jan 2022 + +#### What's Changed +* Update TensorFlow version to fix M1 chip incompatibility by @risenW in https://github.com/javascriptdata/danfojs/pull/358 +* Add new feature `iat` and `at` by @risenW in https://github.com/javascriptdata/danfojs/pull/359 +* Fixed issue with sort by values by @risenW in https://github.com/javascriptdata/danfojs/pull/360 + + +**Full Changelog**: https://github.com/javascriptdata/danfojs/compare/v1.0.1...v1.0.2 +### Release Node (v1.0.1), Browser (v1.0.1) **Date:** 16th Jan 2022 @@ -134,7 +144,7 @@ A simple example: - + Document From 1c2df0e07af2c39350e6146cfc9f1918ff082e9f Mon Sep 17 00:00:00 2001 From: Stephen Oni Date: Sat, 22 Jan 2022 06:22:08 +0100 Subject: [PATCH 170/202] update groupby doc --- api-reference/groupby/groupby.apply.md | 2 +- .../{groupby.cummin.md => groupby.cumMin.md} | 0 api-reference/groupby/groupby.cumProd.md | 221 +++++++++++++++ api-reference/groupby/groupby.cumSum.md | 200 ++++++++++++++ api-reference/groupby/groupby.cumprod.md | 258 ----------------- api-reference/groupby/groupby.cumsum.md | 259 ------------------ api-reference/groupby/groupby.first.md | 89 ++++++ ...upby.get_groups.md => groupby.getGroup.md} | 34 +-- api-reference/groupby/groupby.groups.md | 99 +++++++ api-reference/groupby/groupby.last.md | 87 ++++++ api-reference/groupby/groupby.max.md | 42 +-- api-reference/groupby/groupby.mean.md | 44 ++- api-reference/groupby/groupby.min.md | 109 ++++---- api-reference/groupby/groupby.ngroups.md | 69 +++++ api-reference/groupby/groupby.size.md | 87 ++++++ api-reference/groupby/groupby.std.md | 44 ++- api-reference/groupby/groupby.sum.md | 80 +++--- api-reference/groupby/groupby.var.md | 43 ++- 18 files changed, 1041 insertions(+), 726 deletions(-) rename api-reference/groupby/{groupby.cummin.md => groupby.cumMin.md} (100%) create mode 100644 api-reference/groupby/groupby.cumProd.md create mode 100644 api-reference/groupby/groupby.cumSum.md delete mode 100644 api-reference/groupby/groupby.cumprod.md delete mode 100644 api-reference/groupby/groupby.cumsum.md create mode 100644 api-reference/groupby/groupby.first.md rename api-reference/groupby/{groupby.get_groups.md => groupby.getGroup.md} (91%) create mode 100644 api-reference/groupby/groupby.groups.md create mode 100644 api-reference/groupby/groupby.last.md create mode 100644 api-reference/groupby/groupby.ngroups.md create mode 100644 api-reference/groupby/groupby.size.md diff --git a/api-reference/groupby/groupby.apply.md b/api-reference/groupby/groupby.apply.md index 0fc1595..9e01b0e 100644 --- a/api-reference/groupby/groupby.apply.md +++ b/api-reference/groupby/groupby.apply.md @@ -4,7 +4,7 @@ description: Apply custom aggregate function to grouped data # Groupby.apply -danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs-node/src/core/groupby.js#L297)\] +danfo.Groupby.**apply**\(callable\) \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L552)\] | Parameters | Type | Description | Default | | :--- | :--- | :--- | :--- | diff --git a/api-reference/groupby/groupby.cummin.md b/api-reference/groupby/groupby.cumMin.md similarity index 100% rename from api-reference/groupby/groupby.cummin.md rename to api-reference/groupby/groupby.cumMin.md diff --git a/api-reference/groupby/groupby.cumProd.md b/api-reference/groupby/groupby.cumProd.md new file mode 100644 index 0000000..e47444c --- /dev/null +++ b/api-reference/groupby/groupby.cumProd.md @@ -0,0 +1,221 @@ +--- +description: Obtain the cumulative product per group for each column +--- + +# Groupby.cumProd + +> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/javascriptdata/danfojs/blob/65f9b3753389b08101d4bb00a2d6488255476aaf/src/danfojs-base/aggregators/groupby.ts#L489)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative product of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +let grpCol = grp.col(["C"]) +grpCol.cumProd().head().print() +grpCol.cumProd().tail().print() +``` +{% endtab %} +{% endtabs %} + +```text + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +let grpCol = grp.col(["C","D"]) +grpCol.cumProd().print() +``` +{% endtab %} +{% endtabs %} + +```text + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 12 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 │ 60 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 │ 420 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 │ 3360 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +let grpCol = grp.col(["C"]) +grpCol.cumProd().print() + +``` +{% endtab %} +{% endtabs %} + +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +let grpCol = grp.col(["C","D"]) +grpCol.cumProd().print() +``` +{% endtab %} +{% endtabs %} + +```text + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 21 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + diff --git a/api-reference/groupby/groupby.cumSum.md b/api-reference/groupby/groupby.cumSum.md new file mode 100644 index 0000000..2df6516 --- /dev/null +++ b/api-reference/groupby/groupby.cumSum.md @@ -0,0 +1,200 @@ +--- +description: Obtain the cumulative sum per groups for each column +--- + +# Groupby.cumsum + +> danfo.Groupby.**cumsum**() \[[source](https://github.com/javascriptdata/danfojs/blob/0d33e344b80a3ed54c91c9393ac3b583d4b0b1a4/src/danfojs-base/aggregators/groupby.ts#L473)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative sum of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumSum().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumSum().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 │ 12 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 │ 19 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 │ 27 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 │ 9 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumSum().print() + +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumSum().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** diff --git a/api-reference/groupby/groupby.cumprod.md b/api-reference/groupby/groupby.cumprod.md deleted file mode 100644 index af46123..0000000 --- a/api-reference/groupby/groupby.cumprod.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -description: Obtain the cumulative product per group for each column ---- - -# Groupby.cumprod - -> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)\] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative product of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 12 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 24 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - -Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 │ 420 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 │ 3360 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 24 │ 12 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 24 │ 12 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() - -``` -{% endtab %} -{% endtabs %} - -```text - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumprod for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() -``` -{% endtab %} -{% endtabs %} - -```text - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 21 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - diff --git a/api-reference/groupby/groupby.cumsum.md b/api-reference/groupby/groupby.cumsum.md deleted file mode 100644 index 3b2b0e6..0000000 --- a/api-reference/groupby/groupby.cumsum.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -description: Obtain the cumulative sum per groups for each column ---- - -# Groupby.cumsum - -> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] - -**Parameters**: None - -**Return**: DataFrame - -**Examples** - -Obtain the cumulative sum of a column for each groups, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for two columns for each group, group by one column - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 │ 19 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 │ 27 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 9 │ 9 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 9 │ 9 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the cumsum for a column for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() - -``` -{% endtab %} -{% endtabs %} - -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -Obtain the count for two columns for each group, group by two columns - -{% tabs %} -{% tab title="Node" %} -```javascript -const dfd = require("danfojs-node") - - -let data ={'A': ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } - -let df = new dfd.DataFrame(data) - -let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() -``` -{% endtab %} -{% endtabs %} - -``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` - -**** diff --git a/api-reference/groupby/groupby.first.md b/api-reference/groupby/groupby.first.md new file mode 100644 index 0000000..b1bcd26 --- /dev/null +++ b/api-reference/groupby/groupby.first.md @@ -0,0 +1,89 @@ +--- +description: Obtain the first row of each groups +--- + +# Groupby.first + +> danfo.Groupby.first \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L615)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the first row of each group for dataframe grouped by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +grp.first().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ bar │ one │ 3 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the number of groups in dataframe grouped by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A","B"]) +grp.first().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ B_Group │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** \ No newline at end of file diff --git a/api-reference/groupby/groupby.get_groups.md b/api-reference/groupby/groupby.getGroup.md similarity index 91% rename from api-reference/groupby/groupby.get_groups.md rename to api-reference/groupby/groupby.getGroup.md index 0cdf912..cecf8dc 100644 --- a/api-reference/groupby/groupby.get_groups.md +++ b/api-reference/groupby/groupby.getGroup.md @@ -2,9 +2,9 @@ description: Obtain the data for each element of the groupby column --- -# Groupby.get\_groups +# Groupby.getGroup -> danfo.Groupby.get\_groups\(key\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)\] +> danfo.Groupby.getGroup(key\) \[[source](https://github.com/javascriptdata/danfojs/blob/0d33e344b80a3ed54c91c9393ac3b583d4b0b1a4/src/danfojs-base/aggregators/groupby.ts#L523)\] | Parameters | Type | Description | default | | :--- | :--- | :--- | :--- | @@ -21,22 +21,22 @@ Group the dataframe by column A and obtain the group belonging to the values in ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.get_groups(["foo"]).print() +grp.getGroup(["foo"]).print() -grp.get_groups(["bar"]).print() +grp.getGroup(["bar"]).print() ``` {% endtab %} {% endtabs %} @@ -81,22 +81,22 @@ Group dataframe by two columns and obtain their groups. Since the dataframe is g ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.get_groups(["foo","one"]).print() +grp.getGroup(["foo","one"]).print() -grp.get_groups(["bar","one"]).print() +grp.getGroup(["bar","one"]).print() ``` {% endtab %} {% endtabs %} @@ -115,7 +115,7 @@ grp.get_groups(["bar","one"]).print() ║ 1 │ foo │ one │ 6 │ 7 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -//get_groups(["bar","one"]) +//getGroup(["bar","one"]) Shape: (1,4) diff --git a/api-reference/groupby/groupby.groups.md b/api-reference/groupby/groupby.groups.md new file mode 100644 index 0000000..a6208b3 --- /dev/null +++ b/api-reference/groupby/groupby.groups.md @@ -0,0 +1,99 @@ +--- +description: Obtain groupby internal data object +--- + +# Groupby.ngroups + +> danfo.Groupby.groups \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L598)\] + +**Parameters**: None + +**Return**: Object + +**Examples** + +Obtain the group object for grouped by single column dataframe + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +console.log(grp.groups) +``` +{% endtab %} +{% endtabs %} + +``` +{ + foo: { + A: [ 'foo', 'foo', 'foo', 'foo', 'foo' ], + B: [ 'one', 'two', 'two', 'one', 'three' ], + C: [ 1, 2, 5, 6, 7 ], + D: [ 3, 4, 5, 7, 8 ] + }, + bar: { + A: [ 'bar', 'bar', 'bar' ], + B: [ 'one', 'three', 'two' ], + C: [ 3, 4, 2 ], + D: [ 2, 1, 6 ] + } +} +``` + +Obtain the group object for grouped by two column dataframe + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A","B"]) +console.log(grp.groups) +``` +{% endtab %} +{% endtabs %} + +``` +{ + 'foo-one': { + A: [ 'foo', 'foo' ], + B: [ 'one', 'one' ], + C: [ 1, 6 ], + D: [ 3, 7 ] + }, + 'bar-one': { A: [ 'bar' ], B: [ 'one' ], C: [ 3 ], D: [ 2 ] }, + 'foo-two': { + A: [ 'foo', 'foo' ], + B: [ 'two', 'two' ], + C: [ 2, 5 ], + D: [ 4, 5 ] + }, + 'bar-three': { A: [ 'bar' ], B: [ 'three' ], C: [ 4 ], D: [ 1 ] }, + 'bar-two': { A: [ 'bar' ], B: [ 'two' ], C: [ 2 ], D: [ 6 ] }, + 'foo-three': { A: [ 'foo' ], B: [ 'three' ], C: [ 7 ], D: [ 8 ] } +} +``` + +**** \ No newline at end of file diff --git a/api-reference/groupby/groupby.last.md b/api-reference/groupby/groupby.last.md new file mode 100644 index 0000000..51174bf --- /dev/null +++ b/api-reference/groupby/groupby.last.md @@ -0,0 +1,87 @@ +--- +description: Obtain the last row of each groups +--- + +# Groupby.last + +> danfo.Groupby.last \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L625)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the last row of each group for dataframe grouped by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A"]) +grp.last().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the number of groups in dataframe grouped by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A","B"]) +grp.last().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ B_Group │ A │ B │ C │ D ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ foo │ one │ 6 │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ foo │ two │ 5 │ 5 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** \ No newline at end of file diff --git a/api-reference/groupby/groupby.max.md b/api-reference/groupby/groupby.max.md index 43470f6..98c2c55 100644 --- a/api-reference/groupby/groupby.max.md +++ b/api-reference/groupby/groupby.max.md @@ -4,7 +4,7 @@ description: Obtain the maximum value of columns per groups # Groupby.max -> danfo.Groupby.max() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L309)] +> danfo.Groupby.max() \[[source](https://github.com/javascriptdata/danfojs/blob/0d33e344b80a3ed54c91c9393ac3b583d4b0b1a4/src/danfojs-base/aggregators/groupby.ts#L506)] **Parameters:** None @@ -19,13 +19,13 @@ Obtain the maximum value for a column for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -56,13 +56,13 @@ Obtain the maximum value for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -92,13 +92,13 @@ Obtain the maximum value for a column for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -134,13 +134,13 @@ Obtain the maximum value for two columns for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) diff --git a/api-reference/groupby/groupby.mean.md b/api-reference/groupby/groupby.mean.md index add6958..c411bba 100644 --- a/api-reference/groupby/groupby.mean.md +++ b/api-reference/groupby/groupby.mean.md @@ -4,7 +4,7 @@ description: Obtain the mean per groups for each column(s) # Groupby.mean -> danfo.Series.mean() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L274)] +> danfo.Series.mean() \[[source](https://github.com/javascriptdata/danfojs/blob/0d33e344b80a3ed54c91c9393ac3b583d4b0b1a4/src/danfojs-base/aggregators/groupby.ts#L464)] **Parameters**: None @@ -19,13 +19,13 @@ Obtain the mean of a column for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -57,13 +57,13 @@ Obtain the mean for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -93,13 +93,13 @@ Obtain the mean for a column for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -135,17 +135,15 @@ Obtain the mean for two columns for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - - let grp = df.groupby(["A","B"]) grp.col(["C","D"]).mean().print() ``` diff --git a/api-reference/groupby/groupby.min.md b/api-reference/groupby/groupby.min.md index 0151e64..f74be86 100644 --- a/api-reference/groupby/groupby.min.md +++ b/api-reference/groupby/groupby.min.md @@ -4,7 +4,7 @@ description: Obtain the minimum value per groups for a coumn(s) # Groupby.min -> danfo.Groupby.min() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L315)] +> danfo.Groupby.min() \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L514)] **Parameters**: None @@ -19,17 +19,16 @@ Obtain the minimum value for a column for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A"]) grp.col(["C"]).min().print() ``` @@ -55,17 +54,15 @@ Obtain the minimum value for two columns for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - - let grp = df.groupby(["A"]) grp.col(["C","D"]).min().print() ``` @@ -91,17 +88,15 @@ Obtain the maximum value for a column for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - - let grp = df.groupby(["A","B"]) grp.col(["C"]).min().print() ``` @@ -109,21 +104,21 @@ grp.col(["C"]).min().print() {% endtabs %} ``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Obtain the maximum value for two columns for each group, group by two columns @@ -133,17 +128,15 @@ Obtain the maximum value for two columns for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - - let grp = df.groupby(["A","B"]) grp.col(["C","D"]).min().print() ``` @@ -151,21 +144,21 @@ grp.col(["C","D"]).min().print() {% endtabs %} ``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_min │ D_min ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_min │ D_min ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` **** diff --git a/api-reference/groupby/groupby.ngroups.md b/api-reference/groupby/groupby.ngroups.md new file mode 100644 index 0000000..951c0d7 --- /dev/null +++ b/api-reference/groupby/groupby.ngroups.md @@ -0,0 +1,69 @@ +--- +description: Obtain the number of groups +--- + +# Groupby.ngroups + +> danfo.Groupby.ngroups \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L598)\] + +**Parameters**: None + +**Return**: Number + +**Examples** + +Obtain the number of groups in a dataframe grouped by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) +console.log(grp.ngroups) +``` +{% endtab %} +{% endtabs %} + +``` +2 +``` + +Obtain the number of groups in dataframe grouped by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A","B"]) +console.log(grp.ngroups) +``` +{% endtab %} +{% endtabs %} + +``` +6 +``` + +**** \ No newline at end of file diff --git a/api-reference/groupby/groupby.size.md b/api-reference/groupby/groupby.size.md new file mode 100644 index 0000000..a4ae97a --- /dev/null +++ b/api-reference/groupby/groupby.size.md @@ -0,0 +1,87 @@ +--- +description: Obtain the last row of each groups +--- + +# Groupby.last + +> danfo.Groupby.last \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L635)\] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the size of each group for dataframe grouped by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A"]) +grp.size().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ applyOps ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 5 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ 3 ║ +╚════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the size of each group in dataframe grouped by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={A: ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + B: ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} + +let df = new dfd.DataFrame(data) +let grp = df.groupby(["A","B"]) +grp.size().print() +``` +{% endtab %} +{% endtabs %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A_Group │ B_Group │ applyOps ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +**** \ No newline at end of file diff --git a/api-reference/groupby/groupby.std.md b/api-reference/groupby/groupby.std.md index c792a8e..f0d1516 100644 --- a/api-reference/groupby/groupby.std.md +++ b/api-reference/groupby/groupby.std.md @@ -4,7 +4,7 @@ description: Obtain the standard deviation per groups for specified columns # Groupby.std -> danfo.Groupby.**std**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L262)] +> danfo.Groupby.**std**() \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L448)] **Parameters**: None @@ -20,17 +20,15 @@ Obtain the standard deviation of a column for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - - let grp = df.groupby(["A"]) grp.col(["C"]).std().print() ``` @@ -58,13 +56,13 @@ Obtain the std for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -94,13 +92,13 @@ Obtain the std for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -137,13 +135,13 @@ Obtain the std for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) diff --git a/api-reference/groupby/groupby.sum.md b/api-reference/groupby/groupby.sum.md index f6f2900..6ad83df 100644 --- a/api-reference/groupby/groupby.sum.md +++ b/api-reference/groupby/groupby.sum.md @@ -4,7 +4,7 @@ description: Obtain the sum per groups for columns # Groupby.sum -> danfo.Groupby.sum() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L256)] +> danfo.Groupby.sum() \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L440)] **Parameters**: None @@ -19,17 +19,16 @@ Obtain the sum of a column for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A"]) grp.col(["C"]).sum().print() ``` @@ -38,8 +37,6 @@ grp.col(["C"]).sum().print() ``` - Shape: (2,2) - ╔═══╤═══════════════════╤═══════════════════╗ ║ │ A │ C_sum ║ ╟───┼───────────────────┼───────────────────╢ @@ -56,17 +53,16 @@ Obtain the sum for two columns for each group, group by one column ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A"]) grp.col(["C","D"]).sum().print() ``` @@ -74,8 +70,6 @@ grp.col(["C","D"]).sum().print() {% endtabs %} ``` - Shape: (2,3) - ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ C_sum │ D_sum ║ ╟───┼───────────────────┼───────────────────┼───────────────────╢ @@ -92,17 +86,16 @@ Obtain the sum for a column for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A","B"]) grp.col(["C"]).sum().print() ``` @@ -134,17 +127,16 @@ Obtain the sum for two columns for each group, group by two columns ```javascript const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A","B"]) grp.col(["C","D"]).sum().print() ``` @@ -152,21 +144,21 @@ grp.col(["C","D"]).sum().print() {% endtabs %} ``` - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_sum │ D_sum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ bar │ two │ 2 │ 6 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_sum │ D_sum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 7 │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` **** diff --git a/api-reference/groupby/groupby.var.md b/api-reference/groupby/groupby.var.md index 373109f..08a9d97 100644 --- a/api-reference/groupby/groupby.var.md +++ b/api-reference/groupby/groupby.var.md @@ -4,7 +4,7 @@ description: Obtain the variance per groups for a specified column # Groupby.var -> danfo.Groupby.**var**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L268)] +> danfo.Groupby.**var**() \[[source](https://github.com/javascriptdata/danfojs/blob/9bfda6dcb6b2b620591ec7b3340d35e3f801c8ab/src/danfojs-base/aggregators/groupby.ts#L456)] **Parameters**: None @@ -20,17 +20,16 @@ Obtain the variance of a column for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) - let grp = df.groupby(["A"]) grp.col(["C"]).var().print() ``` @@ -58,13 +57,13 @@ Obtain the var for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -94,13 +93,13 @@ Obtain the var for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) @@ -137,13 +136,13 @@ Obtain the var for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) From aa43be1715471ba7857db76c7fbab5bf2673447a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 30 Jan 2022 11:18:59 +0000 Subject: [PATCH 171/202] GitBook: [#217] No subject --- SUMMARY.md | 4 +++ api-reference/dataframe/dataframe.at.md | 36 ++++++++++++++++++++++++ api-reference/dataframe/dataframe.iat.md | 36 ++++++++++++++++++++++++ api-reference/series/series.at.md | 31 ++++++++++++++++++++ api-reference/series/series.iat.md | 31 ++++++++++++++++++++ 5 files changed, 138 insertions(+) create mode 100644 api-reference/dataframe/dataframe.at.md create mode 100644 api-reference/dataframe/dataframe.iat.md create mode 100644 api-reference/series/series.at.md create mode 100644 api-reference/series/series.iat.md diff --git a/SUMMARY.md b/SUMMARY.md index d9a3ae2..303cc26 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -84,6 +84,8 @@ * [Series.lt](api-reference/series/series.lt.md) * [Series.iloc](api-reference/series/series.iloc.md) * [Series.loc](api-reference/series/series.loc.md) + * [Series.at](api-reference/series/series.at.md) + * [Series.iat](api-reference/series/series.iat.md) * [Series.ndim](api-reference/series/series.ndim.md) * [Series.shape](api-reference/series/series.shape.md) * [Series.dtype](api-reference/series/series.dtype.md) @@ -145,6 +147,8 @@ * [DataFrame.index](api-reference/dataframe/dataframe.index.md) * [DataFrame.loc](api-reference/dataframe/danfo.dataframe.loc.md) * [DataFrame.iloc](api-reference/dataframe/danfo.dataframe.iloc.md) + * [DataFrame.at](api-reference/dataframe/dataframe.at.md) + * [DataFrame.iat](api-reference/dataframe/dataframe.iat.md) * [DataFrame.head](api-reference/dataframe/danfo.dataframe.head.md) * [DataFrame.tail](api-reference/dataframe/danfo.dataframe.tail.md) * [DataFrame.sample](api-reference/dataframe/danfo.dataframe.sample.md) diff --git a/api-reference/dataframe/dataframe.at.md b/api-reference/dataframe/dataframe.at.md new file mode 100644 index 0000000..180413d --- /dev/null +++ b/api-reference/dataframe/dataframe.at.md @@ -0,0 +1,36 @@ +--- +description: Access a single value for a row/column label pair. +--- + +# DataFrame.at + +> danfo.DataFrame.at(row, column) + +| Parameters | Type | Description | Default | +| ---------- | -------------- | ------------------------- | ------- | +| row | Number, String | row position in the index | | +| column | String | Column position | | + +**Return:** Scalar + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: [1, "b", "c", "d"] }) +df.at(1, "Count") + +//output +21 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/dataframe/dataframe.iat.md b/api-reference/dataframe/dataframe.iat.md new file mode 100644 index 0000000..c50f4f3 --- /dev/null +++ b/api-reference/dataframe/dataframe.iat.md @@ -0,0 +1,36 @@ +--- +description: Access a single value for a row/column pair by integer position. +--- + +# DataFrame.iat + +> danfo.DataFrame.iat(row, column) + +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------- | ------- | +| row | Number | row index position | | +| column | Number | Column index position | | + +**Return:** Scalar + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data = { + "Name": ["Apples", "Mango", "Banana", "Pear"], + "Count": [21, 5, 30, 10], + "Price": [200, 300, 40, 250] +} + +let df = new dfd.DataFrame(data, { index: [1, "b", "c", "d"] }) +df.iat(1, 2) + +//output +300 +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/series/series.at.md b/api-reference/series/series.at.md new file mode 100644 index 0000000..887050c --- /dev/null +++ b/api-reference/series/series.at.md @@ -0,0 +1,31 @@ +--- +description: Access a single value for a row/column label pair. +--- + +# Series.at + +> danfo.Series.at(label) + +| Parameters | Type | Description | Default | +| ---------- | ------ | ----------------- | ------- | +| label | String | label to index by | | + +**Return:** Scalar + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series(["Apples", "Mango", "Banana", "Pear"], + { index: ["a", "b", "c", "d"] } +) + +sf.at("a") + +// "Apples" +``` +{% endtab %} +{% endtabs %} diff --git a/api-reference/series/series.iat.md b/api-reference/series/series.iat.md new file mode 100644 index 0000000..3f17e6b --- /dev/null +++ b/api-reference/series/series.iat.md @@ -0,0 +1,31 @@ +--- +description: Access a single value for a row/column pair by integer position. +--- + +# Series.iat + +> danfo.Series.iat(index) + +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------ | ------- | +| index | Number | index value | | + +**Return:** Scalar + + + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let sf = new dfd.Series(["Apples", "Mango", "Banana", "Pear"], + { index: ["a", "b", "c", "d"] } +) + +sf.iat(1) + +// "Mango" +``` +{% endtab %} +{% endtabs %} From a62526e5c23555bf88eb7177b24850f679682f5a Mon Sep 17 00:00:00 2001 From: Kit Sunde Date: Tue, 8 Mar 2022 13:19:32 +0800 Subject: [PATCH 172/202] asType takes a String not an array. --- api-reference/dataframe/dataframe.astype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-reference/dataframe/dataframe.astype.md b/api-reference/dataframe/dataframe.astype.md index 45adf39..5e0d9cd 100644 --- a/api-reference/dataframe/dataframe.astype.md +++ b/api-reference/dataframe/dataframe.astype.md @@ -8,7 +8,7 @@ danfo.DataFrame.asType(options) | Parameters | Type | Description | Default | | ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| options | Object |

{

column: Array, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | +| options | Object |

{

column: String, label/column name of column to cast

dtype: dtype to cast to. One of [string, float32, int32, boolean]

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { inplace: false } | ## **Examples** From fd87f519815fecad1fc40add9d94e7f85f795cc3 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Tue, 8 Mar 2022 08:17:40 +0000 Subject: [PATCH 173/202] GitBook: [#218] No subject --- api-reference/groupby/groupby.cummin.md | 255 +++++++++++++++++++ api-reference/groupby/groupby.cumprod.md | 255 +++++++++++++++++++ api-reference/groupby/groupby.cumsum.md | 257 ++++++++++++++++++++ api-reference/groupby/groupby.get_groups.md | 128 ++++++++++ release-notes.md | 23 +- 5 files changed, 916 insertions(+), 2 deletions(-) create mode 100644 api-reference/groupby/groupby.cummin.md create mode 100644 api-reference/groupby/groupby.cumprod.md create mode 100644 api-reference/groupby/groupby.cumsum.md create mode 100644 api-reference/groupby/groupby.get_groups.md diff --git a/api-reference/groupby/groupby.cummin.md b/api-reference/groupby/groupby.cummin.md new file mode 100644 index 0000000..5f4b026 --- /dev/null +++ b/api-reference/groupby/groupby.cummin.md @@ -0,0 +1,255 @@ +--- +description: Obtain the cummulative minimum per groups for each column +--- + +# Groupby.cummin + +> danfo.Groupby.**cummin**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative min of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 1 │ 3 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cummin │ D_cummin ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 2 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 3 │ 1 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 2 │ 1 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cummin().head().print() +grp.col(["C"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cummin for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cummin().head().print() +grp.col(["C","D"]).cummin().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cummin │ D_cummin ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference/groupby/groupby.cumprod.md b/api-reference/groupby/groupby.cumprod.md new file mode 100644 index 0000000..0c3ac81 --- /dev/null +++ b/api-reference/groupby/groupby.cumprod.md @@ -0,0 +1,255 @@ +--- +description: Obtain the cumulative product per group for each column +--- + +# Groupby.cumprod + +> danfo.Groupby.**cumprod**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative product of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + +Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 │ 60 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 │ 420 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 │ 3360 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 24 │ 12 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 12 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 24 │ 12 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumprod().head().print() +grp.col(["C"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumprod for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumprod().head().print() +grp.col(["C","D"]).cumprod().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 21 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/api-reference/groupby/groupby.cumsum.md b/api-reference/groupby/groupby.cumsum.md new file mode 100644 index 0000000..4262130 --- /dev/null +++ b/api-reference/groupby/groupby.cumsum.md @@ -0,0 +1,257 @@ +--- +description: Obtain the cumulative sum per groups for each column +--- + +# Groupby.cumsum + +> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] + +**Parameters**: None + +**Return**: DataFrame + +**Examples** + +Obtain the cumulative sum of a column for each groups, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` +Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟───┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╚═══╧═══════════════════╧═══════════════════╝ + + + Shape: (5,2) + +╔═══╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟───┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟───┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╟───┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟───┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 ║ +╟───┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 ║ +╚═══╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for two columns for each group, group by one column + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 │ 12 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 │ 19 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 │ 27 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 11 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 12 │ bar │ 9 │ 9 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 13 │ bar │ 3 │ 2 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 14 │ bar │ 7 │ 3 ║ +╟────┼───────────────────┼───────────────────┼───────────────────╢ +║ 15 │ bar │ 9 │ 9 ║ +╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the cumsum for a column for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C"]).cumsum().head().print() +grp.col(["C"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,3) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Obtain the count for two columns for each group, group by two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + +let grp = df.groupby(["A","B"]) +grp.col(["C","D"]).cumsum().head().print() +grp.col(["C","D"]).cumsum().tail().print() +``` +{% endtab %} +{% endtabs %} + +``` + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 │ 10 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + + + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ two │ 2 │ 6 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ three │ 4 │ 1 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +*** diff --git a/api-reference/groupby/groupby.get_groups.md b/api-reference/groupby/groupby.get_groups.md new file mode 100644 index 0000000..9f19971 --- /dev/null +++ b/api-reference/groupby/groupby.get_groups.md @@ -0,0 +1,128 @@ +--- +description: Obtain the data for each element of the groupby column +--- + +# Groupby.get\_groups + +> danfo.Groupby.get\_groups(key) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L313)] + +| Parameters | Type | Description | default | +| ---------- | ----- | ----------------------------- | ------- | +| key | Array | element of the groupby column | | + +**Returns**: DataFrame + +**Example** + +Group the dataframe by column A and obtain the group belonging to the values in column A + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A"]) + +grp.get_groups(["foo"]).print() + +grp.get_groups(["bar"]).print() +``` +{% endtab %} +{% endtabs %} + +``` +//get groups for key "foo" + Shape: (5,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ two │ 2 │ 4 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 5 │ 5 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ one │ 6 │ 7 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get groups for key "bar" + + Shape: (3,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ bar │ three │ 4 │ 1 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ bar │ two │ 2 │ 6 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` + +Group dataframe by two columns and obtain their groups. Since the dataframe is grouped by two columns we most specify two keys in the get\_groups belonging to these two columns + +{% tabs %} +{% tab title="Node" %} +```javascript +const dfd = require("danfojs-node") + +let data ={'A': ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B': ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C': [1,3,2,4,5,2,6,7], + 'D': [3,2,4,1,5,6,7,8] + } + +let df = new dfd.DataFrame(data) + + +let grp = df.groupby(["A","B"]) + +grp.get_groups(["foo","one"]).print() + +grp.get_groups(["bar","one"]).print() +``` +{% endtab %} +{% endtabs %} + +``` +//get_groups(["foo","one"] + + + Shape: (2,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 7 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +//get_groups(["bar","one"]) + + + Shape: (1,4) + +╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C │ D ║ +╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ bar │ one │ 3 │ 2 ║ +╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +``` diff --git a/release-notes.md b/release-notes.md index ff5907d..365c86d 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,15 +1,34 @@ # Release Notes -### \[LATEST] Release Node (v1.0.2), Browser (v1.0.2) +### \[LATEST] Release Node (v1.0.3), Browser (v1.0.3) + +**Date:** 8th March 2022 + +#### What's Changed + +* add max to list of arithmetic operations by @steveoni in https://github.com/javascriptdata/danfojs/pull/367 +* correct lenght -> length by @adamgilman in https://github.com/javascriptdata/danfojs/pull/393 +* Bug fixes by @risenW in https://github.com/javascriptdata/danfojs/pull/395 +* Fix bug in groupby checking wrong colDtype by @igonro in https://github.com/javascriptdata/danfojs/pull/398 +* fix(test): Explicit type in test allows TS to compile by @NeonSpork in https://github.com/javascriptdata/danfojs/pull/411 +* Jan kaul esmodule by @risenW in https://github.com/javascriptdata/danfojs/pull/415 + +#### Contributors: @risenW @steveoni @adamgilman @igonro @NeonSpork + +**Full Changelog**: https://github.com/javascriptdata/danfojs/compare/v1.0.2...v1.0.3 + +### Release Node (v1.0.2), Browser (v1.0.2) + **Date:** 19th Jan 2022 #### What's Changed + * Update TensorFlow version to fix M1 chip incompatibility by @risenW in https://github.com/javascriptdata/danfojs/pull/358 * Add new feature `iat` and `at` by @risenW in https://github.com/javascriptdata/danfojs/pull/359 * Fixed issue with sort by values by @risenW in https://github.com/javascriptdata/danfojs/pull/360 - **Full Changelog**: https://github.com/javascriptdata/danfojs/compare/v1.0.1...v1.0.2 + ### Release Node (v1.0.1), Browser (v1.0.1) **Date:** 16th Jan 2022 From fd75315b3fa36f86baa9890e13e46ddcdc87384f Mon Sep 17 00:00:00 2001 From: NeonSpork Date: Thu, 10 Mar 2022 14:15:28 +0100 Subject: [PATCH 174/202] docs: Added doc pages for `DataFrame.diff()` and `DataFrame.pctChange()` --- .../dataframe/danfo.dataframe.diff.md | 313 ++++++++++++++++++ .../dataframe/danfo.dataframe.pctChange.md | 305 +++++++++++++++++ 2 files changed, 618 insertions(+) create mode 100644 api-reference/dataframe/danfo.dataframe.diff.md create mode 100644 api-reference/dataframe/danfo.dataframe.pctChange.md diff --git a/api-reference/dataframe/danfo.dataframe.diff.md b/api-reference/dataframe/danfo.dataframe.diff.md new file mode 100644 index 0000000..315e699 --- /dev/null +++ b/api-reference/dataframe/danfo.dataframe.diff.md @@ -0,0 +1,313 @@ +--- +description: >- + Get difference between a dataframe and other. Accepts DataFrame, Series, number[] and number. +--- + +# DataFrame.diff + +danfo.DataFrame.diff(other, option) + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to calculate difference with | | +| option | Object |

{

axis: 0 for column, 1 for row (default).

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +## **Examples** + +### Difference with **previous row** of current DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [10, 10, 10], + [1, 2, 3], +]; + +const df = new dfd.DataFrame(data); + +const df_new = df.diff(1); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ NaN │ NaN │ NaN ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 10 │ 8 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ -9 │ -8 │ -7 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Difference with **following row** of current DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [10, 10, 10], + [1, 2, 3], +]; + +const df = new dfd.DataFrame(data); + +const df_new = df.diff(-1); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -10 │ -8 │ -6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 10 │ 8 │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ NaN │ NaN ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Difference with **Series** and DataFrame along axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [10, 10, 10], + [1, 2, 3], +]; + +const df = new dfd.DataFrame(data); + +const sf = new dfd.Series([1, 2, 1]); + +const df_new = df.diff(sf); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -1 │ 0 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 9 │ 8 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Difference between DataFrame and **another** DataFrame + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [3, 10, 4], +]; + +const original_df = new dfd.DataFrame(data); + +const comparison_df = new dfd.DataFrame([ + [-1, -2, 4], + [10, 5, 0], +]); + +const df_new = original_df.diff(comparison_df); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ 1 │ 4 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -7 │ 5 │ 4 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.pctChange.md b/api-reference/dataframe/danfo.dataframe.pctChange.md new file mode 100644 index 0000000..c07fc65 --- /dev/null +++ b/api-reference/dataframe/danfo.dataframe.pctChange.md @@ -0,0 +1,305 @@ +--- +description: >- + Get percent difference between a dataframe and other. Accepts DataFrame, Series, number[] and number. +--- + +# DataFrame.pctChange + +danfo.DataFrame.pctChange(other, option) + +| Parameters | Type | Description | Default | +| ---------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| other | DataFrame, Series, Array or Scalar | Object to calculate difference with | | +| option | Object |

{

axis: 0 for column, 1 for row (default).

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

}

| { axis: 1, inplace: false } | + +## **Examples** + +### Percent difference with **previous row** of current DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [[90], [900], [900]]; + +const df = new dfd.DataFrame(data); + +const df_new = df.pctChange(1); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╗ +║ │ Col1 ║ +╟────────────┼───────────────────╢ +║ 0 │ NaN ║ +╟────────────┼───────────────────╢ +║ 1 │ 9 ║ +╟────────────┼───────────────────╢ +║ 2 │ 0 ║ +╚════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Percentage difference with **following row** of current DataFrame along default axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 5, 15], + [10, 10, 10], + [1, 2, 5], +]; + +const df = new dfd.DataFrame(data); + +const df_new = df.pctChange(-1); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -1 │ -0.5 │ 0.5 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 9 │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ NaN │ NaN │ NaN ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Percentage difference with **Series** and DataFrame along axis 1 + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [10, 10, 10], + [1, 2, 3], +]; + +const df = new dfd.DataFrame(data); + +const sf = new dfd.Series([1, 2, 1]); + +const df_new = df.pctChange(sf); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -1 │ 0 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ 9 │ 4 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ 0 │ 0 │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} + +### Percentage difference between DataFrame and **another** DataFrame + +{% tabs %} +{% tab title="Node" %} + +```javascript +import * as dfd from "danfojs"; + +const data = [ + [0, 2, 4], + [3, 10, 4], +]; + +const original_df = new dfd.DataFrame(data); + +const comparison_df = new dfd.DataFrame([ + [-1, -2, 4], + [6, 5, 0], +]); + +const df_new = original_df.pctChange(comparison_df); + +df_new.print(); +``` + +{% endtab %} + +{% tab title="Browser" %} + +```html + + + + + + + + + + + + +``` + +{% endtab %} +{% endtabs %} + +{% tabs %} +{% tab title="Output" %} + +``` +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ Col1 │ Col2 │ Col3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ -1 │ -2 │ 0 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ -0.5 │ 1 │ -1 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + +``` + +{% endtab %} +{% endtabs %} From 89657203f8b86a4f8056105b80640a373ecae492 Mon Sep 17 00:00:00 2001 From: Chris Jung Date: Wed, 16 Mar 2022 09:06:32 +0100 Subject: [PATCH 175/202] fix browser side example. --- api-reference/input-output/danfo.read_excel.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index f966c10..73c79ed 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -84,7 +84,8 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/danfo.dataframe.diff.md b/api-reference/dataframe/danfo.dataframe.diff.md index 315e699..5288bad 100644 --- a/api-reference/dataframe/danfo.dataframe.diff.md +++ b/api-reference/dataframe/danfo.dataframe.diff.md @@ -45,7 +45,7 @@ df_new.print(); - + @@ -117,7 +117,7 @@ df_new.print(); - + @@ -191,7 +191,7 @@ df_new.print(); - + @@ -269,7 +269,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/danfo.dataframe.pctChange.md b/api-reference/dataframe/danfo.dataframe.pctChange.md index c07fc65..7c64103 100644 --- a/api-reference/dataframe/danfo.dataframe.pctChange.md +++ b/api-reference/dataframe/danfo.dataframe.pctChange.md @@ -41,7 +41,7 @@ df_new.print(); - + @@ -109,7 +109,7 @@ df_new.print(); - + @@ -183,7 +183,7 @@ df_new.print(); - + @@ -261,7 +261,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index bf824df..dc571f5 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 1441bd1..4ce0f25 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d8f9955..d2d7c5b 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 73c79ed..1a75ab3 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 627dfdb..5013471 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index 090526a..a58b98b 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index dd690d7..13b2d17 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index a39ecbf..d84cd06 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 181b055..53b6868 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 3c8ceaa..cf47c01 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 4515a43..28ceff7 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 1b53f6a..1b38e80 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index fe04a29..a327596 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index bc7c71a..eb13f14 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index 2d6eb0c..c2870c3 100644 --- a/getting-started.md +++ b/getting-started.md @@ -36,10 +36,10 @@ or yarn add danfojs ``` -For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs?version=0.3.1\&path=lib): +For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs): ```markup - + ``` {% hint style="info" %} @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - + Document @@ -291,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -369,7 +369,7 @@ df.print() - Document + Document @@ -460,7 +460,7 @@ df.print() - Document + Document @@ -568,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -653,7 +653,7 @@ df.tensor.print() - Document + Document @@ -733,7 +733,7 @@ df.describe().print() - Document + Document @@ -806,7 +806,7 @@ df.print() - Document + Document @@ -876,7 +876,7 @@ df['A'].print() - Document + Document @@ -1293,7 +1293,7 @@ df.print() - Document + Document @@ -1382,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1600,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2213,7 +2213,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2265,7 +2265,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2360,7 +2360,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 365c86d..9707cf9 100644 --- a/release-notes.md +++ b/release-notes.md @@ -163,7 +163,7 @@ A simple example: - + Document From 30fa68505ded642d35c647879c8fdc5cbb516677 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Apr 2022 14:31:56 +0100 Subject: [PATCH 178/202] Update groupby doc --- api-reference/groupby/groupby.cummin.md | 76 ++++--- api-reference/groupby/groupby.cumprod.md | 208 ++++++++---------- api-reference/groupby/groupby.cumsum.md | 267 +++++++++-------------- 3 files changed, 234 insertions(+), 317 deletions(-) diff --git a/api-reference/groupby/groupby.cummin.md b/api-reference/groupby/groupby.cummin.md index 5f4b026..1b569fa 100644 --- a/api-reference/groupby/groupby.cummin.md +++ b/api-reference/groupby/groupby.cummin.md @@ -2,9 +2,9 @@ description: Obtain the cummulative minimum per groups for each column --- -# Groupby.cummin +# Groupby.cumMin -> danfo.Groupby.**cummin**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L297)] +> danfo.Groupby.**cummin**\(\) \[[source](https://github.com/javascriptdata/danfojs/blob/4993242be7847ba7583dd40ed0188929898b8fd6/src/danfojs-base/aggregators/groupby.ts#L497)\] **Parameters**: None @@ -20,24 +20,27 @@ Obtain the cumulative min of a column for each groups, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() +let grpColC = grp.col(["C"]) +grpColC.cumMin().head().print() +grpColC.cumMin().tail().print() + ``` {% endtab %} {% endtabs %} -``` +```text + Shape: (5,2) ╔═══╤═══════════════════╤═══════════════════╗ @@ -80,24 +83,25 @@ Obtain the cummin for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() +let grpCol = grp.col("C","D"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() ``` {% endtab %} {% endtabs %} -``` +```text Shape: (5,3) @@ -141,24 +145,26 @@ Obtain the cummin for a column for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C"]).cummin().head().print() -grp.col(["C"]).cummin().tail().print() +let grpCol = grp.col(["C"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() + ``` {% endtab %} {% endtabs %} -``` +```text Shape: (5,3) ╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ @@ -201,24 +207,25 @@ Obtain the cummin for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cummin().head().print() -grp.col(["C","D"]).cummin().tail().print() +let grpCol = grp.col(["C","D"]) +grpCol.cumMin().head().print() +grpCol.cumMin().tail().print() ``` {% endtab %} {% endtabs %} -``` +```text Shape: (5,4) @@ -253,3 +260,4 @@ grp.col(["C","D"]).cummin().tail().print() ║ 7 │ bar │ three │ 4 │ 1 ║ ╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` + diff --git a/api-reference/groupby/groupby.cumprod.md b/api-reference/groupby/groupby.cumprod.md index 0c3ac81..e47444c 100644 --- a/api-reference/groupby/groupby.cumprod.md +++ b/api-reference/groupby/groupby.cumprod.md @@ -2,9 +2,9 @@ description: Obtain the cumulative product per group for each column --- -# Groupby.cumprod +# Groupby.cumProd -> danfo.Groupby.**cumprod**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L291)] +> danfo.Groupby.**cumprod**\(\) \[[source](https://github.com/javascriptdata/danfojs/blob/65f9b3753389b08101d4bb00a2d6488255476aaf/src/danfojs-base/aggregators/groupby.ts#L489)\] **Parameters**: None @@ -20,24 +20,26 @@ Obtain the cumulative product of a column for each groups, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() +let grpCol = grp.col(["C"]) +grpCol.cumProd().head().print() +grpCol.cumProd().tail().print() ``` {% endtab %} {% endtabs %} -``` +```text + Shape: (5,2) ╔═══╤═══════════════════╤═══════════════════╗ @@ -91,46 +93,33 @@ let data ={'A': ['foo', 'bar', 'foo', 'bar', let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() +let grpCol = grp.col(["C","D"]) +grpCol.cumProd().print() ``` {% endtab %} {% endtabs %} -``` +```text -Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 2 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 10 │ 60 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 60 │ 420 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 420 │ 3360 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumprod │ D_cumprod ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 24 │ 12 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 12 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 24 │ 12 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumprod │ D_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 2 │ 12 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 10 │ 60 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 60 │ 420 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 420 │ 3360 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 12 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 24 │ 12 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Obtain the cumprod for a column for each group, group by two columns @@ -152,45 +141,33 @@ let data ={'A': ['foo', 'bar', 'foo', 'bar', let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumprod().head().print() -grp.col(["C"]).cumprod().tail().print() +let grpCol = grp.col(["C"]) +grpCol.cumProd().print() + ``` {% endtab %} {% endtabs %} -``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +```text +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Obtain the cumprod for two columns for each group, group by two columns @@ -201,55 +178,44 @@ Obtain the cumprod for two columns for each group, group by two columns const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumprod().head().print() -grp.col(["C","D"]).cumprod().tail().print() +let grpCol = grp.col(["C","D"]) +grpCol.cumProd().print() ``` {% endtab %} {% endtabs %} +```text + +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumprod │ D_cumprod ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 6 │ 21 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 10 │ 20 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 6 │ 21 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumprod │ D_cumprod ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 10 │ 20 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ -``` + diff --git a/api-reference/groupby/groupby.cumsum.md b/api-reference/groupby/groupby.cumsum.md index 4262130..2df6516 100644 --- a/api-reference/groupby/groupby.cumsum.md +++ b/api-reference/groupby/groupby.cumsum.md @@ -4,7 +4,7 @@ description: Obtain the cumulative sum per groups for each column # Groupby.cumsum -> danfo.Groupby.**cumsum**() \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L280)] +> danfo.Groupby.**cumsum**() \[[source](https://github.com/javascriptdata/danfojs/blob/0d33e344b80a3ed54c91c9393ac3b583d4b0b1a4/src/danfojs-base/aggregators/groupby.ts#L473)] **Parameters**: None @@ -20,56 +20,43 @@ Obtain the cumulative sum of a column for each groups, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() +grp.col(["C"]).cumSum().print() ``` {% endtab %} {% endtabs %} ``` -Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 ║ -╟───┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╚═══╧═══════════════════╧═══════════════════╝ - - - Shape: (5,2) - -╔═══╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum ║ -╟───┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 ║ -╟───┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 ║ -╟───┼───────────────────┼───────────────────╢ -║ 5 │ bar │ 3 ║ -╟───┼───────────────────┼───────────────────╢ -║ 6 │ bar │ 7 ║ -╟───┼───────────────────┼───────────────────╢ -║ 7 │ bar │ 9 ║ -╚═══╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 ║ +╟────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 ║ +╚════════════╧═══════════════════╧═══════════════════╝ + ``` Obtain the cumsum for two columns for each group, group by one column @@ -80,57 +67,42 @@ Obtain the cumsum for two columns for each group, group by one column const dfd = require("danfojs-node") -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() +grp.col(["C","D"]).cumSum().print() ``` {% endtab %} {% endtabs %} ``` - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ 3 │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ 8 │ 12 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ 14 │ 19 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ 21 │ 27 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ C_cumsum │ D_cumsum ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 11 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 12 │ bar │ 9 │ 9 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 13 │ bar │ 3 │ 2 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 14 │ bar │ 7 │ 3 ║ -╟────┼───────────────────┼───────────────────┼───────────────────╢ -║ 15 │ bar │ 9 │ 9 ║ -╚════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ C_cumsum │ D_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ 3 │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ 8 │ 12 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ 14 │ 19 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ 21 │ 27 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ 7 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ 9 │ 9 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` Obtain the cumsum for a column for each group, group by two columns @@ -140,57 +112,44 @@ Obtain the cumsum for a column for each group, group by two columns ```javascript const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C"]).cumsum().head().print() -grp.col(["C"]).cumsum().tail().print() +grp.col(["C"]).cumSum().print() + ``` {% endtab %} {% endtabs %} ``` - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,3) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ + ``` Obtain the count for two columns for each group, group by two columns @@ -200,58 +159,42 @@ Obtain the count for two columns for each group, group by two columns ```javascript const dfd = require("danfojs-node") - -let data ={'A': ['foo', 'bar', 'foo', 'bar', +let data ={A: ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], - 'B': ['one', 'one', 'two', 'three', + B: ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], - 'C': [1,3,2,4,5,2,6,7], - 'D': [3,2,4,1,5,6,7,8] - } + C: [1,3,2,4,5,2,6,7], + D: [3,2,4,1,5,6,7,8] +} let df = new dfd.DataFrame(data) let grp = df.groupby(["A","B"]) -grp.col(["C","D"]).cumsum().head().print() -grp.col(["C","D"]).cumsum().tail().print() +grp.col(["C","D"]).cumSum().print() ``` {% endtab %} {% endtabs %} ``` - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ foo │ one │ 1 │ 3 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ foo │ one │ 7 │ 10 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ foo │ two │ 2 │ 4 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - - - Shape: (5,4) - -╔═══╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ -║ │ A │ B │ C_cumsum │ D_cumsum ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ foo │ two │ 7 │ 9 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 4 │ foo │ three │ 7 │ 8 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 5 │ bar │ one │ 3 │ 2 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 6 │ bar │ two │ 2 │ 6 ║ -╟───┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 7 │ bar │ three │ 4 │ 1 ║ -╚═══╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ +╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ +║ │ A │ B │ C_cumsum │ D_cumsum ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 0 │ foo │ one │ 1 │ 3 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 1 │ foo │ one │ 7 │ 10 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 2 │ foo │ two │ 2 │ 4 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 3 │ foo │ two │ 7 │ 9 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 4 │ foo │ three │ 7 │ 8 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 5 │ bar │ one │ 3 │ 2 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 6 │ bar │ three │ 4 │ 1 ║ +╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ +║ 7 │ bar │ two │ 2 │ 6 ║ +╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` -*** +**** From 6c51db4a1083ebef87252fe5c25e5a96ad3bfbaa Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sat, 2 Apr 2022 13:35:27 +0000 Subject: [PATCH 179/202] GitBook: [#219] No subject --- .gitbook/assets/newplot (2) (1).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot (2) (2).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot-29- (2) (1) (1).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (1) (2).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (1) (3).png | Bin 0 -> 50358 bytes README.md | 2 +- .../dataframe/danfo.dataframe.mod.md | 5 ----- .../dataframe/danfo.dataframe.mul.md | 5 +---- .../dataframe/danfo.dataframe.pow.md | 7 +------ api-reference/groupby/groupby.col.md | 18 +++++++----------- api-reference/plotting/box-plots.md | 12 +++--------- .../plotting/configuring-your-plots.md | 6 ++---- api-reference/plotting/line-charts.md | 2 +- api-reference/plotting/tables.md | 8 ++------ api-reference/plotting/timeseries-plots.md | 3 +-- ...-driven-applications-with-danfo.js-book.md | 2 +- examples/using-danfojs-in-react.md | 2 +- 17 files changed, 21 insertions(+), 51 deletions(-) create mode 100644 .gitbook/assets/newplot (2) (1).png create mode 100644 .gitbook/assets/newplot (2) (2).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (1).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (2).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (3).png diff --git a/.gitbook/assets/newplot (2) (1).png b/.gitbook/assets/newplot (2) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 zcmeFZcT`i`);>%JsVX2HM3f=|(v_|VSm;QR5)`CYsWEhgpcJvtM4BL7ng|GlB2iEf zL+>pjoj?!>C4_t{dOX*A-usT<{rem57%+x=OS0!$YnEru`ON*$P+y0Mo|~SGjEw2Z z&oX{tzDipip#L zY`RD^n*Kz34Am8S`fma#6BYxl(Co}b4Hhk`OYg&vUZRRSN&cDPsqbUPYr~tw>!`0^ zgomH6E`lP8K`Q^jjz+dGEW&D(D~Iy&CtIP{q8Uq8@94MwJN9q~?=Cx6`K zq;iJd75cZoOCw_{FX-(2{O6x_V}I};CqMf44_1zx8)A@>@=WNDo7w1DRSk-hfB#Io zP{<)NC8b1k{@RaR8gnS%caHty#t4E~s{%bvt z$(W?p{&@Ovas$?E^p@Y<^XLC1=W!tBB;~(E(xAu`)<7;V{_yen^QIgELHjR}!l_jB z!r?=Gv$Nm-ya_gn<^MM7|2FFXH0u9MkL14o&qtm7|C2KhcVhH%bQES5P>Z`5MgQ`8 zk@4;^O!rGoQ3&GP(W6Iy1efgzobx7|?M%@L4i3&l8Dy$F?C-yxC}B0&r%3f@jDrYG zA41}n%bUO168AWI`}*SdPM$h-3p@S(-H#6O_^ev5sYfDN!AC{()6a%__T*4!2CdeG zSK7Su7KGfLP0}D{ss`ow&VSV&OH5>AiGE?sWL>mi1*wVt`8qRWIOldd=+uh zo@u_-ANrgpVpIxg<78&QIr%Y`gQujb)T*{^q{>O!?gQQJ+qb7P0w<*{wif%^4?hee z;-`jdy#)5QmYstA7rM!>wkQXzJdm`h&$g=dOjQq4(~jqkTAyj>Y1?hwo#<;>~^$!H4v_;_rZqM0YXGl$1BM zT6r}_o%fxa?k_TVH=h}F*5~_WIginP=e=*SQrtAVU5Zm5?ol&fd#_1x<=1$lTifO{ zl>A#K0;l3vCmM3yhRWbiz&~o&M^;9v;@KzbeCN5v`HpgE8QiOv645evq{>u&CMYQb zZeByvAA0@({Nn0mf_kxPgw4L;I$sfCgUq zVnLSO-sU2CJ|!*lrLHu2>D!+UzxA5pzfZ#?(^TR%QSaY|>dV(_n1xqS%X7NNWS>Cfo_;S@54-AG@^r6b?Y*%%%ec_}4Rw+C^R&0=uVPZr zWpCgmgbq!t4+psc*Q7w$e$TMg3&Km;Dse=$>wpZupNV+G68XCT%;>BI+El#t)V1Uf zyBqU-<%N4rA5Un-99K{nTp!n62zqRUnV*|gA$NG!AGW#Mow%`Ls+||OBsIDu#|!z& znvGLNsRXrozs-t0@us>%s==`(dYA z<|8c&KVq66GGL3D*;+%JmNYcNwq*8vSjzF9b|N|-!Ulbw225H9JL@H@Z(}=t%qP?Q zeWb0}(1YE1==MZlyvebBD;Bon{*GlzO_x=@^P5Vd2l~aBI@p}l^DblzX7lTt&;(8* z?sBTa{H7D(cV^lyJa_TGdS9v89J4kn##Haw{3%wm=UFKiP@b?~+WUv*nmS<*Hv0_j zrmE~Mb>ELM?CX2WK7@#4{N2!bz2(qo#24HH;KTJV`~tFT^1qoiuBJ6z|L$m1@r#%~B8A%D3{*Nm81u z)_pGHLrpIz%j8A(cziH2N5uR{OeSv-*bm%kWu|g>l3MRilo9ZcvObRcI@;CQIDAXB+eZRF%hHq}NIxHa;|p{??$dc=sa45!R z=8M%UfrQBYt~1nO*91Siqg+HNM~$%!UJ9G=;k;JM_qlI=RoK+1#Ck!hrO-_2$hJaf zgN#b(J{0T)_0pvh;P=o~C^ck_$JkllIo;Pb4TDhg_vz<-uz4&-$666;MQRe-I97{KBe2dv&ECw zOKRkHn96(SmDdom?fAo!p?DAX(YFubL+(a7jRIN*tIXcUo8KK5C%*tET>bLrjuX`evEiX*TeN8q)T;rb0Ak)5?9sE_linqtap&m_H@|z*aYN4IPJ?~= zWrO_(hj$GYDcsXDYVQmcwVc9eG9En-H;?cCYQmj}Cg8@r;yn&6eVGWHyi2=0Sc-h> z(iay!_+||qGWXmmP8H$Wc^?*zd1jz?0eJ6sdGGse+V!o`>Gv3wOkgUp=_vbAR(=^x!M;n}G_^!AceRp4si z(yLR=%`UilrC#jPiN%{B+T5@3&5LpDd6vunMHeYFqTchR&k_~s>xN&b*nak?pY*O<&3K7)9p z&DXMTk4C_U=v9|PT%e_-i&0y$MgeUK1_(v5E#+pq6SaS4Q-5gbIjws=*qEEO$%#2m z@mWceY^vg$uebBi)nB`>QgK6mUf^sa(UVglB@JTH5uSbFuv$ynObLo=TXFp-H{}o~ zhD%T7E!>!K%2U)r{qewGPcI^H+}d%lo!Y9a;iP}rg1z2k#(z+B`#h#@d67*KSPOmFyXSR6 zDtxtKfETX!7YCjt(yhF4P@zemDj)5C@68-9n`)N^l8&P*hl56VEUgzi3Rig5B8L#X z^``VlwK~V>{m)Ib1NtlE^|~~YjjG+pRfSm9-IXFuocauNtxs@^B-LC`aUMMIhN#>+ z^rkDr1?oZLt^ zBB3Q(nK?_lc00vxs3);yt={@sq`8v3jLq>Ow`Li_=P5EVorqrf@HQJglzgBLH^f7f zOVpZzt8J0M38Ii^?Er^j92lEH%AT+4R3AY1j*a3-E_DYl^(l1`g; z7Z?bh5&$nxG6*#K=XJKs<&wfXmgTk-j{LhFN~OJPp}7ZY@xr1wXA;W zbR6&bqc0S_w5_dqC7bts5If&uMXldetS8ri*g+Z1BA^Y>XG|EW`Or{GP5^)LN%lqBCS1=tpZj zVtKp}M||hLM8GDn-#V9yk?JXw#rj@4pNO&~TcB;X&Ht$vF~A*h7P$p^>W{ zA6G73_KsqvEnYTm)jmPh5pi#41Et=sez4BMd)|jCLFEUXQs8QwS*a!0-6s61vJga9 zS9f9KoyIk8;2$$sG(p~|b3_#Nh8zJxkzo3DYR8DDh}4cOl&2M__9VWVBnoDg zw!WQh*w{a)(kVyES9heH&dD7mI;c-?U&(KCDSD>Vyh8yGT>thFZe*GQd!Sc}4aJQ( zSu_MlK%i)9-Sl%uK#rxL*1SC#)bsj=EQms1&LXy!huWv#->1|J!oH`CPnt#}qjQb( zrfoGQVapO{EGo!|dqd4}HCNZ7nfY8_??3`Z9Fp_%mHM!j+6%#CF_{}*T%fb5PAHN~ zrv2%XL&cod81^TzXq)Nll9^>z%VcV;GJJudnhE|-3 znI})4*WTyDD10j0XoSZIAdm< zD;o(CWaB7PH{>dIY^L8dgyYpZYLA;Yp5@1CZAB)Vg)WPuHhPw7nKgTKnB&e zRJm7%BQHsUC`)oflnY0BpXE5oPRB+D{-wm`P(IBJuM?!*GAbunagYg2V8ky@*+yJV znHT$HZ(?TGR@}JI{qFQZU*5x-dvy>zpGuw}p5E)p39UHVPS3j8W1C9@ox@0F*M3oz zjW4p!AUSJ-o2ypj*QgeTGy_B+Tccd)!En{K|FjqJfN%$osht6_J5@PQGELFT(>=BV z)`PV?CEBgNq-79Zr=GX0W$-wjwa5jUksXZYB_*)A5PZQni+eitxE$5H-4T_KJHa14 zRn`|z+iPuOXw!0TB|RObKh`x`UUR09eX`QNom*w#nrM9hCI%SB@bLWxZ}i2PMEK^W z-^_;c>N`qs_uaZvb?exxE38OHe0c;V?TPc}M|O-nT;6SbRi?}`c%i_w)=UgNZua@< zDQVcIbAPdEr;mgSR6@v4O`|_HbK?^wSMH5Xs!Cd80Ab7`KpGKt-HrHzC8AtlJ42~E zO!~0-IUQ-{ETx1J+x@RQ6D8Yntsz}c-yVw{4ZD->8rwSA7-UpteIEJYm|syJU%!#V z2mm|VMz4wc8wN9}Z;bP_sW*!s3^a7L9ITsJ;0;{kGhd(;n^)g_iZx>}}o*7ceX- zsrb=8Y<;;f^&?SNt#S<+oMQIE2x`ZUiv+2`R{Th~ikYgTDcJ1TUvS?nT zI@oJ7FkCye<5gSIv+6T-qoQ8Qwb?W0YkMx*KeKK&&PWWFT(o#dqo)tqK=D%yhLBqmIlBWc@%wokcnQ`J?s8LlmPHGC@T6*4-BfoCi+Er?1v&{^ zr#h5d3fWXs`XAs|1p(k2lvNZ-TOkn({3)Q;Axu=#Xa;VSH-)4$7ADh2eqq z3R;yX)@#@wjC%1{wo~+BmEe}PIfbmMAz;gL{==4CcM0n_GIifI$ee<2k|Het_1+WR zrU_lRpC@Ymx}wsnRx86NdH7iW^HJNwg4<_qSxo%y5nAy1ma$E_z-}u@nkHBC{ z(=Q&dJjv)sJVCpoOBSC=JSKw5M?W9q$r+0Gcb8(Uo(lL-Ba)4-=BqrQGCBp@TfY%= zxu+@;<>N$h-2mF6tHH&5Vb4LMcsQ||y4NIve~Loh^83vpuU`5umQ@D$v3^OjPa)}@Sf=AyDX2FNJ)k_+GU8tXaYn$;YTi;RC zjDMk-@$wm-@PO$LH>~l!+ij=-(iaVl5*BfjatP0IL$#S$`W{~w8=ylB0B&|>0VQvq zuOgC-!iR0d!bpp*`DJd1 z&B?BhFVXVtdgdSrC0(o|a3!@xMYY8Pu7_0QWNBY1&J!bgd=*Fb6y&)fzS|D3HgnMN ziB}zX3g)#?ALT)sCc*ssXfg*6?k|V16lW+OQrVF=#OIT(3^XL6BkZ%T%tPhHn4y78gc1SFx{|eS>BC z(U4C|-QocC@ZFOiakWJ~Sa_I$wlNF$Eh5BDk$&~}H&ue8|oh4TsBe%djaE`F9EmvepZtOTr(bOF1H zul+(R96_MN(O|*tCRZxDlZ1 zodf)uZ^iYjl7J;kP(Z)_f)r5a|Ei$3WtkWopLHKTds0M%N8P;4n#;Z|?m`qj`$}0C z^-R#k%?}GVuIVD(;rw%W%GEhbds> zZd=U$fng}lNl@W+$X)Cc60G})lE#3^kTY2lzM2(#OK zeJUSa-G*}Y;)aw^m2MUMyjXiMbimh4Ca`1XCyiCiwhoy|Ffg!@zfO7u? zLDe2Q5J2SsO)Ba_VfocV$1Of~g-8IRE@paY~N z4}hdcutE^d-99Q1?D>O-504aieu&MalUKb0s)^omJW=qWGv`$a&Oa|seXAz+HB&A( zQ;e!mzJ+ycPxV*hd$wn0Ma|Cf6N3t$FOUwgYx4P%9+WKH9Br0wUfMh71m%#hj3lK7 zc~_GzzEJS!M%?wyy$BHP$AYZTn8m&V+S3Z&(;EG+Z}go-Va96PvoG9_TU)ZM^~_k` zAk}j$j+z6ZKwag$3sgQrjtdSSI(bfS!ujWga85OG`$|g+A)KBm{NNfBh11u9nR@f4 z_DZ(EpN{@}JeS}^PAm3nsx&2NXq+|k9xAu>3RYeJ!1@kTGxoFk9{A(?=ZL3Fd`fJf zN{jSGsYZiZpWO}?4ZmVGG}rZ_2Xu16i_C(8Gn&3;sV9J<$-~mK%Br@tv&w<1yfJKI z-)e4YeT2%$$iy|`mJa4YfqcubVlSoi-Me%1&t!#8nBwh?nR6FjF+Vt8&pyA(9lc2t z$UPA3*WtRq(|&6_RO?jS-k3vKx%W8$BQ<{ba6}ZIMbte}2mJ~|E8aIE)qE>F@1~VeCipBaT!nenx`I=m*$=YxOSW$EKcLdQ% zN82d#r4CYxny_+K@IDZaG@p0>pv<5+)3KCywq|Ug&{9dJCfW$^uol8M0;FNM_i{2Z z;QOZ|$cnjIqOmGtRp1)rdhvC!DT0eDsvLGxgVYx|ubsZYem$LTFCDqnyzrbTJmYbIPfqtb8e$hcy_6Y`#TFOwPipAiCAD2)iX?0#!xo4lX2kjrG> zV_#+e)hJNUc}pzlY1t-H`~>N);U@Ti+JC{|Ppyoy%GK(+HznNx)@;pTlY8~xXyZL$ z)>~O7o3|MNVEPHG!ag_?BdS{(6nAcJLFle~-1{q)?^$|E51o(57d1NxIp&x;Qbf2# z;d{%M8^UocFI!M6Zh>9y3Ee(vQF4DTN*nK_Li0M6Y#e*ed$}3ARouvV&fye&d;7Os z{w^E5LUpWZ%BWP(+VUs;U&YN6+MB#{-!3V|WU?korQiRZ$~@>k`2M^_#3tfsQbdHf z_lexImI;;*gbGkIe*xgzf@xp$F^Y%2Y5|vHb3M*5`sk4yj-}ftUh`=g)PPFiFHq0` z0q_Q-L`C3aU<}T^d@LaqYz&J07o*!u*Rv$`Zj)Pn(#O=2p-$PjKy8d4c*D^!&=Zk4 zGMEh3b@unVY|06-lQd0y%>6Eu`-E!<;)ViZrwevn(v(d=#gB>GOiYZS`(l7=Gc{Cl z@hWop>BUG{#-Uiqxn~b6YS>gqK-u#bj$U)cs3W+bCFdVMXI7EncoA#;D4?A9U^7k^ z0W%O9A3Ag8Smwu-{?J%5n{I$)skP_=>B^2ZdW*2$!id4%Q2%VwfODG~7*%%@t?=XZ z#^knm2=%OI*jD(=OZzpK32Tr0N1Zvx1dfaQIDK?Bnq4yd`DWQMRaw@UY&9T@-QTiU zVy0ABcHXf*Hspr7pMqF=lg)&VySm@nnY!O~V$Q>rqeQaW7B@Nc1oUiawW96cnSrx9 z{^U`P$OYBZXMY`4*pMrcww7Eul-g6^zHP^N6z!y~U3kn}5{B)VoCnBoo zE^j;t{U^c%Nf~l{oc}5Cb{GFPjf;2#fgh@c0dsT#1pgDG!CVP)3I9yz*66|3L!KNa zee&ubpPX-|+doI|yicZtS%%LlKY{^u0ss9+&SCxltT`s~F}Q0AioHJ@o3_^YKq<<} zX6gqI--nf@K9cVIniHD$EfwqSYw*t}OGyHK5i`En3u-Abzjf^nCaafv_#BTFk9yP# z4n>8V(8Yf~_YM$P|H)C3z{bA?j&&ubp~4qcBVtm}$yMbyH{P3Ydi$y}x{PTYi_rv@ z!W>Z}4eFZl-WYm`)35-&(-*%P0}rY7TTfGQS<2`jL(F%zeW}G$aXY!k%1UjH%?Q-D znf&dm|3dS&x|{B)*Iq@D4vX`5XtNt7&Jf8rbZ$BgjCuDBuF^yrz-qDMf5Yp)l0`dk zOx7nPNJ{$gw~})791z^Xi8XSvQ$$CMJ$?iqqA3iB zW;>$VAi^%V4je_)-&=kOuO38au}$41x^b9h%`FyZe!VTM!A64N;&J6_TeAAOL^(uS zgwhfHOPlGb7F6F!6{Uy2_q)A13^~-&?|Clyab%m0PL7|Qpzh*8Yn7KtgN1();mvl_ zBVb@kqDs8TJ3YS8P)~gw5YhkE(MPUfdv`%WM5h*Axp^V=$tZ96WFOtO{I#c1#}hL~ zrKlkGmfVo|vl;ZWg$w89i|9U+${=jNckPiYvD}Noml%@-XvZs;1x zX_o-+`>P65I!fG{Y5Bn-Er|&@Q%amQU^kGO$%|^R`&dt`2J=zP{DmuqEOWn4!nOgIr9`$rb*k;v-mwsBl-i!*^=7?z zK$7^wzhQu_ayD|4{LGu*>suZ?;1gic=;~sX7HpI_9e9@&BUye%`2vSi0j}ZQIYH)l zxZ)*4PuF~_&2c%!+Jq>8F$8}HG=Ep(u1BmP^kPuDwh{p>p-qEH(Wt zkhu$L_*k)K}Ynw-pRvQmaPkf`qZbwJ~)J&b2{BKapFD4VI znXuyrK6v!E5|m%VhaK$my|pF~D`axjzN&6YSoVvFC|A+}Sd?o&$j?{ubDoSk{O)bQw<)jl2HES%#T!b?J;UFkpMrMI%P@DJm1l;sK}gom5mjyzf~cJ&{-pJVUIR2 zN9&8_e(3I5xu(E(E4NRa0T8*BJ{jd**UA$i|Mmpz$T=HxCeliof3LLEnV71mjeeLb zWoOU>E5vR3j6A$_Gr%>B>X^jPV;87U1>EeC6h*;uu^<4}ofm#v$_hyzj7GRa`+9p13kYO+IgonG-#*3)2?`3L=9e7Ryr;=JQlzrH zh=9Ozk?EbW6R!|wc+Tz6_GW{N?lAj zg6=C=*z`9CrU?^q1W3X^2qmc8JH#rS?K)5#vE)A0#0N6vlZh6EC0en^psRKB6m0?M z)+p#~lKJDzOwZuSDklTK)fMG9?$sE>D zO-%*IbN%=6AbSo#t#2A%E^HT!HacfgEP0fs{4rl}BrrQ2C^{Xfe@TgW4-l^0-g(%>8_{yv9df)#Vd zMbIR_*)|ewBsh1@n<%0|saEKi2kQ?N-yH850@WA~9Yc8Fr^kZl8P@=Z^A1XN`zD~V zIFG(9x|AEK+;CPHeTm@gq2mu_@kkg!EJATgR3B-p8XxwUb=>5J?u2{nz3Mv&!V>u;P9T( zc|*Ca0aW=rM-LDv>Ed&X>Z>n8q5?POx)#Q2r2r|DcNm_nMkJAXrt~tD*t0_S#PSWY z_zUM+A}Ecj9QBYYpb+y<9;RlIao(lX@c$@;Gm(^2Kl2J}P0*s*rBU{#HY_V!X;FQg z0UWc|CIW3!=W{9(wp7GRWBPpj$}{0xZE;*}$<);yC11*k+)93hmDCq88y;gd5^xrQ zM+zRJoC0{Jw^P@%RD%ZB8>Yb)w7I_Rr>~k}4Y+a9bR$PAw%+}Ek2G&J3KFtQlowWV z#AMzmZuS~kwYAtB18lgGFrTn90Y^#I@PaJ(Y0=vzFzs2tY%s#Qv`>iW^IYW2E~ z+5BI)%W(67+=;Z6m--V`yr6`CaWh39!KPP0OPpgIS%O38 zh_}Mu+(lWAK7q48w&HGW&1;mdm2=kNHfxCmWW>9JG;xGG;>S)gUQGIOza@kF`cvGO$zQq@wKPydYZlQ@>9n+OvsIDi+SeRLUjjs}#SIRMW@2G>5<)Ia!OV;&XD zZ9`1Gc-L5wjo+PBjhuTD`+RZb!k-NvozPL@=H|f8?Ged1DQRZK0!b=MW*X1C5GTvF zZ}jCNs}Y4Vh|EIHn+R!ru5D1BEY}sYn*(9Q>hy0P=j%rNeo9$-KUUuPSi_M%`erh= zaw?Td{s-|Xe1)`CCU~LdUvZNgQkP@2`F*&AL^1r?7;zdph{qdzL$jpZTC0?`xZ!xN zBYlMVXNS0I<+y4Z$?Br=(D5zY02Q$Rq@x1Z)!3mAo_~L3bPCjxQyT-+4{j`)Z=O3i zW>_GP-7ddPy8yC}gHKYDBpd}8Qf1C;s^@XwnJa*Cv5T(`8#fq}_R*KQ+MeFJrWIV? zsFNiSemZ`ZcCqJ(A&?e$N`MZ2OABD^8_;K*FMk_0a8L#H>%E$;mIA-)uddmsYD*@u zM}e_@B9I-eLsF1$y;$v=OyDUo+C9(gNrYLz@Xl=RJy6Sf-JVk#-BWOIWxv@bBs?cC zT;y5A#fLvAH?eeugeSJvBrF3cu+}{!HatKEBjC9k#3A#Nv!OkniC50V<;`YlzSLX} zXC{)TsfnteOGqGrMe6*2?hc8|P8@N=y;?C8xXG?gUxmD=TwGJiyywnerI)$=qoN`6ifwBSDo%1AUwUj5LQRWAM1 zph<{)2(?W2frC18obF^|GS_uB$2^=)XwOd&1H{wHUHDuHPQt+exvWCm!s};m>onim z?veeOFi+w{zu`*B4wUGfGyMt)2p=*}Z|uY&it(N23KmsJ}?fa)_@#1n|gX2o>d#%Sy|YJl-St zt?;<(xBZCpmHt-B%AAgrz+ZV${D%WoY7gs4MlPtXE2gWwfQL=q;ew@y3Rr9&GnQ)R zs0`zYC6)hakh(PFAm~le{RcJlhljzmg%8w1#X?8+MLZi{ADwK-<;7;TY5#Z@Vs^aJ zPJ$caboGf4!=L#x$iWYF?9PMq`S_ie#ubM zQyaPb?VGhTu+Lwf!8Z!bLzqJ`v(0NeH#YYc6kkvH@@AA@Y5k-hAD&W7K5szIqD#3n zbrtF6bx4vMGZ%+kmQFZ^>c7{gz z!_La(%k=ynrW^)S0bfL!mWNH!cjkvN+;jm1WQ2OOb;;5Ga)5V8ZF)UF}8^*e^^$lur z2+0x_fcuWC#0dTJL?$q}|O$X_;fRW!zHYACagY@%33aJg^(Pq~)o^ zT|FhIG~@>;sd{1;1?Y&$0!rc&5@N9Whj5MrxS|TA-l`9~BvgNU`PSy1^LhPry^q*t zg-dHMmdMl*^k;Syy%#YWDWC5?HNtPLvnU>|R=2iWbpr<5l*V@ML<}V2fxDYVPZg8L zZkFBdc8!eC0*D)Z~Od^b?JU@&vDC9c7JQuwELGSYE zXLP~6?3XhS{bFMUvjWMmimXwiUhuSrJ+MKZ--!M+-ELuPNw(0btsm#fJN!Moo14ki4eAiQ719fi5 zcK?a*PYgFNYUecyY8fc^R!{(YiMkeK&kb?AybZV=dizXn0Rrt)X=d%I__80=yuMuC zb}ZeCVJ%79-B?Sc`!z4uW(f;ECQzyu^;G@*vy;jimE#0YYXV2QXOZ^s64DKBS%LbC zQlT->duYcKs|Q*k{5!MiErBSCtpf@_{C>`%LNK6YwWx=wy@=ui^ydkq=nCx%Jq!#f zgKcc8rRR{$+DIM+nNmK`gPqymthIr^t>Tp!?gyH>7|*XaW7 z5~`^dsh%=JJfbQ<`%_g-o&?wlFtp=yIQ|$WVe&fn_MV60s`^8S00Ew%W8A&bHoDV} zN!e9PAEdNU=6e@|aayhuMdjmZn7Cibk_$)4`AUgNC zD4VKm|K`?9^gw&B?n&^4g?c;w%9$@JB@Je7VWhOC2K^&W*++~RkXKt$uyip>h?2R6 zeJXsb_zLHyvjo-PhO|GiG61xwuifrcB)&RquLrw?c2=Ng@;X{=#{QcN0P)e$&r+-r zFD(B~*|fHd<89yFj8lmZny{cnjRzdUmcMC2!6e9v<(cYu`wt!)xp-a13_a>!4+p{u z)n-1gqqxGG|5tPKM)qJ5FJ>+P_`i$!0Qq$9dLI z)=*UXwT~el*_u}^{r}+7zb}DrTUEmxFVAFUlPWH)m_E`_887JMOocv#^-$tVY9Bem6h~rk#dXefh;>Fo24f z9QmCf;{C(@Ytq;-r-P?&*=TWA=gDJ(5nUWJyT(mxEGQaRh}UV!>M1q_iHt&m<=GgT zmuU8nUXtgvP`rwKjiN9m(X@mMNVm+4N12`qh>j23V@KX#YE8v!>$*z69UgylSgvk1 z#zn3+beMLKLS&n~Q=LNL3t3tKtrEhao~=K$Z{bYfE1Z?KC_i8-A*j$S;W->?vNo!s zu=>ksv6>|BS_biyM!4c5!afde6R4hUXMA{ARdhFhG~1`Ue{Xv-SqgHA<0(V?bKKbq z+{X00v~-KfSa_sNzOM;hFSly^$*33CODGvPWc_HQI#~>4=ZoJ~_QK)`7fDctJ?~i$ zyTS?a|DK}6Cs^Urutud|-7*d_zVdu5-HP>evUkh)91Y@*!r8oQkd?qDa%;llMW7`A z)%T8gKn=3COUL(`6;@C(wN5|E#s^C*RNUMyCciJWKALomeL&vS?T#Z8d2&;VV%rvF zM2%G1BRz~_{8t|x*Jg*vZ{*I^QwwQ+{ONsVM$Qo)Y(FvCs1CvqIo@F8ABo5nBPld?rO<`mqTOGlr23;J4> z1Si*ZjRpnXNP1dm*5)ub$g*kZll(b@FjpHNT243 zf`|)-o2@f>Rq|Q}B3)Q}KqExyIwb&xl(i*%O|*ib=DR%R`=Yr{@AR|O`3M;YsL(eh z|86Jmq#o6`(&xT+#0LwThlnBFHncFcTv)Bv{{^=FoK>6&Q&?{S|Std)Q18TAdF@27*0dz<}vqE7T&zD)HST~Dj* zNeMgqJY4Kc+G^WJjb$JYzHxG(D|otvJW%Z?oOu4-Chfu(^fUFC2{#PhMT%1 zQ_6ATdYMNi2d2Yj$Ii=lju%&X657lfKcPP@BE)NxuCiUY-|_K|R&_7=vyw-&u{&;E zPHMRg4x!$sPZg7;yk#nzYnvmi-Rs-P$0_Tnq$YqVPKfy&pbV8Ge$Y1&5AeKSiowJ% zsE2YkTmAQBIlqD9E9cl6E1tM411>bY_xf>eh{-TTMz4$vWl2p_^ygqT<7Hg`(Rkc6N4#Zws$|ZK%E{w9AwASuc|-E@$%I+|;v@8VR<5Aq7U)=A?U8%hxcq zZ78P3+*WK87?B;Wa${Tf@bP5nVhhLs$^c65ExfopuW8QV(c~T=Y5@sStrkdk^tZ4mn$GV{W!@m zn+WgL5$!fEoi6tE845X6h+$YdotWD9UATiNJ{k4N5Kq1O{55D#lE%~@aU+BFckbA; zD{fccd{2Sc?7aprk{}J}+$qq{@CLKSxk1~j3!~NIfT9);nDjhZU74z57U&G+z_Q9- z!8=BqCkydDVES^n4+}{R(RR#V-x9>d5}vT3>0)dIQ3I5P=zpJ zaeM@4pOgxlx^JWNH5&xLaoCMhh0(2VY@a_5AGKdrtZmx{@oeY%q-t#*Yf_yA`PL8k ziqk|}+I}bO11Q_|()vdZkD`2=4(CkT-qSW$eQ@j+N40I)&A&E~9;s~K#<((EiL`ic z(;V8kzV(6CV7g|^Qx=R!m`(z=C~Yce3H zRF##L0R?vZ)>MfLVh6543{vxl3PW%mn=m^T7quP!eed(fJXDYFyn;S~BF5Kc(ywe~ zq&-Fu6Dyy-nCkHO9C`8GTjM*0rF1D~xG<@Ronga4PtB6NUga$*E5H?{FTH=i)b3zB za#%j=cmN^g!TBcf$LFiswmuaGipwljYdP*-T zCrz)f)d*-NJRJEN)Ogw1A(H3%X*f+%j1&Gey!8(5;M6ejrkAyKdecLz2e0Bh_UjFf zWT{YAMic2Sbrg=Wx%hitfMr-cHd>@-;2IxD8kMq2@P2D6k+x2v7|J2a8*$ub<&bzV zZPa2h(bX7jj+rvWlZwCtOP=MB#<-3}eW zyH?t*P>2Qq>nAjlpzCZ;%?oUo!2XN@a_E~ zlG{G_>7s`bRzS#XS=;>V8{fl#uhZKIb$4y%4YGL-Jd+x>h4LI=R)#-^-NcMIWikC6 z=`YId+&53)SM>%1c|7XHzR)b#l9>DWLQoj&KaBK$xdsm$%PNp|`OK_qiC}dy4si-k z(LWPuFIGhU$(4OOHgt%GCA|*q(~ot`$Lp@9Ew&6&zh6u#;tIyk6Rv3MID6N&=4e$nMj+LL_J z2)6=qw|sIQCt9zJqe;H}LUZ?OGZzu%n(FpU(7p zVK0Hz&8Q&#mY=ex=0)l1w$G5f@Q5fs;SS&`}BaJ_fnGuJoA^&D&6p#zjoZfaYl z-!nU4WhaCsm)}>_G;(#9x8>0J}~x5`D2Y`dP0R7@sw%$)tD)?}Kk z?&ri?ZyVcDfDU3=6$fONFZB%lA-Ukvfi2EOnuXDy3}fP*IFhb4@#4P7nZzQ@y^*>w zy8h5QZliyeuIA{=c~^pE8b+|iwB2ztACp%;lnIHoE%1mWDbz>;65nT2-Y#b0+erMp zaMov2@w(_Y84}jZ@M)wIyQI8wTp>mWlOhhvRwNa7f%-r3JIkzvx-bkJb%oFeY_ZVC z{vJC4sgVdw*xn=p>QHUm7UP*RCvW``wRBU`6*{mSY;HiU5KOsZ!=-E5c%%EfSzX7{ z;hcJPu*>_u+7nS->nnDr#q8gvm`XgPEh}|NwUL6{ zW%TOEYB}xT(@YZ}Nw0sNei9~ZWb4{YThDr-X;*Y=D#_Hc#Qq~EafJ{kS`iryaY#)=452=ruv6t`a zjk+Zx8)0hlxM@}V13_BkTuZO~eU?nE5i8Wm;!Bv6zfBYj;z~YcZhN_Ko=(~PG^whb zbfW_sx;G|?Tqv6i87DKWvOaMTY9oPM5N3;c7G>vz^S9kG^BHIw_nYc*eg08gaPBFt z<&;N=qhihD456DV?o=S~*HZpQl=YXDIHPmskGq2%8s5DfFp3RrvQre6oP3z1oWPx1 zWT`~XVq@DmoNM*^GNNSIndeLXd0-Z9)2~s}nvGkpL#@)w2WYsqMsu96G#$Rkvv!uk z2#*ZUs}o}?cg&_hgBKxWTj^ctsk+)792S#FN^O-Kpv`+B<&`-N?)W42!|d1C-Xj(J z+bAVmvu_)*lsS76-UsTJS$3(`O_>*8Jk-Q)O)Lpv?G*fO|Jjf2h4hcZ*|^RLkd*%8 zM1Au}Hfa7Fqkxb#UqgQQs9XVEzGa`|5X;^sB;m$m#nEx{SaJqpb)_Mhs#ctLVlI}S z^+n(JIoL9IC(G)INREV20e-2B(jtPAOUDPmJ41VliEE*bs$I(f6MW!J3+^fCjH-a< z${hU0oO--;vM6@~L~&615vREMxTba>acMdr>ORlCEo}3aZs}ZdBi0J#43(H_O{Ope znN1ZKm-9N5B@SkK>vI^i5DW_Z za&fDGk=YjcZN{#<*3@R^%*5&cuf6jMYqII~zDh?BDGCMwl`2S42)!e{OYcpjgGiMQ z(gkc3=}l^A3L(^>ARrYu5Vz zrYQci);;B&x#lN4jS?YbN);ow93N@6Yy)77vgeoXyq!!3httzLZn^zqp_UCOX&~Xh zh3(*6r9|e!6(zs51A_3wBU5~W`}Q5O;;tVVT7Y#xDHx>Wx4HYlrVNpT8W5Mi^~+Sf z1E3L3^?axKaxuYaX6~h_46#Hf-`ENV=bsKm&FqTWrz);=XiJ;BSVG*>db^$P6||&h zwww&mqLvj(V;^zEGsPoi4q@9?_HHJ79HQ?wwx3YtqL8ZNu}=Q*e4$f$BY9@3*0&H| z2E`{|aq+VvX;}ph|D5}hqH%naz8{STj{>$avO_st9ga|)=Ahe~1TWTpi8MMxMOG_3 zgo<1UHQkTQ+^&G~8n3a!1#n1yC1of2Tga*k6O~HGvgo5_vYP=TS27YoAy!>WyG@4@ zyTPQKIM<0ZZ{&R5&`pV)>s&IpRplVydspl&z44B8UJ{uee;}Z&=#-@J4;Ooc|L_Qc zH97?Gx67`peUNHgii{Es93TbioWez*B-@GUSMyW+$)Pry*&!~(FY6f$n+|1*t%dn@M!vn^c0p>jl_yLU&Ebx zfkKk9x)Q}NAPR4jy;~2>+Zm4@dHWt5{N<0N#TJx2vu}6-&M;_($B*Ts{Z@14y5iTq z**BjfYlfFPxmujc&Mi)2p-u=zCEh7!o@!$lN`Z-@b!&};tJk-vFGr`ayxi&?NSB`6GfUG%NeKP?DzZx$bQ zuMbv_Rq-)Z)rlNXb60OazMXV4`$veAtC0+}=f63Vl>*amVK&~sT@&Dp z^V%k^BWWX!H%cbT{Y?#{0DIS;)UbbvAx=G#LvPEbO8nal{IRwfL0jw5XKw$!=SCoybhZ~36fT~q_PZm9~kukC2RfF z)0g~@E|j=tcl1if;_+?_Z@A}Sk=)}gcMBHu2p^Al{nZ|nNyG6abGU^K*v+~X)y}}( zx2{Z>q6rK#n;a%=k|Lu;G^{f+_3%&vO4h5C9t<_+-;<-!MNy5THK3LTmO-rJ_?vHkDwFfYuLnXo;+=sxT8sR&~!eO zx+8GOTKGxxSH$Z3(3H}1-wa_5Xgr7;>!&|F1rt*G|CkW*b9iI5avSgNAjHk**ruj= zoFlBs(ML7vJ(fIRJ#y!R`$-SNK+a8X6fWwp_g%!^P45#(s+nas_dr{zrW91&Yzr5Isc`o6SroP1J|^(uYB&0K70QY8?HwZu^*qZo9(kKLyHJHdfrWw z2zn*#VOjv~1@K-VfBBc-C=;-dY_!c=2<(2kw}Vy~rHZCY@pib%ZBOMwbAEHu>v}5D zB7#zTdFkI{ns;}zUZ6g^tr~u4ZP3Nln2yinC0 zcm%BB^GZ4ENB{I2vK=nunf1Ugxp8$|xVuWln7%9yDv4EWL{zZ_MgpwOraD{X9Qa=z z%?Xv~@y~Lh5F_5~FiwwF!tAOl%ZCf+ObIDG%t7nH(b>@rsXWX17@PN>s?@t2> z-pBOa^4cZIn?ao(s5!UYbTt*%#lx-XD1kO5e#-n&e2$pAc!2H}pN8i_{ABdtq}Nu$ zV5x1~4gUf+0`Eo+RgwT}G|d|iOY4=6#PM1ohc9Yr1U@G;lDcxO{b^~wfW7>?1?&G) z)_MFZcpJ~$vA8ChWgBE%Z)_v!xy-&eQc!&9+xtN#V9=Z4eM=e>b|3r|)z1Pgbk*#J zji5_~!iwg<8H{r%>2q^TWHfr7=(C6aACn%j0vbpML@iyH^M||m)#(yNb{3_B6nMRe z?%~}N5gGQY9R~PEwN|R=8?C-BS=EmyY4}=!D&uxqOsfXqI71V))WIqJ<%Hr05Ovsi z8GybiqZHP<4&nytQ8UhwolSB&=OH1B46IY)${UQ}k%~(Y?*+x8?0jDyO za!ozrHt9pqBa*~*KkU|+sFVne>iTyHk%C573`nj1hu!=)LksVIbk=UUJvtbPUhV4c zobEAW%v(r=>vHi4*A-+*{|Ky2|6Y(svDOnThA$KJOzEi{qbdC^s;vR)g978I_-HiW zyZp|gotUnkBtyW%^2H^`g5FiRNn5S>9L2E9P0EFfecIBF43qG{B$7{MQcc08D8(0h z7ZcWYa)Za|l6xkbZ*U%Mr0wm@9vFF^_a6m~8tr|sd>+bb;@HdbAS``fI|>D5{2O=B zKA=!*p-RqtQL)-u$rm2WF^KmZz7G5Zl4q~xb%5aa!pfx^Zy!!XQL|uZCSqV1*VLa9 zIbRyc={K{B^9(&*;Dn!1=VAInEjBYlnAg!pr}gZ6zbkc~LQZXl5BbPJ14n^vq&Qu? zW$BwO#8cuyy!~cw^q>WD&hd;jsDKVu`$)}wsFOtR4~y;2Fpp)_s=|wT$T76^)(tol=-n{{nl2+D{->DP%9zBM!BkfX znlls2UE+(OUQ)?gT*`kP1fUqbt3i*J=OI`41q}QpO!k1gbOFz zkZio$iJ@ebm-q@gwPsHDu+4(Sqxz##&z8|@vkN5e%L_Y+G3HaEdgunNmA*#J8I6bA z=)IO5O)zQ%REHhg@t}!Y>9kqouac1BDq8W*p{V7zW8BTVzJQBBS^;=^RgRW4tsvvN zVn!cwFsE~-G{EHJTxi)d^3L=2jK}i;CN5X6{QJ=W{6*k zic+6oqvd3#PM5>OBUl53MR?eN;t%@84EgW6pf29$1%-?jn{()1?bhjhUR(~`_@O$N ztJj;#%V zJ9h6MKmad~QB}fiyRJMSu1i;kDuNV0D%es5U(;1a{H^(gk-?=^3KD! zH?NMNjsLKEKJml=>zT19Lf@ju*`5s~g4#vl|0muaVVEBcQakjKZD z$HpCwgn8upcaU3+-LC{g`rrQCUx~2m6H9efP|^@)IQ9?sw9gDOwlkpeEGn7(5m(4% zAxZs7g=lE_A`IzJe4T@}Z_gz7Sb~cpV0E z+$wPW*%Bf#WkUwf&v)*JbjTgv{zWDUIq}KsDNktf7xm#vx}RDn5j+Yy;xC*S<-eZJ zoqKWlu+{n1oS;>+eE1Z}IB`fW?Af3&E+v)IGHHN6qnCx#sNX!eo%s4U8=22@-gvYQ zLXjk&dh}IlG@7|8U#Vz@G9_6GoCmGWK-Bah7#*(0W=cwrv)fKnNGW1U2;sJc#VIc; zBuCf{qL#uvZ|oCl)ku-p*2J!j#M+r!8~if6n3QTWc4?5 znFXg;>8+K|tdm00x!oo2)plz1>U%ypdUukQajBZL-_ASVZ}Zw~lUd7&;~#jf0#7#j zKXahJtoyH+)-v)<(+9u|etL>5)65iB>iv^#{93@~+-V)q0A~2Byi;*5dE$h}nLptB z3-hLz_q)1S1v!|JSkEp$1{wVE3jP+KS?2V>rxDJ;la=5gw|Cv2n0YRU+5Q;jTUdD9 z9eLHR_drsRwnRHuX?=EW6d%ARMLQL;e?2E5JK}B@RBczUD`gLPT)Q}`GQ|_@Gf8VW z_ok#|?r?uoMMb3s5`Uz5QD+5Z&>)b@C=fpIh<;l`b+AB@nvu~(>@q>5vh05N!@84l zSQR<{S+jAiuxP}YkIwdffTit-uF4)9YHODWKJZSyWkRD6P4Tu>gxnx zFDZ7G6cpHEC%IBbZP}f_z2>^XF%VsFBRW=zbfV?(CsHaaP|RUq4Rg{c@!pT-2D({7 zVnHzQ7(bOhX0MheE&SF+W_i-5xbGeFh}W7c-cNm5A@#i3pkhf;Q70hl)z<{q5zTIX zvW$v^Wv$&?8EmvVN{|=hH4%E2!MXDc0(Bm|8^5Rb3MagHwQ>fvxK?A+(Vl8wIYUWu zG9X*~>%?t*_WInH1FEDwIwg#)%0 z?_oMJg;Mesd=3_>WAf6bzIaj5SZenj`nw8|BN$;xtK+4w+MY=OBg=e=6Fv)7PWgCz)wn;C2A?gbUYZn% zAlyn~ewl~X{VyN%Qdj-O ztvmAn`R@O7bK-p=?#wyTYhkA!Umu@iYsq%#dvQ_r%vr+UA8Hq`&G4ShR=Dx|fzuD~ zoHJw|3nnGZPW@S8BdvkE`}KoO`BowOov9YSCT6yA>_73XBSObOxHJL;N*VYQ00b{~ zO9fA;NIM1fJzobpA(sQ_Mz)w&F%XJaeP~lp<694I_+<75njd<&9#i@5GdJ|;!9WgE zh}D3|>Y)}=0uXa-`;duQ#d;Ycpqh?f$PINZN-->d+@iFu@YbQMD7E}bruaO;t@k8@ z`};tXVg`zo@tL(==(`WqDh=DrGZa^CEx@Xdsh6SQ9!R#rI)@{Q@0(L@fWtQMNCjaU1 zuP0Wrao;?F5 z!3bmg?eKtj-_cn4G$sW3t2nb=>}0}gAc_%Lw`mp^=6)CrK&Uay0i~_$U5xp;phWMW zc8lw>Qhm*pTf@%WuPzi21xW4GrWW25O zj%=}@l2OuPML7{-Zxwn3cVbggB>R3n=Bh1_vei?HObBcrjw~j;beP0B-8WXGuLYPV zk%Va7pY&f9t>^=@t25o|P0Fj4qGBkn*s>}o)oF@M3h5U!N_XCw{K!UDec)aRABm87 z66XGc4h`(re)vwAkd;A+y>#t^KJs;oT6z>2|63UX|7J~Zuj1tz_sf`|&A#aMLX3}u zs(;+kK0Z%y=i1CF#XNEM*ED5TT@;zeo%TJj=HuYz4JK!Q0K)AcO)IudHV!^q@80>U zKxN>Jb}Ul52-KtI<6yL_0Cq%qVz3WvseJ%N=1s^V70;2tB7<>nJK7N@^I)}Nw^F0f z0vM~$4x{#I7AqCC{qHRNCZTLC5V-yZZ2NIW)s*d1-h#cB+rsjC4M2!n3n)+g#yz_3 z^yUxc7^i;hIxQex5>LKAy)`2x7)oADoqfOOZUV7=y{h5C1;-!i%SXdOQ2d*8j!9Qe z^*40Qr#GwMPF_a(J)smP4Q>GR-YDwbfMxyO!-=<7@mXH|w>4k%VlzFEs@s+BweGXt zh4->?H2BT!a$;#AmnMLekJ-z^%BJq=E;nVfwR}7d3jS(h_6p~l>iyZ%IoQ)Xrc}a5 zlVHi+s*pRw{aalcjiqKT&&^Taakq{pQ6hErZqo(WblDpo)eGK>Y_auLoL4_|^S6@0 zX)r=olR6WD*w&c`b9qlLkW-mE)mgB1sfp=w!{=ux3P>}el&*3~_pDGdSL z^N;CrMuN&*txbcLp+~QlG9B2-4x|@bj6$8+EU6$%*o?}dCvITF5ABP2qDI2ic(!M8 zttidXdEB*D(_TzlYN{?0p*v+D!+LL{J82fTG4y@%ne@RYfWQiWNRXDWAso-LO=D>r zN@rnKOU>3oy`|a8pQO~f2B^+8m-SUs_%zhQpxZ?SBrM*X<ei+ z>iAS$*bH7$TPFUvRr}=*b9Z;N~A|% z0$k?FoZwn6{+vMd%-p1}iexqE$C|qML$_f*Efq7_=-sApL)$u_$&S&jVjDwU&afz_ zmw5?o0jktWw|6}p`SMcUMR$$K?&1q{EqR@$c`4oO>HO&Ew*=nx54>3n%r|Mhg@mUH zz1e0O@TlWcdwW1b6b~(>I<=#&9gx)&@7jT20=sTxDdC1=j=yZ zyr{(%)Ii%Q*v;}~&{8;Ob~pDs^y3P2YmY`@Qou`7ddkE+P7fy)i8iQn1vIeYaeKXgl&B74p>sQ}SY%EGwKwBFsW zF$g>Y1BR`DA)Bs~xizp=_fVzTofbbQ)uH0AzQ(A@#DOI@(DM%eO7}FLkFIA54feH~ zu{ed<;DD*QAo^D56Ljf`n#2;KZvwC!E~Y!}zR{4nv_(hUoXt!t(m z52BQi5Krv`4OT1)`&e^Fb7_RYg}f>Ndc__S>lXO*$052eHg%1yI(}HJisbAo>Q1Ev zgr#Ef>Z<~hz&cFE5cl&0zWQC2{u3pnX>s1*W8RW`V<31?2pXb%iXki%X=n4)3@#^B zSk}8)c`kqidwORGOH68-Bgc(CBZ*(D0vWf<`FhN5L$;ZMt!?f~iTS~#>Ozdj9v1Gs z@SWt?=?;v3f$JI(Ffj;vt|F9O zmDLs=e_X^`sfp?%#g!MDbCE*Z+>nMaiDy#O3Z$ z{uRoH$!39A-gD=CrTkx^{KbbfAiRxu1NkGe2jP9VD3OZ)+zP#E)ZZzRb!A05ks$r36vX{>PWC^o$*JcuHtsF1?{ra$1XUM8)*-(EZ z7N^7fcvH5W(V^`t_usES%XyZ@l2fHz?(Y%C>V-v$^oQgd{PTJ(@H4cY>p%H>gcnOd z{*iSg5Bul!S%fP7+1JX5{~qBrt+W4`p#MzJAJ+IE3;JLDi=7Y{I(7w~vj}tmHv*qg MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (2) (2).png b/.gitbook/assets/newplot (2) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (1).png b/.gitbook/assets/newplot-29- (2) (1) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (2).png b/.gitbook/assets/newplot-29- (2) (1) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (3).png b/.gitbook/assets/newplot-29- (2) (1) (3).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH zOS!V&z2CoZc(FnNR=Pd!qGxOstZbiop&pqw+1tbjuPdg|=(=0;3Jv1R^Tu0WFi5lw zL?6A$h!1&kI5t@O%(Tk?xLDsxpi4PB(^i-y-%_zO{GiTAMP>hrai4&3Ht4Y`sVgCW zpkDK+G$=nVE{V-qmnz)Qr25)F+haS5tF^Y(MS#o2V*AQZvr~hnNG+@rC~jjpta>{Tlxrg->HN|P2Pj4Mml)Onp;1& zxQp^n3^1qW_UWeAhJe?2tC;~518hi{(H(5Vuk~Kip9~Lnq?5D*$p|P#hT`R<3b@d1 zt^y`Rxt|9U{@FuKP z3AC+EOI5q!&L8g9PMImml7nTziKHmdgY;y_mzCD|nH3+)%q2&%TP6+VEuehOev(-w z_Mix)Fp{lq}5&+{e%J-a{@_EMaN4ID zO}1G0nvV2rb|4H1u?V^O`2YlL%Ftmhgy0s4tM5r@^E3%8I4Y!E5HEt zl6O241FVsc0neo0P$N;dN_-~GU;muG{~28ZJshl7U;;q1gngwq2aAQsKCBQj6Gs{d zk4a16T4EDW+xxQc)LE}Vn|$>^Fy~!Qnr=u`{#b?fiM5cjRq6daI=GzhN}|V2#}Cdn zoMPxo85t+^6I(}A***;WdG_4T8vPk=b;J-dj*McLT~tq!ggN$#v166d2qiOwR#Cdk z^fP_OoTjbz?>xWhGPh=P-Lp(Q^uWf&CHrfto2EcE^5xMx6;nug85@4uz^Lh2--T5F z`3=8X0eeLKyZA+T@@&!Dv1IFC7v`)0l?(QZNl1Psb*2KJsz|IaFmKs_?XzU(ex@Ac zy90255kTt-5=KTwCgyL+(c&L?J_*(U=C5YI^Q9RKntnR$I&yd5a%8R5hhSS}Xw%5> ziTFT$-Dqvcl;mW2_tY&vc4m;MDj~>QFRZ`Y@og=@wL6)ohh-kF-V#Vfw_m3Fe9aOm zM0QY|%wzL5tBW~5>CN_n6serJvI^PA$+=f)3Z06!()ABx>2{VUmCV?CY38~H@+rLe zyF`#6XM{!2S-zFF^2gIZ`NPUBiL6J&FMhKYfkaez>D2DPsX+YX;O&RMr*&c?8u?}c zuC^kGo@D|~meFnrUOd>CPJI7$I`oQY2X4U8JrpoUy-vsK zKjV5{`)Xxmx2uk*MT^G*KFqo}!8^{EeBb=1!ia8}{i1teIN3&i41FNpfwuItt0ZDM zvTNMeWLJf^Kb-LDobn*13G>^SThGvs3eIXO$Odko<;@HCnIIVqa5x%UoeN!vw9lGm z8axgkrWYSGQaz^4o-ubU_L=s(|BbArlJ&wypc0}O^OipH%H^_Hl+&h}c5FpI5OkO6 z*z&r$00zfdm@udPxfaf1jnC7m&%8>{)_*+Yrh!PmWF`88%N4zrRA=`4_wQ6rvyd!t zk%w~)#VkRshc;7b+oR4nUR^6g*gOi34E}?5X$Ui;j)+q~KheOl!4!2Qvc4#?1=zNMS9bCIcn}k= z_vT|odj&zXOY@xjj%gyYQ_l^xe_WYY7sck!4OY7U8{cBp`MbtbFAc;yd#6iFWFQM# z3C18a1?X2lz-@v@z%z-*sE!Pne+7RhNQSHcR(x?Jvr#`G0T(7OJIjN%Cft*q^Jbz= zt*PZHWqRz_zkH`?)K@bkx+ohR_TJpX{NV;yBC)p=7S=_Eio{H&H-Uwkaj8qn4RRjX zFT{qXO_|K&%BSNx@3ahqBo;2RPY zsHaHV5<`~#=BBJ~c9hAYtzOG_w>)3vPo$7oCEZZH84Y`#L|>HCW~aSv-s`-f_gmr0 zO?6_ypXK7iQ!OOzt>0|TVe`?cA>LW@Uv7bbKnI2cWhQ<{zz()UEd(0K{A10j0?BSi z;QHDlr7=P0$E_q}h0Ln$;7MP&HI*7Wq^K()Os!IY`TdS>3n`h0Yft!#B(;NWZIAch0J87MIKo7Fp1*1VfZJlg>qB1SWLDTu$v4L@y-k+dHWI=si~56iY`LFUIZ;g z;Hsx&z+b^P_HcdtjYMbnK1TcLIgQh#a5BIi__{edtxjzbgOXzAnlX_8{jQONeJUlJ z?o%}ws~Ht(FFeEsZEUrEvkSlIWm+Su!r_Qso2K&vp!a%DR$*Z>fGi{PJ3rh1qy;^= zKO;0i7x_3K1=U1i)779QkEvk?8hkA&NAQVSJx_~a5(8Y>l}@@YU*p-z{-K;$N~pZz zwICLh8e>_9KS%$>eWk8p>9s0iTWl_U&4?_I5Z1CZbeixAT)J1p?!2bd>REoA3-J3n z@J<3&1f5eFRk!A#ON!ZPD|4q(a>!K`)ZvpTj>SG^cnA3|q;i5ajMMLl!C!9J<&w}u z60=SAJCw39_i7KNiuzS6ChZjVx>3lqbk9fKc3P4yf&*vShXcQDOZ++x1W6G4J>FO* zxhr-No!cL;w55vrivZV45I~sovQs>v8diZon!4NBjM^)}F5k~Ulo1R>D?_nHNzpGB2yL@w2$v{u>6ar|)znG zmXGbQ5V>pNC;;Z9B_sY$#@-3O7cH#0$X_n>L?LXqFQfp2@%UZs1lIpPm10-4@(xA! zx6z;`piZHuKKLbbabr4+Z0ftWCYLUW4mPtNU5TPx19dWkm;N~u0xp;zAFn!|%$xH8 z59EJVAD*Y1YF)F5bP^ud2zXf}(0j>zS6*m1>!XJZ;M=EJjZq2w`37*z4E!#VOxMdn zqor4EO2FB@ZTP|h8&+@RMUioOS>390@xyb9AY+Y;Kmde>%jySG5Il}pt1sVsDfWjP zGxes~-cIftUHBTU1t>j;d_Z8(zo_(y1UtgGNtzK-D_d60=$T<&0xJwoI9Hv)Q?KbO z{G*k@MPaHi|0PT%)ws#iXPy!T>Qq;c7c#_k*RQ_SIht`|G!sQWQ}SxE>Ns{bcKYWq z5p@n(j{P;cMy!X7o-1R|>qnHIeRo3|Wqo9~`A*XbY%1x2v*w?LI#H4DnIMgTha-Si zZKr+}cSig}veCdE(%V3JQL`A8(NwM0Vw5G&t(BUBLEwnzMS;Z;G|&hp+a>yuV>L;InY)i~Aiz{xE?+K`5k zOm9|NPxD%X?wqMU999-FWCzn(WEb>ByX5_NcoNGjb%yn44JBUIO(B@J3Z>M+N|y`d1I1w$E&bWzuHhb z2v@%8TPM!Z^*p8e;;Knre);QQJ1Yeh>0=z1>U(3UWV~>NhLYUT9WB<`yv1ibgO->m z(A8uV)UmGtMkvQM=EI1~MF%s$n`b_R81VRh2AIKUdQ z&iLt}AO&vr)|@R_31al*iXb{I1qL9lz<1vsl13~zKPE$?8LJbuD7-pbjYq^RTRx0( zE);<9ZBr#Zm*Q|>EmY6;PesD2O2>_5(-;|i)=~BKKC+@L4}}Ia)stn)A6mRCu;hw2 zehV91t>g$6rh^HfAw7~=Q)hkeAZf|T@KkC7+VO-LVz+s?i?w#-sON#wG~NtZD(4Ac zI@->OD+v9pFRU-rQrvqC(C3@QgIV~~hiu;iJ4Tv2!h?stv(^8}Pw4KTHkH@@-9Ojy z*b17w*En==hC*?{WJCne?d4-9U{J0>Lq{j^m_)Y~vvma!Y;#rfB$((@N4=4Iz|LIi zxnj?cG1sNW4-*@5SL54fBNTL8)F0Cb6Wz3*=*1sjg8T(yo-@0> z85z@i^Ol&n)X!(WYm@U~EH=RFo0HauO31{Us?>nfMHw^mud)+%zwXG-H|I+Wisj?e z37r}cl|-)1^vO@Y-wyk(_YjjzixP90$zpjQK6&5TE{PnW@~n-)qYp%44@6ulv`DV< zgwhLRJNpPpnzV3$XC9VgX3CNWYX9OYbCV7+j@kir-T^(|3jP`L3OLgobv*fn_R#P_ z?dBAs_`XB|4B1?uKc0=1{g})4h?*{qa*oL1;CILuHsm@IbbtQ< zVXh}j*Xw;Z{RZT;%lsE)6HSXcimR@#j2>>;#|#F38I=-F;a~hPd?{?BKkV9Kyj4(2 z=(xQcnzYuYS<1PPv-|BZR9)?9n`-XrN>|9yMeVhnPG>Orga6<7M*aM~qUAa8j-h7R zZ;nN@@X7~!OQVU1PxFEM$#u1uw6QUb2H}z$LW^;D0&))z2duIAd&H!fPX7yc$%9Q0-fdL zK>lSool-i3dwQq`&>7LM)f=uQ&aJuhu2X{0U3OK%E_?DTNAC z(tL!$6h+i&Ijf1#*!Bs}#=<9Z4OAyWkF9iV=FbxE>gEiwYo!-+C*x(4=4nV}7KxfS zeq&k*i}ohNH%7wLlbQSyT(p>OP^``rK7DIX&#Fhyk4UWg^M^HpG3T}9!5H69AicAi ze6nx6>o#yZbS6D2c@sP=Yc)f~PiM%8DNXl`ZYTm3qBPX#GDIND1&a2hP|#t#0n zB$TRzup#8FFefdm@?F>avVuhN^NnF zN#njM+~up5k7hYo-sN$Vr;llhDg@~ z5j?B;m({ouF;FEcq07=%!?_%r9-r3-*p+LqnM0&3A3hbb7)ftEa zxmxx(42h3+v|rFM-2|Ei#u~OBFmH!VRI28^_?*}q$=)93d&iO?4M>M#7&VHUvZzKE zXW!X9WXK`NZ_Wr?eVXRcz$)zwJ$}pEUo=RjO)+*Phf2@hjw?wV{)$+fhIU(P$duOU zl?-u9z%7&K*wt*+eXvO_vlnp_0zqem;cL^d7E|x$`QLUOmxof^A}8eTng?I^vW&3i z8k@&apr4tDEW?XZDv*GE`xaF8HY97xTyT)q`;)~Sy~rn3PX}74{dkXwUv04aH&)z< znK(lkysS_@zRq&r?SWD4#dp;@tvgNVlL_m1N8IROj~^$b4!Ez-I&G1ArlvHL`e&C7 ze#wkb;@xp1uHi#NMTB+S180+9tuc0GPgIGs!r`dA-RZ>VmqIYVe8Mq;aLKQPyc;F; z6jZ|I^bwjZ7)ela)mX!#huM$Bzh_fk`C&mXuv?Se70cu3tJg+Xm#i#5uyR`rA3P5e z<>p$8RJoQy>`7IldaUD@Qh|BF6)d!g=#xuZ65DDuRJRvg z5K8t9i)mc-uH}0ub#_&l6me-Mx_tHyFnuNWM2#z}e1(iq|F)s*8mOU_1I8Ee8<*QQche($eQpjEErJs|l~&}d>Y;8*AUS3%mp(e%yH z>g|h121j}(%=^BK?Nggo5o}nC($|IFk>T0r>^U~2LU}cv3JYa0c3obG+!w2pQ;XTp zlNn)Fwr{L!Ux5$90~Gbu-^)wa%@?#%Q<_mewjC1Vh4W+Ga~mD=-|U* z9q;t~GAKS{`H+^kI_IdNnFgXoAqD{Lo}obbc557B(Nd)mHYP6@Lf$x_gC7d)+fv5O zQvLSC*5j^}znFMVy<5ed`!EVuY-i01xWnlSty>!%ld7Q`qFKg4ln(k(K`ONlXg%>61bpH7_xh)Ivrk*_KLo=!KZ-hVc6Muk5z=OEa=DN8938Ck z_rw5-%Tc>_;p(ENjNtAh0Y0bB)@SG8>i51F#Uic3!QKWoiRwFgJO8_z5Q`swHo9}K z5G}34M$Df8@Fa3z@vk|w;|j(ZFpC1^K}plD()Gv0iQ%q2TXs*Wx0h1Vy1aEhS&XAM zDWVll>p74YrSf{7$)HNyJND>h@3Qzx0Upa(-$+$$V(wt<+^WLbHrJky6n|Agdk&<{ z_L)MQ1FuvOFVn=o9XgM&Kzdz1H?RxUF8ELP9sfQU?widtCp7BBHP<*nR5#lBE5uZU z41JqHZCg{ym?7fq@8}=M-{8EzIa1DG=|BIXe6_xc)W!sl?>JsiKRdTl=aHMu7Plg4KI6WgEKsp1pZ^Syii9>TYL)mHYBUTHlA z6tlaf(LLF{udzfrA_p9I<-m25M@q5IeTpNQ*s>vZ`lM<%Z_$@8 z@<7p77^gLl<{N%<{k(7$ukgu>Vakrvn5==i4qdT=+in}st@)kIB(-!*!LF#Tq(Ybq z$$mk+t={j8CJe(4@9LEhUv^=uC8h0|)%ESB>5mX}u;t&ARAYLvPLczHH;Da$HB3jO zz2c{_IzGpf0cE>p=kiLHT5Y%-^WXTBp}{q5nEHpCk{f~->g^5vbQh~poaR90iHSy= zV(K0nqD-PwgU&ra*LOn4T;hFl{1uE3(;m0IIlp!8IAnaKKZ6^)HUEs845R0cmu)g^3(nlRZzm`!w@cd`i^{SR z&R39#cssMmc6O%UU!c``G}mTNUB>DVj_WC(t5Y&>BbgC|Zg5!BWoaigaWK+;xs2360Nb9U38CJn?(QYxpJ&?w5|QBd?#y4mZl|vK_bb(&LgI z@^sn)=HR>)&&slMtjmSA4`>w_#6~6MY+TZ3>i%>l9P@5pkg)hCujA4Yz!sJ+nqdzo zy3(Ed2SXc9M449y=D(k))8pONY8md zmMs?w{&TqcIycRdON%vAT&gOJa~?)VGFw)MTs+$sU(RRz$DX2mRCA2CS>Uh8qi{u( z*WkK6>1}y!N%}TF6b)<}^3sFPdT_KS!Q&|uEq>Cz!eaG-7)NiW_Wnzo92#CHv&M`% z$?Zlh5W8_Z2q;U*1_Y)IcTOP#ILpPBA4)1Pd5ZQ7SoD0Sl{BwK1>Ra>tVX=>ZGg;W z6G5UHP5>0arcctExw7QslCE_ zCw-%*(CX{=29%#nDoEeGE!ehwP6fcCzcEs%FsN#*JhkS;kP|-!g1*3FV6(kA{oa7(f5j-AZehBxsO@hD{Yv)x$iP6}%e4)a)$lM)&EgBaKpvD`8R0O{)|eYCZ< zBQ7zHt#7vY%27@R6J|#Ty6{;%9lgz6a|?YpenR}b7Wj|0?isNGE+$RJ?2yl-XfEGp z#?1ZxGDPrvN`~oF(U{Gds-i10ZJSVycj{2%hV@F`&!mg^u1EYy~G5L!GT~Vd{R@zvu?|!wW21g=BtY0v8KY z@|%kN!Zl15@8Bi7Q6`A4`RH5`1Lq&x9hHV2)rcQ)qvBuZDqgU-ST7P~O6~wxnE$pB zo=_X8$Rg5z%_Ic{`aXVcBv=i)-i~N{o>JNA2<(2|Jk}&@tH^9>i{>`xx+c)BSWc_^ zMtQXA&MDR>_IIIw69@5N&2Nj>+`Q2M-1J{mMP=ZAC;%+fIPpsftaZcv>~nl~X%DT* zHb+AiHa_xi_l=^YuO>TqWwQX3+Tj_2gJ=}jF7X>^=W+%ewt4iKouv9Ejl$nhh$m7Z zF&m_Q${}Fk6@T5->l9}a%f4d#FIIS$Pl7|N0^0 zwcnH6q8*KYEnR>xHf#t<*ZHmEEysjkHtn6{Gj2)Xg#+sa9VIh6L9U#+dS)wPO)A%y z=qUNXr?^JdKMZ3G(ZREE>WG%UNZGp(AWU=McfsRBQ$@6(u{~449XFTgVM?;pUP!K4 zew)KV`Lk;Cfq<#6_MsOPH^(C$Uc$KVr;*eFq>$f%J}MHN(W#K+q7Ug4)-dcTX|< ze6KNnynQQ)a-8fDFwI`7WC0XwR2AEj;>FJHaF z_>dVOzTIgBO>zN&vr3N7A$l1eye5lznp%hQelPxXGcyjx9Lk(UnpHbTZT#u*I-!Xj zGqhj085$;9rgTL){%-SYS2DuwG|3r!(Q;`7!&PW3VZf^SPN{v+U+*~WO6ekm;xLdZ zn9KG(kS})x-z$+Pa&6jFkq4vcj$iPc# z;0@5)KC@q6T{P-92}A>PTc7Q^0yR4o3s5)8+lANn9g{O@Q@CMy^qcXR8Zu2D?Ck+5 zxu(u{rLc;+R4#FJFbG5xdxZiV8Y9(hqA$R6=0;-pE9(c^3a=;c4!O1ziTxbDFK=5Y8uFM{lIuT39bLd){lkWFSfh zVvpH3v0PZdub<5Yayf|w1oF8i_ku(zWV%9I-%?~pp{NzatN&%|xqJ|Ge5Mne+G_sI zuuU~d#P&;X94>6N;sN=heLsKbRbwl^X81%})^URZ^)}P+QcMcEhn_p8Kyn~(;u?9n zXGekOWY&il9_0$`3Q0==z?{Oyr@ zx`w&^0x|4ttjn$-w@RLIuyZ*nbdioH(R8wV#RwtO84DAFd3EmBl3+a3v-uFhz4@5D zSzNzFeDZ1)Sdt52mzcjVfLSCoM!C+Tf>8K-prSuKv_-&`Vp_8+3>{vgID5M4tJCr)3_RpRHq^#tn~yh$EY{+Ie)QzrwH&9i5>8e`AG#SJqBf+ zl{RR+T^ASSQK|2L$xa`V^Mn}##>#(RqMM*v-cPlByr#!S);>==5?SQn95#hF+cd!1 z(2JjNJiP_5m+9j_#cMo%!eMKMKQ|m;4X1=>K%5GBf8)O4{X)N3*A&v*%9Jrr;MzmH zDVvi(VGP98eMtFhTFBg3$KmgM)hec6 zugHpf*_-hE+ zv4Ne3ql4?t9LQ(X?lb4kFkOe=qujRqDp=({;1b9cdj@u!I1eaDhyA(av+pnyWGYW~ z#YKFVlsfnIJ8iofqZv!2I&I}^gYFA~L+OW>N&<|c`Os|h;5@K#Z)s8W?al#jFtI># zt8W&OKUPH61HR#@vPA#c*#v`6Yi0R1VL#Q4ya4(N>Ds$$Yx~Oy_fG@03v7N1hTf+_ z$3XCN@dk9cM+|)L`1Oe$`@fU&!5G&KN(eJKZv0ue_(A{jx$VlLd(mv}b{(-W;M#E(Vgn>K#LE=nZ(BADkZ-*S;$8sbOWZ~WHKhn`B`oaKoRrd?r&v<* zyyV-jt+%uWH@1Xb8d%TMBE^Zq*@f|mK-%V}I+HfcGOR06X==FBuQK+>q)oerWMZ~8 zjXugO$L@hH*Lut-3UumGvjqDOztxp}!GnFFew~C1+)%xLzPe@M!M>V9<1$!L9R8*n zumi!3M)Ofm3ZBWjXI%qQe3I(p7DXG`8p9bGQ1dIF_E&X@qJAS9Bf?=&q7=zI} z)JKoDq_7uaxIn$XyDCN!3tHau;tYbm@~ck&=XiP`-yAFH+AQ!yt-W+LxfMVMpKQu^ zhVBnP^KggFlxqbQZey46s zJ~8rAi!Z0cI)kf+uqEV3eN^p0!NHVZ*4b01|MOBA3k+!$;goqYmrw%pT6rndO!TdykLwaZS$Bl7y^wMc19->r`Qz!wnU5 zk-!@LMBSjHf+c9TdZ|ZqnUrzFHR16UUTV7UK+?WQSN#5)5TUiSVAi{#p-W~^N76!# ztjH*G?$2O;o_EMOV9D(lngnL+-QvKMKw^u)Q_}7@y11DdyF9gYUZiSK9~AUb^4UHN z`ty5hp;-tyw$s2Oa3UE4uTB}9fK2(CHrkdYm#5Y+Ce#qoR+zJMR#q<2ne{Bm84X-Sl zf%aML?d>S@zc+Fu(JL=qtjF)2h6ugrWc=Q(WXk3B^hmsBd)CUCQZ1(u&IX>9%D_U@ zUSm8goYBfFwAtC*Euzw1>JL(4X(Xxf=jVq7`H1pAJFuO-W1kr}|D1XntBlU>GU=4L zGwZU65yIqZvddmI_ah^=D|Ka$1+s8=f7J_wzV|+Mh{!)=M5|Pgk)Z^A(00-G+rx0H z>__Q2%p8>;a_<3!gCeqn>ho`R_+4g6A|fKTEgbyMcD38U?n4X1A@#)JCGgAvHu-uN zWlybTX-{HLS4{#zNvX~Ap2CxYwZl!uc^Z3w>8C^kK3e4?gofflnGsIiOT>O!^u5?Z z>!PKJm3;Y;NCN{oSHFyP3|YBNZuS6nNIB0~-A=_*3X^{CFH3mALW1aScPLoVzEB(i zY?rKa0L*@dD!xR;#Fu-6g8uBg8#pUGV16dQ{fHE2++xrz4bX#jeiZT20xijul+ZHI zv3fDT%;(!9eD-6K{fBj@ZX@d3E_G>yH;cC$>I0VNHCKoZ%0n(!BneX42({ zuCswJXNq$*$M+g-V+y(rZv8KE-H2X8YMTDAce!;GgjcRO9txWd?#!yU&3}swJO;hE zR-3Sz<0D~Xzruc(3ZzffR}D{3wqHv3d^9%^AE`&P9*&0PtVfhQH3r<;Zyt^wevvov zX+(f8ai-t(qfq;a2MLbM)M! z(UWg&rsYlo`_+;s)H{BMKvlxIe!O zN)a~a3^#x^Bef`6lpQ-Kv%G6kHR1dhr6a+QwA5!KB=cVYVdm&sR5&uq_^rJYRCKZz zHDy~);4osN@t$C@R2=rN%$mwSrRnp1p|hI@Rbhk6(!5~0Q@`i4(ZlyGr9>KgmpC_Z zXB}ZwPW1akQ9cIi(vmKut**}aFGa(BR0Nhz9;vbLQqRSj=~Gc?lC)s5o-%*F>Urfs zujxTT<=FS3-BuC>jE~Au7iK^nHwc!zaLd`OQ@qg1NUm&3kCwPHapJ*2@-b)Q?towM=lgLjSB+JH{v(+QA?Lf90@_Q9*8FY4 zWPJwxk1#gBvNy4F$&<;g74W4RNgl;AWgEEO;oX$;UJ?CB4AY;auNa{7r#W2iQ#qjJ zFr=|_!k3$$#aH?(br2Ngp(i-R1i?;_*5-#sBETm$KZm2hz}Q-Ej%+X}78D~X+^Fj$ z#L$RMp83hhpkzZfN3Ld6!SMmY7%-qY)L442%J-+b&8u9!OjovMy3h8c z-4t-l4TaYAI_ROS+?*1qxN+NTy(yJ3`#VEj@SC=!L-j$<8nV&rUjBhL4gN1^l@o=E zJDTk`rK+=N`!iorguQRw*Y|+#9;J?sAb07MApk#%^G!S4hxs0V=7!iH*cBpz8Qm-CkSUa=u zHe||7)&$+{wuI_Q)gBEYxBu_?$T~#+R>vOZb-78?vwdwczHiQc-h{( zJo!4rp!5mz&jxB=cJh~64vkF~+wbzHI7q1mM_|j#Svvmg#8mp>B;&$-6_Js7sotM| zST)$iF;RtgK5^UDMKyT582%O4;oFjI>NDHMT2u7Oi6qHuPhGVLh{B+B$pavvz53zVcUEAO2f#u#=| zUz>+<6dhG-e%E1gAFiM&U(rw`qlqgiz-{7$+!~(nvN356nk(6`vF|dWarroXSc3ZL zGdWwUXECW9s9e7`gmsm2(bsr#^Dn+CU;7#=aiXqV3#;J9NbJx9N2k2eXMICKRp7Bu z8qa6~#gkK6fKW$-Os(s!T;B)Ia`+>|h6aEid=$jn<3NgggSFTrYexpVA>Z%(vBwIq zmV0F0aXo8B`)2oHVNrK=yeDVHNns|o1X90q(?M;4i|mvakK4-LYt73KYG)mTS+|cw zZ?C9hNh{tY2DW+znKyBe7&MoCC7qlW{9Jfcp?Y0t`BXe5K**KjBY~oZ(NSDf&q9jl zP$Q1{LX5oWAlZkTy_{*F4`y31-8rp1*t?u`oOc-&@Hk(Z_+`O8e8L9KWaWy@rYk@; zU)`tHJjMf0EV>JJu%x3`epjY-P`wZ5+uHMm+{kgOoymeE14%WH%dKeb#JF0#Q z<*h}{nKtDo_u&y{UgcQ<#W?T`swRX&vg*yxu5yk>d`c{JsFfM&U{E-~tvO+YnS z;*JtSG(W4~)-SY~XaCegGGScMr#3a*kpSH7xgpeB7QF1w4XE4-4O zxit9UB^CV-{53U?Jlh zJTE;PvCUf=l1TK1O}9#qK<^C*G}+WBG*7?_Ud$UavVES~P$fgE>kA1}PKt5i$ZYg8 z^jdAQN^$;CQ64Bp6r%}y*VYlWity5XHhhJbNo*&vWA8K&^A0pAjK&kG1#$=5ce~<0 zQO#*X>wH_`RgrPa%Ur3B{>~c=fOe3~bXRz!0|^PoHw6p$#!1Y;?pNdz4Ui?(@MYuz zjkHpuA1ZM(bJ6nr>47K-5>?bW+_~bNJ{l2n>{tmTjmpqCn4BM(srD!Xppg9=vB3vo znIgDdi3N0zYh8hdY_<@8KNnE#uKUM zKT=+76U~~p@|nr`h2!u$mq3o0?2v?G%=t68?@d=jiEm>6ycQ;)ZarThAAtY?=kAk^}FvzD@m#VA2aW-FS@1kj3bTDFSQ zDU31g#_R%_eAU4Sb>C{=CpFV4Jk|j&s~LQxzo^6c?XzD>t&3;>IQ=f!L+9j|Vh7aa~axvvsj3Ru8 zRw#Sj3~VpN`T#)k~w$7=5<-+ox}GMW|A$9NKQ9@l^Y%H{Bn6@KkI`hoDms(rp81xO2Y!dc7B< zL7I{!Mb!BgDMT>ktens=Q2=RcL)VeB)c?xMP` z(}h-VF3iuSIOUms=uX%cPk+7NVEp-kWo(d}n5|Zo&w*$AD!!HB4c-VLoPFhF+O@Xr zBC_B6(Pgxm13jevJFR_jLu#W<6TFuL0);ix*QJ?OL}9z^e~N#F-l`l|uq06YLMFf% zU=*!)zQ4W%s^|K6kK+OLgMOuqcV?jpb#K&j*nqT=iTNZpiG2c1{(Ffj)Y!CA&}Ao_ zmDO@|x7{$`j5C-#6A|)w%0#?Tu>ukNT4;z*kBwKtLl&)4V9FiP{;px$y)jBF(VC;b zcOMr~wobJhImN+H=VwNb=6=dHz)p-pE!1SE$Ji(KSFp*t)jJUI??XP#9Ca}!fxCT5 zV9gYMSX(Fn%uOJY@%j)4>GYlp*nFwLLa4u`l>%7nlA2$*nX75bQlR91DP#w*xaBJ? z$v^t-QUlV}(2O%D%s`1@aR03f@>mgP2w z0!$K0pUrsB6|uj-I|vFx&iqUpx^!nQ-h^}YKp(tk>ZveQ$4xEZbGo-jZs7Q7uIo>{ zp}kM0b(Q_uh5}LmyYNKq{m0n6b(6f8Y3H0~#slP~w*%@uSv2F}GBbn}IZv_?W%Lz1Mao08B>{u(>9c%Z@dKG&jZv-Ibx(SOH| zTbq;PRBW-Of)jOcB6omOI+OXQvuM5VJ%Oe^?W^W_SbEJ1Ly0{d0q)#eNWH`Wm?Q3O ziv{kg?33#IZ-E(pa4&g*QWZE@!))7MgJ$qj^87J{m-3n%-YgI+cYKpdRXIfT?f8zE zO1Hy03Q1szRhBg*9YZy9!h>tXIn%FxA>}pN~*Y{ zJm$$HMgqeXz0+3qt#3MOY40M9eNKl~UAoYg?sb4PF+3kBnH zllWu~xY94EXFpz!Y2f2t2KA&Wzq47~`F@Fr{1{3qC5PE+N~ir^ z!09aC3tlUlBk~D4b_$u&R*3vgR%2UK6u6AXSm&_i5gxjh=V1S5LqSQnx4$UOo%b_i zWNWo%jNc1e-8G47Bj2&d3K|B!{x&twGq)JaDChe}pq)d%kqguITcpVfT$(B6fA1y( zsNnrw32Nx{psKj)@qH>Vx9K-AQ-WXbDsdr*2MJzbNy1APpQO&{R6A(CM!4n5*$G7W z&?2Ve$DNFsV^BwFIPzkZpnptyy&33fmo5%kklw#|J>!EQZg?)Pc&I4Q1wFFD94XK_ zz=*Gs@hGvq51UXZ(@wwp{nsfjXdGFxlu}~i|3{^R589sxN^iCk1qi@3(P_Vgl|&Y< z?+j`jyf!}aJrU6w<9aE*zbs(#3i`bcdVHYIk=Krq|1WnfVvbXaSvu(VgI`~PbYcX- z;2mNhh#4tFDK&Lu@yTgH#XhH2{)Wrkr^XhJ)p?#kxuFJk!eDpDPX}AaQysJwok6Q) z4h4v?gPHh!W~xEuPux(RU%@&f>3ygYwM4#OBa)(aE>p z(Ytl~XIEp*#I$c#n~=2;ktvNciGOgvWmnT^3oO(0=*D}tt}Lg-*rsKosCQGQlBrF* zAcBZXHK4W8oD-9bH|YZCGlj?_-yLxk+5Gnd+<31K;{PiYD0D9T}}#e1nU;%%P3vw3GAqpKF-k7R#Q|3Y|vQ+2>V!}M0%`O5}fg*!RdV}QbHLhy9-HdqJYvXmX z)DycP$q%8wPF<^K7yzRoCYJu3)f0ynDTN?>sCoXkF}3;fw{^|GyygL#nCq7!uCtO4 z{3}vr=g0P^*S%fNx)pYB*wx>BpcK$vUn6}nFA%^8T&C0G3x0Shw~4cUi1&()P~TIW z`3M!%wmwl8C*cmEOR5*MKd;@{3L}>@yR9|s5N=L={v7C%ote&qjV5_xhU1L|XsOPc z(*4C=_PTk|xt4Qf-Z%xm+6Uo@P}EIhRtRd3{v#1xz_s!;6NMP;rw_ugRq4{$S^HPo z2_9am_%hbP#0FLa%IN~NachiaI@gPgaP{=j0(Fh3!kxeK?s@TLJiN6q8M)DUTGkRE z1Y3WRb)1H=(}`_yY(S z*XIlCl$;R09t7b3$6Qe}?*%#)QwYzNkt&54RLHgqgv$>>Nf+YVvhdpQ(Zgx_s)KpE zlchVm_?6hIso0+#8i$9T$#$Dmzep|%_j-Yz-20101SbjOOzzpUXImV*gfJZ(1R=lQ z9aG-FAkgG5N(z5NR4Hh?s5 z2U_ctNWA;yQYwW^s&=AOwEf7f`G*sX*;|09!UZ2jp-rewY4@ahB>*U4D#JQJ_|UoFP?46bTNO-sm1UYpen=*>Q2|Cv699|ROS z!^8mk?Q>b}a}MlkQ%{WD<$Dlb$4O;Ar(i&H(@4urX-TmPktm<{xj(n^hcC6(qRuG(J1r#T^0YZy4AKLN@3Ih-JQpl}I~MAcVP(*nyJ+bNz5D0nvS z3;Gfe56^Qs)Ubt>uhUEx&i`3qe-BhqmAHug^PEn=vA)L>L+ahDF4n(*A}(dP(-Cy_ z=Lri$f~ohoMH+Yvs%JA_UVzjUPuAfoHsBFNodCXs?fBWp{e<_WT8`U}nNA{8ZIPX! z$P2}>$s=0TLwtwf@rqzq0k`}mf$47B-Ppgme~|oQ{5Sa}frYQszDfnuoOjvHo$@pM z+8gzLR)7Ch#H>UQp^5O*6_uXpZUEJDfL-w2xdd?B>NfZq-6}xXrwW99fKGLxm3^!T zcVf|K9!hL8c>}8X#uxDw^yOOk@_-7P#tc*`o;y1iX0t*Dt?`EBLDo9}{jXcjTM{7o zVrD1iy(f1Xw^P!#2P*!{|4^X>S(g9{mmM=W&WB!^UIuRjt^p4X%#T3?KS_F&1U?g5 zUWbNtjXA*PwxO()am6{`3({JIuAtx-1xnA{T4^0zEn<9>)<-!x@YMT|0d{Tipw-qI zSivrbsdOwviI6#Hk54(o z5h8TiVqWyXTdM$*-S7`rWh&{=FBJfV*;(x=>oZ6 zc^<;{tDYxMdDdiluE z4VA+&J>7#VY#3cQ_|;r5Tb520!!a5~{U9w)Ry8LYa3?ZVcUnJifbIaEFbot|%{H8D zPvDlD)a$qX-)K({rpsWk@B|Mtt+8;-_aDdrW#P6DV1N-c9GM8@Dlcrl)j7DL7QuWO zBGrqFz@rjenlP~VtC9zk7IFs=C_P{T506#%y=P^HM0|Ebosp#M0G$#@Mxe(YYZ6KRZ;3`Z)Lm2fdQAY-vFRiIY_t`F&Xuh++~ZkO22l%0(OypyHs%M2bsE z6)4>@g+UTzrh4}2aLnmY&sW_69}v2qmkTZgZFaZ=*s7U3)QCsmm0b7!r`=GWp+v7_ z9kjg22bN2*A0H235l(mHyq6`wRU@pN>X3%jmS}Yoz(C@VI@Ix()zG52kj}JOE0)sXOm?+x>wRZ|RwI29_vekiL5u@K=yR+uel!o4??< zu>(03f7EgkP-{@Lit!_l_+7%8Fl30}7gs*x2c%J%^3gd2=#__RgVP|dp)79~(FO+m ze>21VL%@GHkaawkhl4?*-u8FE=SO{5jk}LjCDEGHAnmDO6vb1pXshWNRf;&~e8yp3 zpMfWTc$fG;4=iMkC+%WxPK_OZ=RXg0?y3KNgB>rW1*|ci<8j9EijJ=C;a>gXXV4iD z3m4Z*xDPZ{_zg}8i*YT>5t!n&{-M;Ma^>Q1wP87&ijasX!G&(7#a4qiSAyM${O8Y~ zEZUz#WeJH_*?AV^BS}0in#!>M(y5%iGU7wWA&~-win3I7Zw%T%#rdguOkCV>-4rl2 ztH6%2=#?aQod52MBA?g+|M*-qO`jgE56rYq*(`zn_a%qxd~XNa&^)hyr_N*vd!S62 z`Otu$_YAw;X0Tf;0HU2z*MDCI48|&Hjm~d59ujM~+{pBz-rdXzQUH6j%J0+>@YRn8 zs+5(L4PlU~y?t=DI=;T>aKAa7DsB6hXr(4*2I^!`>ohe~kt6#Ke>vSQ8~!gUe$L4g zk!JDQ!KVzy)l((H{3Pg40PGy$zuhIa54#TvkA+B50uE2NMo}Fc97-&zygc)~Dg-7faY&J;nj&%QpU@YU`~vYBhnA|^hy z6qqmOvhUNVop@e>5J_0r^ob(lOwQsHvTOAbZ{fXMzzAI4o zHMl?OPho#2_NxIEh=24~E|BBW07KfTJKprlsn%_gR#WnlvGr=3o#~tHaCQussK!D@ zpBhUeR`@5!=m7jr21Wr?1upmVfIdPha$re6+4Ns5-u}Uyv3csTA}6aI;d79rDGBc& zcv=Rlw5$PwqSCgAbH&hc;OU+K$G0||L)YSet}s(=bGThvS>jt}48;K*`}8bA!4QSo z`!M?Vz<3qG!mG`J1Hd$@Tv4_jQ29n8U2O%EG>f__T*&UjWU_Vds6#Prk<+j(7(x zACLP}hqXMkdatD=71w)uQ^z*zqmOrMhD**H=cj*zMqgVKrD<2AuI^q}zf<>72OH@F znI1p30?j8b4mt>G0(q_1pjDOM0ER_1ea1JqE063y0cVCNMpL};-)}Jp#8$rlq6y4s zgMm)8y@MT@m!HG&X-d$_u;?y5lepE0q*m|}nJq686lt|(3^K&)Qdhg8)|3wV^SmxY zY`kKE1Eg<22LhF{-qlS|94@`ErF5UW5i1RhwklfeB7-_k=&Z;O`5wSAQ?v$u9TvQ1 zJ}O`q60*z#O=XH+>9xHMd?j0eZF)FTVb-i4L4SBB%Ez$vg7LTf{xYds>j{I?mw?No z3Nv>sy7GD`1U0OFW1XA>1jx?>n>Mrk$Nf1T6S&z%(>r(SK5kb;14H)yl)!3#tZgW| zY89%bhk#BcGPE(bpiJGc-jxOvXInppK&{q)1_xk#ZB&r@0Ckzu$2PB8{!yTsA}cLv zz%;+xxS6fH&)wKJ-QdAsX=(Y4B_p)p{hlYzi_u}Z+e^-z7MIyt?L}1NR6kyU_yoh!m9C^%G8@LU&Y*s!xsQnGS}9F+sw@tehuOW_5=oVGzVnZur_4z+7u9U zVdq5{nxsu~q|4x~V*m|l3g=v#@qnyIC(c0rL(RH| z6nDs46llJ2R6q)PPjqUjsNk$6G}J1@JSZMPGr|Ntx^Z0(mf$K48QW(Q z*y+k@YR_&}=4$NXt^)fKnfk+x@8`1b$a5o!9;|3AKHp@vn^!-7po4yC!!8dV-83O4 zP3oNAyietBy=d>2Lo07?jycD)J? z?nK6jKg34zXgpUVOY{QS96&Ug%DM5H-(O;EGI|tI?E5#Jw#DjX<)*CmI2gNnqS3jCyW8+NDFtgh}5|YPMkiQnhb4LjR^DeTF`TV z!HAm}LEm2NzTEEkywQkslrdYhyl*gZ!)*LdYSvPUp~Ve`K~;@4P|{-|ZwY$kv`Ka- z7*ttoxZ~D(so>ksj*%y2*MAnrX@i;&@La`CH(JG50SZza5GwN*O^t z+}_cRiV#leS*$M1?_(ASyyvD7Vz9wxQ9X+nQ^x7L%Smg2UH{xmP0G!wF@cDnx%m;E zr!1?bfomk<^|gyw<)_Yr{=uX&hMQ~ssO3RrFm~-NmVgn#EPhbq&ldOPklD`ORKB~H z^CaBGuzJQ=16LJfSJhXEp)|ezqcreL;04G!*mL%c4HG&SBj1D1;RRwCDm&j>l@FPa z;~AxI|K|COuzFpMBKndPyH;!x-0%95FjLX2MY(`PNrhTjAMMie{%{l@4{T*2p=Xs? zsA$oikt)xcywTZ@h=>uzK(MBl;)(0p(%A^RHzwLzAzu9jvE!$`Z8GUcR7Qw^V|6BL##Y`h@!=mqSnsOVPR>Z0BHlmg z$v2SahW(Z>?i1vqGnJTtqi4H@zgIN*)uR=~R%e?9rQS&M_o~rF^T81YhLe%jsDy50 za{?$cGsc4GDj0Z&*(w_(L?661hoE8UYa|`)n~p-Ct1&tYf5?66zcy-DU6Wv;4g6{1 zDrIApoLV4FYc_Cgw4%`EO5Dc1*&jC_&}Zd?t(f?VLCB0(u`wZG7_+VnZH-w^rem!} zGb$+M<2W%Hea;(VNyeNxdL>}8J?a7Wma}LnG!wvf>0=|&yIJcTJ7(w5`}5eOLaF@` zBcnpA>Iu*9S|RK;1)zu#k_nJ7K_O0hY^j~$jFCw29pu(hH(VZBN9zo6Pnd)XJ5~D^ zTEs(s&??)dy)zIeNDOE38uOl2?Z!NO;;0TIOiWdBx`KT>5+Zs^{NRx~tyPqev{Us9 zb+knB47&jpDRGwvVuu&+-AV3ptSGH;K{@b*7G5SDM=QNBJ=Kdmn{zaPB}sC7Sx!tF|EuG!xBP2*vFz@I;Y?j6L*yQE<+EX zyE<>y&n`JNhz~EEat>GYQXk`Fq)C1mb|dOILZnbV;dH{?Q$ZO*%5_pn;=GikV0H9L z)upeQe!}HG2(vv|#?~Ryq;JY+OWPgtE{L#G3T?o8Z1=;u@rTb>8upO2lb>TMYoaBP z$AaaHI;Gt0Pzmv=u@Yph2ZulO1T4)Z|gojHXXj)X_SrT+a`5(4o8QnRKEu!4U-0+2`~ zd9nz`f6^@M_~1p5_FdsgU^4$BCp-9ewb_5)PzvQW!2WiGPN+Zp_YMF5i~N7#N=7rf zZ+xc&ZCwdU1_1Vj%s=F#$hy>p7V=-)G5mFxv5(x&lgGAqJHmrvJF0p$;Fo3!U=wgkb zj*mDw@ql(64zQ|(#KaJgNm7EwbUr0hCnqm!9Vb+<*TEEPu~+y6;B_GVf5Hvk=6E)o z4_uS`8xYS;R+!CsZvbpC#hrBY8YGC1KuyyH=!$m;{;q<=vkN3w+WAUE;vl6FbaMp` z1F3E$VbQvS3~2+^b0p2OnqPEaAf>UwekVnKEugg`1f-foL`2K&&b};v-K}75fHz(x z3ig1@IC$`87p?MM!|NMA7|;t-2)R-_ju*WFF~>5S@u2R}dzV7=)pjVdLPJyHG})yaEW5m;V@ZRFOwFA;XadS|($9`gBGdF? zFl=n>UaoxU&^=@qW>B{=eYG`JNrz7-84Vza%uuv1e;@n!^g94EK|?|%guTiKzZTmp zuxGO+{8vCctcT*W(it(`8rY2EFp}Y{l@#L`i?$Eo#1WXUmz=!(Ogr_OI48#nXuyPp z6AQya-W@CjaLsUgJ@fn6p%34DM62xl)p|N~3j*dV?0;59TtS>PS8gI?Qpsst`xP4jkR5)fNwqK`r4Mf>*FJz8kY)dCtFk?s z*NtaHBEW}&eZj5Fm=gR*3BJZfr&O#^1~Hjb0Sukgt))EnwSJ0cAB3YXxYAp2Gm+cWJ?9 zke~H&RZN9B9Bch;b?K1y_O3NPSooztlyqE8`>MKE+vC~@Q}x|`HMvh3AD&42`WGy` znle*qh}<;L`JkK>eGed|+U-WOUvgfT@QMb2BX$AOwOz{~`8((Pi;LIfeMEoT>3O6~ zk4!LI4uz3$3ytxfbUO{>xby&YXDcI??kRrpB(n$v%DjnemDb?79vOLyM?gUElKSJ* zzZMzP#34Qja&yQ2!$<=f#OdEI0Qox}7J*g6fcpA+{L{Q6A;*7yFAXG?LPdiEQGc6^ zzwtUG4fh}94!KMIpMZBqEC2CC;0q*^_0R7^0LSB|m6=Aa_-`MEbY}1Yf&ch4@C6}~ z&3QWug9-oB0Rp<_AI|IHn@>o1Vtix0E8!m)B9ejnrz=JK|JYI;1mO>qcQQp~>fQl= Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/README.md b/README.md index d5001e5..92a7bb7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ D**anfo.js** is heavily inspired by the [Pandas](https://pandas.pydata.org/panda * Danfo.js is fast and supports[ Tensorflow.js](https://js.tensorflow.org)'s tensors out of the box. This means you can [convert Danfo.js ](api-reference/dataframe/)DataFrames to Tensors, and vice versa. * Easy handling of missing data (represented as `NaN, undefined, or null`) in data -* Size mutability: columns can be inserted/deleted from DataFrame +* Size mutability: columns can be inserted/deleted from DataFrames * Automatic and explicit alignment: objects can be explicitly aligned to a set of labels, or the user can simply ignore the labels and let [`Series`](api-reference/series/), [`DataFrame`](api-reference/dataframe/), etc. automatically align the data for you in computations * Powerful, flexible, [groupby](api-reference/groupby/) functionality to perform split-apply-combine operations on data sets, for both aggregating and transforming data * Make it easy to convert Arrays, JSONs, List or Objects, Tensors, and differently-indexed data structures into DataFrame objects diff --git a/api-reference/dataframe/danfo.dataframe.mod.md b/api-reference/dataframe/danfo.dataframe.mod.md index f3cda7c..7979969 100644 --- a/api-reference/dataframe/danfo.dataframe.mod.md +++ b/api-reference/dataframe/danfo.dataframe.mod.md @@ -53,7 +53,6 @@ df_new.print() ║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -100,7 +99,6 @@ df_new.print() ║ 3 │ 1 │ 4 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -148,7 +146,6 @@ df_new.print() ║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -194,7 +191,6 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -241,7 +237,6 @@ df.print() ║ 3 │ 0 │ 0 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.mul.md b/api-reference/dataframe/danfo.dataframe.mul.md index 41b2baf..a2e0071 100644 --- a/api-reference/dataframe/danfo.dataframe.mul.md +++ b/api-reference/dataframe/danfo.dataframe.mul.md @@ -4,7 +4,7 @@ description: Get Multiplication of dataframe and other, element-wise (binary ope # DataFrame.mul -danfo.DataFrame.mul(other, option) +danfo.DataFrame.mul(other, option) | Parameters | Type | Description | Default | | ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | @@ -143,7 +143,6 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 0 │ 8 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -190,7 +189,6 @@ df_new.print() ║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -236,7 +234,6 @@ df.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 20 │ 48 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/dataframe/danfo.dataframe.pow.md b/api-reference/dataframe/danfo.dataframe.pow.md index 8a1bae7..1f2926d 100644 --- a/api-reference/dataframe/danfo.dataframe.pow.md +++ b/api-reference/dataframe/danfo.dataframe.pow.md @@ -6,7 +6,7 @@ description: >- # DataFrame.pow -danfo.DataFrame.pow(other, option) +danfo.DataFrame.pow(other, option) | Parameters | Type | Description | Default | | ---------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | @@ -55,7 +55,6 @@ df_new.print() ║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -102,7 +101,6 @@ df_new.print() ║ 3 │ 1 │ 1024 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -150,7 +148,6 @@ df_new.print() ║ 3 │ 0 │ 16 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -196,7 +193,6 @@ df_new.print() ╟────────────┼───────────────────┼───────────────────╢ ║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} @@ -243,7 +239,6 @@ df.print() ║ 3 │ 100 │ 576 ║ ╚════════════╧═══════════════════╧═══════════════════╝ - ``` {% endtab %} {% endtabs %} diff --git a/api-reference/groupby/groupby.col.md b/api-reference/groupby/groupby.col.md index 130b18f..7ebc5dd 100644 --- a/api-reference/groupby/groupby.col.md +++ b/api-reference/groupby/groupby.col.md @@ -4,15 +4,15 @@ description: Obtain the column(s) per groups # Groupby.col -> danfo.Groupby.col\(col\_names\) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)\] +> danfo.Groupby.col(col\_names) \[[source](https://github.com/opensource9ja/danfojs/blob/master/danfojs/src/core/groupby.js#L104)] -| Parameters | Type | Description | Default | -| :--- | :--- | :--- | :--- | -| col\_names | Array | List of column | | +| Parameters | Type | Description | Default | +| ---------- | ----- | -------------- | ------- | +| col\_names | Array | List of column | | Returns: Groupby Data structure -Note: This is similar to pandas `df.groupby(["column"])["colNames"]` +Note: This is similar to pandas `df.groupby(["column"])["colNames"]` **Examples** @@ -50,9 +50,9 @@ grpColumnBD.apply(x=> x).print() {% endtab %} {% endtabs %} -Apparently the output are not that useful unless you perform some operations like max\(\), count\(\) and the likes. +Apparently the output are not that useful unless you perform some operations like max(), count() and the likes. -```text +``` // select single column C ╔════════════╤═══════════════════╤═══════════════════╗ @@ -97,8 +97,4 @@ Apparently the output are not that useful unless you perform some operations lik ║ 7 │ bar │ two │ 6 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ - ``` - - - diff --git a/api-reference/plotting/box-plots.md b/api-reference/plotting/box-plots.md index da440d5..d87360b 100644 --- a/api-reference/plotting/box-plots.md +++ b/api-reference/plotting/box-plots.md @@ -35,7 +35,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -61,12 +60,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (23).png>) +![](../../.gitbook/assets/newplot-23-.png) ### Box plots on a DataFrame @@ -102,7 +100,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -137,12 +134,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) +![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1) (1).png>) ### Box plot for selected columns in a DataFrame @@ -183,7 +179,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -217,12 +212,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (24).png>) +![](<../../.gitbook/assets/newplot-24- (1).png>) {% hint style="info" %} To customize your plots, see the [Configuring your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/configuring-your-plots.md b/api-reference/plotting/configuring-your-plots.md index dccfa01..679192d 100644 --- a/api-reference/plotting/configuring-your-plots.md +++ b/api-reference/plotting/configuring-your-plots.md @@ -15,7 +15,7 @@ The config parameter extends the [Plotly.js config](https://plotly.com/javascrip | **columns** | Array of column names to plot. | All columns in the DataFrame when applicable | | **values** | Used to configure a `pie` chart. A column name containing values for the pie. Maps 1-1 with labels. | | | **labels** | Used to configure a `pie` chart. A column name containing labels for the pie. Maps 1-1 with values. | | -| **rowPositions** | Used to configure a `pie` chart. Pie chart domain row. See [https://plotly.com/javascript/reference/pie/#pie-domain-row](https://plotly.com/javascript/reference/pie/#pie-domain-row) | Range of `0 - DataFrame column length` | +| **rowPositions** | Used to configure a `pie` chart. Pie chart domain row. See [https://plotly.com/javascript/reference/pie/#pie-domain-row](https://plotly.com/javascript/reference/pie/#pie-domain-row) | Range of `0 - DataFrame column length` | | **columnPositions** | Used to configure a `pie` chart. Pie chart domain column. See [https://plotly.com/javascript/reference/pie/#pie-domain-column](https://plotly.com/javascript/reference/pie/#pie-domain-column) | Range of `0 - DataFrame column length` | | **grid** |

Used to configure a pie chart. Accepts the following parameter:

row: Integer size
column: Integer size

| | | **tableHeaderStyle** | Table properties used for configuring table header. See [full list](https://plotly.com/javascript/reference/table/#table-header) of supported arguments. | | @@ -80,7 +80,6 @@ function App() { } export default App; - ``` {% endtab %} @@ -134,11 +133,10 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (32).png>) +![](../../.gitbook/assets/newplot-32-.png) ## diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index cf47c01..7f75b6c 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -67,7 +67,7 @@ The example below shows the plot of column values against a common x-axis (index ``` -![](<../../.gitbook/assets/newplot (2).png>) +![](<../../.gitbook/assets/newplot (2) (2).png>) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/api-reference/plotting/tables.md b/api-reference/plotting/tables.md index 7dfc1b5..dfeaca5 100644 --- a/api-reference/plotting/tables.md +++ b/api-reference/plotting/tables.md @@ -38,7 +38,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -72,12 +71,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) +![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png) ### Configure the header and cell of a table @@ -134,7 +132,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -189,9 +186,8 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) +![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png) diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index d34888e..7cae867 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -105,12 +105,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot-29- (2) (1).png>) +![](<../../.gitbook/assets/newplot-29- (2) (2) (1).png>) {% hint style="info" %} To set customize your charts, see the [Customizing your plot page](configuring-your-plots.md) diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index 0a40dc9..8fdf8e7 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -8,7 +8,7 @@ The book then shows you how to load different datasets, combine and analyze them By the end of this app development book, you'll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser. -![Danfo.js book cover](.gitbook/assets/B17076\_Cover.jpg) +![Danfo.js book cover](.gitbook/assets/b17076\_cover.jpg) ## **What you will learn** diff --git a/examples/using-danfojs-in-react.md b/examples/using-danfojs-in-react.md index 682a0d7..ac720b5 100644 --- a/examples/using-danfojs-in-react.md +++ b/examples/using-danfojs-in-react.md @@ -57,7 +57,7 @@ export default App; On running the app, we get the following output in the console: -![](<../.gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png>) +![](../.gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png) Note that you can also import specific modules. For instance, in the code below we import only the DataFrame module: From ae61b124942c3e5926bcaf088766a7944fa8fadd Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Mon, 4 Apr 2022 11:15:50 +0100 Subject: [PATCH 180/202] Update version to latest --- .../dataframe/creating-a-dataframe.md | 8 ++-- .../dataframe/danfo.dataframe.diff.md | 8 ++-- .../dataframe/danfo.dataframe.pctChange.md | 8 ++-- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +- .../input-output/danfo.read_excel.md | 4 +- api-reference/input-output/danfo.read_json.md | 4 +- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +- api-reference/plotting/histograms.md | 2 +- api-reference/plotting/line-charts.md | 6 +-- api-reference/plotting/pie-charts.md | 4 +- api-reference/plotting/scatter-plots.md | 4 +- api-reference/plotting/violin-plots.md | 4 +- api-reference/series/creating-a-series.md | 4 +- getting-started.md | 38 +++++++++---------- release-notes.md | 2 +- 19 files changed, 56 insertions(+), 56 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index be01b23..56cac29 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -40,7 +40,7 @@ df.print() - Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/danfo.dataframe.diff.md b/api-reference/dataframe/danfo.dataframe.diff.md index 5288bad..259e6b6 100644 --- a/api-reference/dataframe/danfo.dataframe.diff.md +++ b/api-reference/dataframe/danfo.dataframe.diff.md @@ -45,7 +45,7 @@ df_new.print(); - + @@ -117,7 +117,7 @@ df_new.print(); - + @@ -191,7 +191,7 @@ df_new.print(); - + @@ -269,7 +269,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/danfo.dataframe.pctChange.md b/api-reference/dataframe/danfo.dataframe.pctChange.md index 7c64103..1a39c69 100644 --- a/api-reference/dataframe/danfo.dataframe.pctChange.md +++ b/api-reference/dataframe/danfo.dataframe.pctChange.md @@ -41,7 +41,7 @@ df_new.print(); - + @@ -109,7 +109,7 @@ df_new.print(); - + @@ -183,7 +183,7 @@ df_new.print(); - + @@ -261,7 +261,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index dc571f5..72cac94 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 4ce0f25..4de2c13 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index d2d7c5b..ce39331 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 1a75ab3..e5d68a0 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index 5013471..cfd5535 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index a58b98b..72b28d0 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 13b2d17..ce72145 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index d84cd06..617b8cc 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 53b6868..4b98d4f 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index cf47c01..786c5d6 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 28ceff7..1faf15c 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 1b38e80..29e7c21 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index a327596..69c0b3f 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index eb13f14..fd7bc6c 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index c2870c3..f1717f2 100644 --- a/getting-started.md +++ b/getting-started.md @@ -39,7 +39,7 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs): ```markup - + ``` {% hint style="info" %} @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - + Document @@ -291,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -369,7 +369,7 @@ df.print() - Document + Document @@ -460,7 +460,7 @@ df.print() - Document + Document @@ -568,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -653,7 +653,7 @@ df.tensor.print() - Document + Document @@ -733,7 +733,7 @@ df.describe().print() - Document + Document @@ -806,7 +806,7 @@ df.print() - Document + Document @@ -876,7 +876,7 @@ df['A'].print() - Document + Document @@ -1293,7 +1293,7 @@ df.print() - Document + Document @@ -1382,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1600,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2213,7 +2213,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2265,7 +2265,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2360,7 +2360,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 9707cf9..da1ab0f 100644 --- a/release-notes.md +++ b/release-notes.md @@ -163,7 +163,7 @@ A simple example: - + Document From d3dfad087c8f4853dcdc37a5baf96828f52d8b32 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Mon, 4 Apr 2022 10:25:30 +0000 Subject: [PATCH 181/202] GitBook: [#220] No subject --- .gitbook/assets/newplot (2) (1) (1).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot (2) (1) (2).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot (2) (1) (3).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot-29- (2) (1) (1) (1).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (1) (1) (2).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (1) (1) (3).png | Bin 0 -> 50358 bytes .gitbook/assets/newplot-29- (2) (1) (1) (4).png | Bin 0 -> 50358 bytes api-reference/dataframe/dataframe.to_csv.md | 14 +++++++++----- api-reference/dataframe/dataframe.to_excel.md | 12 ++++++++---- api-reference/dataframe/dataframe.to_json.md | 14 +++++++++----- api-reference/plotting/box-plots.md | 6 +++--- .../plotting/configuring-your-plots.md | 2 +- api-reference/plotting/tables.md | 4 ++-- api-reference/plotting/timeseries-plots.md | 2 +- ...ta-driven-applications-with-danfo.js-book.md | 2 +- examples/using-danfojs-in-react.md | 2 +- getting-started.md | 10 +++++----- 17 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 .gitbook/assets/newplot (2) (1) (1).png create mode 100644 .gitbook/assets/newplot (2) (1) (2).png create mode 100644 .gitbook/assets/newplot (2) (1) (3).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (1) (1).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (1) (2).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (1) (3).png create mode 100644 .gitbook/assets/newplot-29- (2) (1) (1) (4).png diff --git a/.gitbook/assets/newplot (2) (1) (1).png b/.gitbook/assets/newplot (2) (1) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (2) (1) (2).png b/.gitbook/assets/newplot (2) (1) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (2) (1) (3).png b/.gitbook/assets/newplot (2) (1) (3).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (1) (1).png b/.gitbook/assets/newplot-29- (2) (1) (1) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (1) (2).png b/.gitbook/assets/newplot-29- (2) (1) (1) (2).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (1) (3).png b/.gitbook/assets/newplot-29- (2) (1) (1) (3).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-29- (2) (1) (1) (4).png b/.gitbook/assets/newplot-29- (2) (1) (1) (4).png new file mode 100644 index 0000000000000000000000000000000000000000..a884a2060a233ec9517e12facbe7dc6b3937374e GIT binary patch literal 50358 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 72cac94..53fae6c 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -4,12 +4,16 @@ description: Convert DataFrame to a comma-separated values (CSV) # DataFrame.toCSV -DataFrame.toCSV(options) +{% hint style="danger" %} +Deprecated in v1.1.0: Use the [`dfd.toCSV`](../input-output/danfo.to\_csv.md) function directly instead +{% endhint %} -| | | | | -| -------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

|

{
sep: ","
}

| +DataFrame.toCSV(options) + +| | | | | +| -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


download: Boolean indicating whether to automatically download the CSV file in the browser. Only needed in the browser environment.

header: Boolean indicating whether to include a header row in the CSV file.

sep: Character to be used as a separator in the CSV file.

|

{
sep: ","
}

| The **toCSV** function can be used to write out a DataFrame or Series to CSV file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a CSV file from Node and Browser environments. diff --git a/api-reference/dataframe/dataframe.to_excel.md b/api-reference/dataframe/dataframe.to_excel.md index 38f6abb..7157518 100644 --- a/api-reference/dataframe/dataframe.to_excel.md +++ b/api-reference/dataframe/dataframe.to_excel.md @@ -6,11 +6,15 @@ description: >- # DataFrame.toExcel -> DataFrame.toExcel(options) +{% hint style="danger" %} +Deprecated in v1.1.0: Use the [`dfd.toExcel`](../input-output/danfo.to\_excel.md) function directly instead +{% endhint %} -| **Parameters** | Type | Description | Default | -| -------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in the browser environment.


sheetName: Name to call the excel sheet.

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| +> DataFrame.toExcel(options) + +| **Parameters** | Type | Description | Default | +| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in the browser environment.


sheetName: Name to call the excel sheet.

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| The **toExcel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 4de2c13..514da1a 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -4,12 +4,16 @@ description: Convert DataFrame to JSON format # DataFrame.toJSON -> DataFrame.toJSON(options) +{% hint style="danger" %} +Deprecated in v1.1.0: Use the [dfd.toJSON](../input-output/danfo.to\_json.md) function directly instead +{% endhint %} -| | | | | -| -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -| **Parameters** | Type | Description | Default | -| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


format: The format of the JSON. Can be one of row or column.

|

{
format: "column"
}

| +> DataFrame.toJSON(options) + +| | | | | +| -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | +| **Parameters** | Type | Description | Default | +| **options** | object, optional |

Configuration object:

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version


fileName: The name of the file to download as. Only needed in browser environment.


format: The format of the JSON. Can be one of row or column.

|

{
format: "column"
}

| The **toJSON** function can be used to write out a DataFrame or Series to JSON format/file. The output is configurable and will depend on the environment. In the following examples, we show you how to write/download a JSON file from Node and Browser environments. diff --git a/api-reference/plotting/box-plots.md b/api-reference/plotting/box-plots.md index d87360b..326fed7 100644 --- a/api-reference/plotting/box-plots.md +++ b/api-reference/plotting/box-plots.md @@ -64,7 +64,7 @@ export default App; {% endtab %} {% endtabs %} -![](../../.gitbook/assets/newplot-23-.png) +![](<../../.gitbook/assets/newplot (23).png>) ### Box plots on a DataFrame @@ -138,7 +138,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1) (1).png>) +![](<../../.gitbook/assets/screen-shot-2020-08-11-at-1.20.42-am (1).png>) ### Box plot for selected columns in a DataFrame @@ -216,7 +216,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot-24- (1).png>) +![](<../../.gitbook/assets/newplot (24).png>) {% hint style="info" %} To customize your plots, see the [Configuring your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/configuring-your-plots.md b/api-reference/plotting/configuring-your-plots.md index 679192d..2ad915e 100644 --- a/api-reference/plotting/configuring-your-plots.md +++ b/api-reference/plotting/configuring-your-plots.md @@ -137,6 +137,6 @@ export default App; {% endtab %} {% endtabs %} -![](../../.gitbook/assets/newplot-32-.png) +![](<../../.gitbook/assets/newplot (32).png>) ## diff --git a/api-reference/plotting/tables.md b/api-reference/plotting/tables.md index dfeaca5..2614b0b 100644 --- a/api-reference/plotting/tables.md +++ b/api-reference/plotting/tables.md @@ -75,7 +75,7 @@ export default App; {% endtab %} {% endtabs %} -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png) +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.34.08 AM.png>) ### Configure the header and cell of a table @@ -190,4 +190,4 @@ export default App; {% endtab %} {% endtabs %} -![](../../.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png) +![](<../../.gitbook/assets/Screen Shot 2020-08-11 at 12.38.30 AM.png>) diff --git a/api-reference/plotting/timeseries-plots.md b/api-reference/plotting/timeseries-plots.md index 7cae867..cc49d74 100644 --- a/api-reference/plotting/timeseries-plots.md +++ b/api-reference/plotting/timeseries-plots.md @@ -109,7 +109,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot-29- (2) (2) (1).png>) +![](<../../.gitbook/assets/newplot-29- (2) (1) (1) (3).png>) {% hint style="info" %} To set customize your charts, see the [Customizing your plot page](configuring-your-plots.md) diff --git a/building-data-driven-applications-with-danfo.js-book.md b/building-data-driven-applications-with-danfo.js-book.md index 8fdf8e7..0a40dc9 100644 --- a/building-data-driven-applications-with-danfo.js-book.md +++ b/building-data-driven-applications-with-danfo.js-book.md @@ -8,7 +8,7 @@ The book then shows you how to load different datasets, combine and analyze them By the end of this app development book, you'll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser. -![Danfo.js book cover](.gitbook/assets/b17076\_cover.jpg) +![Danfo.js book cover](.gitbook/assets/B17076\_Cover.jpg) ## **What you will learn** diff --git a/examples/using-danfojs-in-react.md b/examples/using-danfojs-in-react.md index ac720b5..682a0d7 100644 --- a/examples/using-danfojs-in-react.md +++ b/examples/using-danfojs-in-react.md @@ -57,7 +57,7 @@ export default App; On running the app, we get the following output in the console: -![](../.gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png) +![](<../.gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png>) Note that you can also import specific modules. For instance, in the code below we import only the DataFrame module: diff --git a/getting-started.md b/getting-started.md index f1717f2..2012df4 100644 --- a/getting-started.md +++ b/getting-started.md @@ -2309,7 +2309,7 @@ let data = { let df = new dfd.DataFrame(data) -const csv = df.toCSV() +const csv = dfd.toCSV(df) console.log(csv); //output Abs,Count,country code @@ -2318,10 +2318,10 @@ Abs,Count,country code 47.3,5,GH -df.toCSV({filePath: "testOut.csv" }) //writes to file system in Nodejs +dfd.toCSV(df, {filePath: "testOut.csv" }) //writes to file system in Nodejs -df.toCSV({fileName: "testOut", download: true }) //downloads the file in browser version +dfd.toCSV(df, {fileName: "testOut", download: true }) //downloads the file in browser version ``` ``` @@ -2402,7 +2402,7 @@ let data = { let df = new dfd.DataFrame(data) -const json = df.toJSON() +const json = dfd.toJSON(df) console.log(json); //output [ @@ -2412,7 +2412,7 @@ console.log(json); ] -const json = df.toJSON({format: "row"}) +const json = dfd.toJSON(df, {format: "row"}) console.log(json); //output { From 02736f5bb80596f2075f6b112b5a8053f31fa20a Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Fri, 23 Sep 2022 08:32:52 +0000 Subject: [PATCH 182/202] GitBook: [#221] No subject --- api-reference/dataframe/dataframe.sort_values.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 9aedc7b..03b8981 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -6,10 +6,10 @@ description: Sort a Dataframe in ascending or descending order by a specified co danfo.DataFrame.**sortValues**(by, options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | -| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | +| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | +| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| ## **Examples** @@ -86,9 +86,9 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ +║ 0 │ 47.3 │ 6 │ 30 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ +║ 2 │ -20 │ 34 │ 20 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 1 │ 30 │ 5 │ 3 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ From 42917a262a3171a6a4427502de8f50c162d0f128 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Fri, 23 Sep 2022 13:38:23 +0000 Subject: [PATCH 183/202] GitBook: [#222] No subject --- api-reference/dataframe/dataframe.sort_values.md | 12 ++++++------ api-reference/input-output/danfo.to_excel.md | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api-reference/dataframe/dataframe.sort_values.md b/api-reference/dataframe/dataframe.sort_values.md index 03b8981..9aedc7b 100644 --- a/api-reference/dataframe/dataframe.sort_values.md +++ b/api-reference/dataframe/dataframe.sort_values.md @@ -6,10 +6,10 @@ description: Sort a Dataframe in ascending or descending order by a specified co danfo.DataFrame.**sortValues**(by, options) \[[source](https://github.com/opensource9ja/danfojs/blob/cf5c7ae3a009458e61eedd18d9c9b5b6b10d5276/danfojs/src/core/frame.js#L125)] -| Parameters | Type | Description | Default | -| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | -| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | -| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | +| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| ## **Examples** @@ -86,9 +86,9 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 47.3 │ 6 │ 30 ║ +║ 0 │ -20 │ 34 │ 20 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ -20 │ 34 │ 20 ║ +║ 2 │ 47.3 │ 6 │ 30 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 1 │ 30 │ 5 │ 3 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index 511381a..1192a55 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -6,7 +6,7 @@ description: >- # danfo.toExcel -> danfo.**toExcel**(data, options) +> danfo.**toExcel**(data, options) | **Parameters** | Type | Description | Default | | -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | @@ -17,7 +17,7 @@ The **toExcel** function can be used to write out a DataFrame or Series to Excel ### Convert DataFrame to Excel and write to file path -Writing an Excel file to a local file path is only supported in the Nodejs environment +You can write a DataFrame or Series in Excel format using the toExcel function and specifying the file path. {% tabs %} {% tab title="Node.js" %} @@ -39,7 +39,7 @@ dfd.toExcel(df, { filePath: "testOut.xlsx"}); ### Convert DataFrame to Excel and download the file in Client-side lib -You can automatically convert and download an Excel file in a browser environment, by specifying a filename and setting download to `true` +You can automatically convert and download an Excel file in a browser environment, by specifying a filename. This will open a download window. ```javascript let data = { @@ -50,5 +50,5 @@ let data = { let df = new DataFrame(data); -dfd.toExcel(df, { fileName: "testOut.xlsx", download: true}); +dfd.toExcel(df, { fileName: "testOut.xlsx"}); ``` From fcf2544f51882d5ffa4aa7fc269b2a29a66225ce Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 25 Sep 2022 09:48:35 +0000 Subject: [PATCH 184/202] GitBook: [#223] No subject --- api-reference/general-functions/danfo.dt.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api-reference/general-functions/danfo.dt.md b/api-reference/general-functions/danfo.dt.md index 766aacc..1e5b59b 100644 --- a/api-reference/general-functions/danfo.dt.md +++ b/api-reference/general-functions/danfo.dt.md @@ -4,12 +4,12 @@ description: Accessor object for date time properties of the Series values. # danfo.Dt -For example, in the following example, we convert a Series to an `Dt` instance and apply a couple of **DateTime** methods. +For example, in the following example, we convert a Series to an `Dt` instance and apply a couple of **DateTime** methods. {% tabs %} {% tab title="Node" %} ```javascript -import { Dt, Series } from "danfojs-node-nightly" +import { Dt, Series } from "danfojs-node" const sf = new Series(["1/1/2000", "1/2/2000", "2/3/2000", "1/4/2000", "4/5/2000"]) const dtS = new Dt(sf) @@ -45,5 +45,4 @@ dtS.monthName().print() ╟───┼──────────╢ ║ 4 │ April ║ ╚═══╧══════════╝ - ``` From 245fa25f261d9f968a265233acbd5da353396c48 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 25 Sep 2022 11:23:44 +0000 Subject: [PATCH 185/202] GitBook: [#224] No subject --- examples/migrating-to-the-stable-version-of-danfo.js.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/migrating-to-the-stable-version-of-danfo.js.md b/examples/migrating-to-the-stable-version-of-danfo.js.md index c186782..9f3869f 100644 --- a/examples/migrating-to-the-stable-version-of-danfo.js.md +++ b/examples/migrating-to-the-stable-version-of-danfo.js.md @@ -13,7 +13,7 @@ The following list summarizes some of these updates: * **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increase the developer experience. * **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. * Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. -* **New features**: We added lots of new features which users have been requesting for. For example: +* **New features**: We added a couple of new features which users have been requesting for. For example: * Stream and process large CSV data * General bug fixes and improvements * Better error messages @@ -28,11 +28,11 @@ Update your function and/or method names to use camelCase instead of snake\_case ```javascript read_csv ==> readCSV -to_json ==> toCSV +to_json ==> toJSON drop_duplicates ==> dropDuplicates ``` -**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. +**Note:** that your code editor will generally suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. ### Functions and Methods argument structure @@ -40,7 +40,7 @@ Another major breaking change of v1, is that the structure of arguments/paramete In general, it is important to understand our thought process behind this, so, here goes: -Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: +Assuming we take the method called _**rename**_, which takes the required argument **mapper**, as well as, an optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: ``` rename( { mapper, axis, inplace } ) => DataFrame From e5c5f686cafcbadaae8613486f49d64f940786e5 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Sun, 25 Sep 2022 11:27:43 +0000 Subject: [PATCH 186/202] GitBook: [#225] No subject --- .../danfo.streamcsvtransformer.md | 18 ++++++++---------- ...rating-to-the-stable-version-of-danfo.js.md | 8 ++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/api-reference/general-functions/danfo.streamcsvtransformer.md b/api-reference/general-functions/danfo.streamcsvtransformer.md index 922dd43..30363fc 100644 --- a/api-reference/general-functions/danfo.streamcsvtransformer.md +++ b/api-reference/general-functions/danfo.streamcsvtransformer.md @@ -7,31 +7,29 @@ description: >- # danfo.streamCsvTransformer -danfo.**streamCsvTransformer**(func) +danfo.**streamCsvTransformer**(func) | Parameters | Type | Description | | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | inputFilePath | Function | The path to the CSV file to stream from. | -| transformer | Function |

The transformer function to apply to each row.

Note that each row of the CSV file is passed as a DataFrame with a single row to the transformer function, and the transformer function is expected to return a transformed DataFrame.

| +| transformer | Function |

The transformer function to apply to each row.

Note that each row of the CSV file is passed as a DataFrame with a single row to the transformer function, and the transformer function is expected to return a transformed DataFrame.

| | options | object |

Configuration options for the pipeline. These include:

  • outputFilePath The local file path to write the transformed CSV file to.
  • customCSVStreamWriter A custom CSV stream writer function. This is applied at the end of each transform. If not provided, a default CSV stream writer is used, and this writes to local storage.
  • inputStreamOptions Configuration options for the input stream. Supports all Papaparse CSV reader config options.
  • outputStreamOptions Configuration options for the output stream. This is only applied when using the default CSV stream writer. Supports all toCSV options.
| **Returns:** -> return A promise that resolves when the pipeline transformation is complete. +> A promise that resolves when the pipeline transformation is complete. The streamCsvTransformer can be used to [incrementally transform](https://en.wikipedia.org/wiki/Stream\_processing) a CSV file. This is done by: * Streaming a CSV file from a local or **remote** path. * Passing each corresponding row as a DataFrame to the specified transformer function. -* Writing the result to an output stream. - - +* Writing the result to an output stream. ## **Stream processing a local file** -In the example below, we stream a local CSV file (titanic.csv), applies a transformer function, and write the output to the `titanicOutLocal` file. +In the example below, we stream a local CSV file (titanic.csv), apply a transformer function, and write the output to **`titanicOutLocal.csv`**. -The transformer takes each `Name` column, splits the person's title, and creates a new column from it. +The transformer takes each `Name` column, splits the person's title, and creates a new column from it. {% tabs %} {% tab title="Node" %} @@ -86,7 +84,7 @@ PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked, In the example below, we stream a remote CSV file (titanic.csv), applies a transformer function, and write the output to the `titanicOutLocal` file. -The transformer takes each `Name` column, splits the person's title, and creates a new column from it. +The transformer takes each `Name` column, splits the person's title, and creates a new column from it. {% tabs %} {% tab title="Node" %} @@ -121,7 +119,7 @@ dfd.streamCsvTransformer(inputFilePath, transformer, { If you need custom control of the output writer, then you can provide a pipe-able custom writer. See [https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/](https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/) -In the example below, we add a custom writer that logs each row. You can extend this to upload each chunk to a database, or any other function you need. +In the example below, we add a custom writer that logs each row. You can extend this to upload each chunk to a database, or any other function you need. {% tabs %} {% tab title="Node" %} diff --git a/examples/migrating-to-the-stable-version-of-danfo.js.md b/examples/migrating-to-the-stable-version-of-danfo.js.md index 9f3869f..c186782 100644 --- a/examples/migrating-to-the-stable-version-of-danfo.js.md +++ b/examples/migrating-to-the-stable-version-of-danfo.js.md @@ -13,7 +13,7 @@ The following list summarizes some of these updates: * **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increase the developer experience. * **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. * Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. -* **New features**: We added a couple of new features which users have been requesting for. For example: +* **New features**: We added lots of new features which users have been requesting for. For example: * Stream and process large CSV data * General bug fixes and improvements * Better error messages @@ -28,11 +28,11 @@ Update your function and/or method names to use camelCase instead of snake\_case ```javascript read_csv ==> readCSV -to_json ==> toJSON +to_json ==> toCSV drop_duplicates ==> dropDuplicates ``` -**Note:** that your code editor will generally suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. +**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. ### Functions and Methods argument structure @@ -40,7 +40,7 @@ Another major breaking change of v1, is that the structure of arguments/paramete In general, it is important to understand our thought process behind this, so, here goes: -Assuming we take the method called _**rename**_, which takes the required argument **mapper**, as well as, an optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: +Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: ``` rename( { mapper, axis, inplace } ) => DataFrame From 14a89eea3b7ede17bfb28f2f8e3f32836320d49c Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Oct 2022 16:29:41 +0100 Subject: [PATCH 187/202] update version number --- .../dataframe/creating-a-dataframe.md | 8 ++-- .../dataframe/danfo.dataframe.diff.md | 8 ++-- .../dataframe/danfo.dataframe.pctChange.md | 8 ++-- api-reference/dataframe/dataframe.to_csv.md | 2 +- api-reference/dataframe/dataframe.to_json.md | 2 +- api-reference/input-output/danfo.read_csv.md | 4 +- .../input-output/danfo.read_excel.md | 4 +- api-reference/input-output/danfo.read_json.md | 4 +- api-reference/input-output/danfo.to_csv.md | 2 +- api-reference/input-output/danfo.to_json.md | 2 +- api-reference/plotting/bar-charts.md | 4 +- api-reference/plotting/histograms.md | 2 +- api-reference/plotting/line-charts.md | 6 +-- api-reference/plotting/pie-charts.md | 4 +- api-reference/plotting/scatter-plots.md | 4 +- api-reference/plotting/violin-plots.md | 4 +- api-reference/series/creating-a-series.md | 4 +- getting-started.md | 38 +++++++++---------- release-notes.md | 2 +- 19 files changed, 56 insertions(+), 56 deletions(-) diff --git a/api-reference/dataframe/creating-a-dataframe.md b/api-reference/dataframe/creating-a-dataframe.md index 56cac29..a325b56 100644 --- a/api-reference/dataframe/creating-a-dataframe.md +++ b/api-reference/dataframe/creating-a-dataframe.md @@ -40,7 +40,7 @@ df.print() - Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/danfo.dataframe.diff.md b/api-reference/dataframe/danfo.dataframe.diff.md index 259e6b6..d623940 100644 --- a/api-reference/dataframe/danfo.dataframe.diff.md +++ b/api-reference/dataframe/danfo.dataframe.diff.md @@ -45,7 +45,7 @@ df_new.print(); - + @@ -117,7 +117,7 @@ df_new.print(); - + @@ -191,7 +191,7 @@ df_new.print(); - + @@ -269,7 +269,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/danfo.dataframe.pctChange.md b/api-reference/dataframe/danfo.dataframe.pctChange.md index 1a39c69..99248a0 100644 --- a/api-reference/dataframe/danfo.dataframe.pctChange.md +++ b/api-reference/dataframe/danfo.dataframe.pctChange.md @@ -41,7 +41,7 @@ df_new.print(); - + @@ -109,7 +109,7 @@ df_new.print(); - + @@ -183,7 +183,7 @@ df_new.print(); - + @@ -261,7 +261,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index 72cac94..15e1236 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -49,7 +49,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 4de2c13..f467a79 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -62,7 +62,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index ce39331..54812bb 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index e5d68a0..ece901a 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -77,7 +77,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index cfd5535..ad28bcc 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index 72b28d0..cc9871f 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index ce72145..911c1bb 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index 617b8cc..e3b3546 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 4b98d4f..62751e4 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -135,7 +135,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index f883122..45ba114 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 1faf15c..b51e0c5 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -87,7 +87,7 @@ e - + Document @@ -132,7 +132,7 @@ If you have more than one pie chart to display, you can set the grid parameter, - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 29e7c21..67e85ba 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 69c0b3f..0827ca3 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -114,7 +114,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index fd7bc6c..f1f4740 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index f1717f2..0121553 100644 --- a/getting-started.md +++ b/getting-started.md @@ -39,7 +39,7 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs): ```markup - + ``` {% hint style="info" %} @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - + Document @@ -291,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -369,7 +369,7 @@ df.print() - Document + Document @@ -460,7 +460,7 @@ df.print() - Document + Document @@ -568,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -653,7 +653,7 @@ df.tensor.print() - Document + Document @@ -733,7 +733,7 @@ df.describe().print() - Document + Document @@ -806,7 +806,7 @@ df.print() - Document + Document @@ -876,7 +876,7 @@ df['A'].print() - Document + Document @@ -1293,7 +1293,7 @@ df.print() - Document + Document @@ -1382,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1600,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2213,7 +2213,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2265,7 +2265,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2360,7 +2360,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index da1ab0f..fa893d1 100644 --- a/release-notes.md +++ b/release-notes.md @@ -163,7 +163,7 @@ A simple example: - + Document From f30c2510e363f3d997581debc335d1c573aa0dbd Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Oct 2022 15:38:19 +0000 Subject: [PATCH 188/202] GitBook: [#226] No subject --- .gitbook/assets/419nr0t2zml.jpeg | Bin 27488 -> 0 bytes .gitbook/assets/b17076_cover.jpg | Bin 788502 -> 0 bytes .gitbook/assets/image (4).png | Bin 20104 -> 0 bytes .gitbook/assets/newplot (2) (2) (1).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot-1-.png | Bin 25882 -> 0 bytes .gitbook/assets/newplot-11-.png | Bin 25611 -> 0 bytes .gitbook/assets/newplot-13-.png | Bin 39004 -> 0 bytes .gitbook/assets/newplot-14-.png | Bin 12931 -> 0 bytes .gitbook/assets/newplot-15-.png | Bin 10876 -> 0 bytes .gitbook/assets/newplot-2- (1) (1) (1).png | Bin 0 -> 30776 bytes .gitbook/assets/newplot-23-.png | Bin 13536 -> 0 bytes .gitbook/assets/newplot-32-.png | Bin 67128 -> 0 bytes .gitbook/assets/newplot-5-.png | Bin 26223 -> 0 bytes .gitbook/assets/newplot-9-.png | Bin 18874 -> 0 bytes .../screen-shot-2020-08-11-at-12.34.08-am.png | Bin 122541 -> 0 bytes .../screen-shot-2020-08-11-at-12.38.30-am.png | Bin 153263 -> 0 bytes .../screen-shot-2021-02-14-at-7.22.16-pm.png | Bin 45524 -> 0 bytes .../dataframe/dataframe.sort_values.md | 12 +++++----- api-reference/plotting/bar-charts.md | 4 ++-- api-reference/plotting/histograms.md | 5 ++-- api-reference/plotting/line-charts.md | 6 ++--- api-reference/plotting/pie-charts.md | 9 ++++--- api-reference/plotting/scatter-plots.md | 4 ++-- api-reference/plotting/violin-plots.md | 9 +++---- ...ating-to-the-stable-version-of-danfo.js.md | 8 +++---- getting-started.md | 2 +- release-notes.md | 22 ++++++++++++++++-- 27 files changed, 47 insertions(+), 34 deletions(-) delete mode 100644 .gitbook/assets/419nr0t2zml.jpeg delete mode 100644 .gitbook/assets/b17076_cover.jpg delete mode 100644 .gitbook/assets/image (4).png create mode 100644 .gitbook/assets/newplot (2) (2) (1).png delete mode 100644 .gitbook/assets/newplot-1-.png delete mode 100644 .gitbook/assets/newplot-11-.png delete mode 100644 .gitbook/assets/newplot-13-.png delete mode 100644 .gitbook/assets/newplot-14-.png delete mode 100644 .gitbook/assets/newplot-15-.png create mode 100644 .gitbook/assets/newplot-2- (1) (1) (1).png delete mode 100644 .gitbook/assets/newplot-23-.png delete mode 100644 .gitbook/assets/newplot-32-.png delete mode 100644 .gitbook/assets/newplot-5-.png delete mode 100644 .gitbook/assets/newplot-9-.png delete mode 100644 .gitbook/assets/screen-shot-2020-08-11-at-12.34.08-am.png delete mode 100644 .gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png delete mode 100644 .gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png diff --git a/.gitbook/assets/419nr0t2zml.jpeg b/.gitbook/assets/419nr0t2zml.jpeg deleted file mode 100644 index 971413ad50071b608398c7551e0239d86f2cabb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27488 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 diff --git a/.gitbook/assets/b17076_cover.jpg b/.gitbook/assets/b17076_cover.jpg deleted file mode 100644 index 726b93975fa0f4ce1e945caadf90e2a89afa4306..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 788502 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

3asbLQP(U=Va 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%0A1Do4PB|KJ7fY5$?~Ays309W$8lRSdi$Di&m)=e} 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 YkSyyJ-CW^8lxx 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∓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

MihNsF=}1(*i3IoR)b$eqC>v?SjgKtRD0G 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

;+Yw>6)E$AqpJ0RVL>e+~fgb48lgWwX*n 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 aFSDGi+O`do{m;UG_T&E<4q*qs7XAzW9T^`0 diff --git a/.gitbook/assets/image (4).png b/.gitbook/assets/image (4).png deleted file mode 100644 index fc601b5be0dc8ccc0ab6b98a9d35d0bd4334f52f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20104 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 diff --git a/.gitbook/assets/newplot (2) (2) (1).png b/.gitbook/assets/newplot (2) (2) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..9f34611dd09a280c06d1a1f30b28dafc5f3936cb GIT binary patch literal 30776 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-1-.png b/.gitbook/assets/newplot-1-.png deleted file mode 100644 index 8ec8c53db0afdbeaa2534ef20bb14eda71a6f90d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25882 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 GPW}r=gwrJe diff --git a/.gitbook/assets/newplot-13-.png b/.gitbook/assets/newplot-13-.png deleted file mode 100644 index 3f01471a0990e8078d5bfb4ecf8dd640d3afcf4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39004 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot-23-.png b/.gitbook/assets/newplot-23-.png deleted file mode 100644 index 1fb937a2a36fe875f02b797c227d7618ce0eefd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13536 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 diff --git a/.gitbook/assets/newplot-32-.png b/.gitbook/assets/newplot-32-.png deleted file mode 100644 index 4ccee22453b3e73ce6006b05a2fcdad8208b9a15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67128 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 z 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 diff --git a/.gitbook/assets/newplot-5-.png b/.gitbook/assets/newplot-5-.png deleted file mode 100644 index 0c92dc78c47e65a23e566f00e1577a6d74c4e456..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26223 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 Y9b5gPV8c%MBN-km^OHwknqIu|AHM}5RsaA1 diff --git a/.gitbook/assets/newplot-9-.png b/.gitbook/assets/newplot-9-.png deleted file mode 100644 index 27d047f35fd6173821fbf2c5e99bc3a7c37ca355..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18874 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 diff --git a/.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png b/.gitbook/assets/screen-shot-2020-08-11-at-12.38.30-am.png deleted file mode 100644 index 3a2cff59ec8ea308050242ca275b83c7658e545f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153263 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


&$}-i#F~ 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 z

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 V-AB);3%S=GWd)5(d2%-%{V&z0yWs!; diff --git a/.gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png b/.gitbook/assets/screen-shot-2021-02-14-at-7.22.16-pm.png deleted file mode 100644 index d0e4ab156d02124918aad2b5435958cc8bb7c5e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45524 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 configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| +| Parameters | Type | Description | Default | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | +| **by** | Object | This key can be either a single column name or a single array of the same length as the calling DataFrame. | | +| options | Object |

Optional configuration:

ascending: Order of sorting

inplace: Boolean indicating whether to perform the operation inplace or not. Defaults to false

|

{

ascending: true, inplace: false

}

| ## **Examples** @@ -86,9 +86,9 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ -20 │ 34 │ 20 ║ +║ 0 │ 47.3 │ 6 │ 30 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 47.3 │ 6 │ 30 ║ +║ 2 │ -20 │ 34 │ 20 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────╢ ║ 1 │ 30 │ 5 │ 3 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index e3b3546..7934ba3 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -35,7 +35,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti ``` -![](<../../.gitbook/assets/newplot (6).png>) +![](../../.gitbook/assets/newplot-6-.png) ### Bar plot on DataFrame @@ -64,7 +64,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti ``` -![](<../../.gitbook/assets/newplot (7).png>) +![](../../.gitbook/assets/newplot-7-.png) {% hint style="info" %} To customize plots, see the [Customizing your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index 62751e4..e19c892 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -42,7 +42,6 @@ function App() { } export default App; - ``` {% endtab %} @@ -80,7 +79,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (10).png>) +![](../../.gitbook/assets/newplot-10-.png) ### Customized Histogram plots on DataFrame @@ -169,7 +168,7 @@ a {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (20).png>) +![](../../.gitbook/assets/newplot-20-.png) {% hint style="info" %} For more configuration options for Histograms, see the [Plotly](https://plotly.com/javascript/histograms/) doc. diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 45ba114..9a4469a 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -35,7 +35,7 @@ description: >- ``` -![](<../../.gitbook/assets/newplot (4).png>) +![](../../.gitbook/assets/newplot-4-.png) ### Line plots on DataFrame @@ -67,7 +67,7 @@ The example below shows the plot of column values against a common x-axis (index ``` -![](<../../.gitbook/assets/newplot (2) (2).png>) +![](<../../.gitbook/assets/newplot (2) (2) (1).png>) The example below shows how to plot two columns in a DataFrame against each other. @@ -105,7 +105,7 @@ The example below shows how to plot two columns in a DataFrame against each othe ``` -![](<../../.gitbook/assets/newplot (3).png>) +![](../../.gitbook/assets/newplot-3-.png) {% hint style="info" %} To customize your plots, see the [Customize your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index b51e0c5..89c6a1c 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -39,7 +39,6 @@ function App() { } export default App; - ``` {% endtab %} @@ -75,7 +74,7 @@ e {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (12).png>) +![](../../.gitbook/assets/newplot-12-.png) ### Multiple Pie Chart from Columns in a DataFrame @@ -117,13 +116,13 @@ e ``` -![](<../../.gitbook/assets/newplot (21).png>) +![](../../.gitbook/assets/newplot-21-.png) ### Configure Position of Pie Charts If you have more than one pie chart to display, you can set the grid parameter, and also the position of each pie. - For example, in the snippet below, we set the `grid` to 2 by 2 and also pass a set of row and column index positions. Each row/column position index corresponds to each pie. +For example, in the snippet below, we set the `grid` to 2 by 2 and also pass a set of row and column index positions. Each row/column position index corresponds to each pie. ```markup @@ -163,7 +162,7 @@ If you have more than one pie chart to display, you can set the grid parameter, ``` -![](<../../.gitbook/assets/newplot (22).png>) +![](../../.gitbook/assets/newplot-22-.png) {% hint style="info" %} For more configuration options for Pie Charts, see the [Plotly](https://plotly.com/javascript/pie-charts/) style doc. diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 67e85ba..61f6815 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -45,7 +45,7 @@ In the example below, we use the titanic dataset, to show a close to real-world ``` -![](<../../.gitbook/assets/newplot-8- (1) (1).png>) +![](<../../.gitbook/assets/newplot-8- (1).png>) ### More Examples @@ -85,7 +85,7 @@ In the example below, we use the titanic dataset, to show a close to real-world ``` -![](<../../.gitbook/assets/newplot (19).png>) +![](../../.gitbook/assets/newplot-19-.png) {% hint style="info" %} To customize your plots, see the [Customize your plot page](configuring-your-plots.md) diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 0827ca3..73ba658 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -64,7 +64,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (25).png>) +![](../../.gitbook/assets/newplot-25-.png) ### Box plots on a DataFrame @@ -101,7 +101,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -141,7 +140,7 @@ export default App; {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (26).png>) +![](../../.gitbook/assets/newplot-26-.png) ### Box plot for selected columns in a DataFrame @@ -177,7 +176,6 @@ function App() { } export default App; - ``` {% endcode %} {% endtab %} @@ -211,12 +209,11 @@ export default App; - ``` {% endtab %} {% endtabs %} -![](<../../.gitbook/assets/newplot (27).png>) +![](../../.gitbook/assets/newplot-27-.png) {% hint style="info" %} To customize your plots, see the [Configuring your plot page](configuring-your-plots.md) diff --git a/examples/migrating-to-the-stable-version-of-danfo.js.md b/examples/migrating-to-the-stable-version-of-danfo.js.md index c186782..9f3869f 100644 --- a/examples/migrating-to-the-stable-version-of-danfo.js.md +++ b/examples/migrating-to-the-stable-version-of-danfo.js.md @@ -13,7 +13,7 @@ The following list summarizes some of these updates: * **Typescript support:** This new version has been completely re-written using Typescript. This means we now have well-defined types that increase the developer experience. * **Standard naming convention:** Functions, methods, classes, and variable names have been standardized to follow JavaScript best practices. * Standardize function argument: Functions and methods have been updated to accept arguments and parameters intuitively resulting in improved developer experience. -* **New features**: We added lots of new features which users have been requesting for. For example: +* **New features**: We added a couple of new features which users have been requesting for. For example: * Stream and process large CSV data * General bug fixes and improvements * Better error messages @@ -28,11 +28,11 @@ Update your function and/or method names to use camelCase instead of snake\_case ```javascript read_csv ==> readCSV -to_json ==> toCSV +to_json ==> toJSON drop_duplicates ==> dropDuplicates ``` -**Note:** that your code editor auto-complete will general suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. +**Note:** that your code editor will generally suggest the new function or method names, so it will be easier to update to the new names. If using Typescript, then it is even easier as the TS compiler will show you warnings. ### Functions and Methods argument structure @@ -40,7 +40,7 @@ Another major breaking change of v1, is that the structure of arguments/paramete In general, it is important to understand our thought process behind this, so, here goes: -Assuming we take the method called _**rename**_, which takes required object mapper, as well as, optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: +Assuming we take the method called _**rename**_, which takes the required argument **mapper**, as well as, an optional configuration argument. In pre-v1 version of Danfojs, the function signature is as follows: ``` rename( { mapper, axis, inplace } ) => DataFrame diff --git a/getting-started.md b/getting-started.md index e6d019f..99afb7d 100644 --- a/getting-started.md +++ b/getting-started.md @@ -2284,7 +2284,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe ``` -![](<.gitbook/assets/newplot-2- (1) (1).png>) +![](<.gitbook/assets/newplot-2- (1) (1) (1).png>) ### Getting data in/out diff --git a/release-notes.md b/release-notes.md index fa893d1..16a0cd7 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,24 @@ # Release Notes -### \[LATEST] Release Node (v1.0.3), Browser (v1.0.3) +### \[LATEST] Release Node (v1.1.2), Browser (v1.1.2) + +**Date:** 12th October 2022 + +#### What's Changed + +* Fix copy/paste error in df.apply documentation by @kgeis in https://github.com/javascriptdata/danfojs/pull/469 +* Makes an ESM bundle using esbuild by @dcrescim in https://github.com/javascriptdata/danfojs/pull/447 +* Fix invalid assert.throws statements by @igonro in https://github.com/javascriptdata/danfojs/pull/419 +* Allow Series.append() to use zero, fixes #486 by @BowTiedAztec in https://github.com/javascriptdata/danfojs/pull/487 +* Add error handler for io functions by @risenW in https://github.com/javascriptdata/danfojs/pull/503 +* add support for excel parsing options arg by @risenW in https://github.com/javascriptdata/danfojs/pull/505 +* Chore/add default support for datetime by @risenW in https://github.com/javascriptdata/danfojs/pull/511 + +#### Contributors: @risenW @BowTiedAztec @kgeis + +**Full Changelog**: https://github.com/javascriptdata/danfojs/compare/v1.1.1...v1.1.2 + +### Release Node (v1.0.3), Browser (v1.0.3) **Date:** 8th March 2022 @@ -13,7 +31,7 @@ * fix(test): Explicit type in test allows TS to compile by @NeonSpork in https://github.com/javascriptdata/danfojs/pull/411 * Jan kaul esmodule by @risenW in https://github.com/javascriptdata/danfojs/pull/415 -#### Contributors: @risenW @steveoni @adamgilman @igonro @NeonSpork +#### Contributors: @risenW @steveoni @adamgilman @igonro @NeonSpork **Full Changelog**: https://github.com/javascriptdata/danfojs/compare/v1.0.2...v1.0.3 From 1a56d9b9a164708579ef953511807fad19aa7619 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Wed, 12 Oct 2022 15:42:41 +0000 Subject: [PATCH 189/202] GitBook: [#227] No subject --- api-reference/input-output/danfo.read_excel.md | 10 ++++------ api-reference/input-output/danfo.to_excel.md | 8 ++++---- api-reference/plotting/line-charts.md | 2 +- getting-started.md | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index ece901a..65fd184 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -6,10 +6,10 @@ description: Reads a JSON file from local or remote location into a DataFrame. > danfo.**readExcel**(source, options) -| Parameters | Type | Description | -| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| source | string | **source** : string, URL or local file path to Excel file. | -| options | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

}

| +| Parameters | Type | Description | +| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| source | string | **source** : string, URL or local file path to Excel file. | +| options | Object |

{

sheet : string, (Optional) Name of the sheet which u want to parse. Default will be the first sheet.
method: The HTTP method to use.

headers: Additional headers to send with the request if reading JSON from remote url. Supports all the node-fetch options in Nodejs, and all fetch options in browsers.

frameConfig: Optional arguments passed when creating the DataFrame. e.g column names, index. etc.

parsingOptions: supports all xlsx options. See https://docs.sheetjs.com/docs/api/parse-options

}

| ### Example @@ -62,8 +62,6 @@ load_process_data() {% endtab %} {% endtabs %} - - ### **Reading an input file object in the browser** By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web/API/File), you can load Excel files in the browser in DataFrames/Series diff --git a/api-reference/input-output/danfo.to_excel.md b/api-reference/input-output/danfo.to_excel.md index 1192a55..146f70c 100644 --- a/api-reference/input-output/danfo.to_excel.md +++ b/api-reference/input-output/danfo.to_excel.md @@ -8,10 +8,10 @@ description: >- > danfo.**toExcel**(data, options) -| **Parameters** | Type | Description | Default | -| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | -| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| +| **Parameters** | Type | Description | Default | +| -------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| _**data**_ | Series or DataFrame | The Series or DataFrame to write to CSV | | +| **options** | object, optional |

Configuration object:

{

filePath: Local file path to write the CSV file to. If not specified, the CSV will be returned as a string. Only needed in Nodejs version
fileName: The name of the file to download as. Only needed in the browser environment.
sheetName: Name to call the excel sheet.

writingOptions: Supports all xlsx write options. See https://docs.sheetjs.com/docs/api/write-options

}

|

{
filePath: "./output.xlsx",
sheetName: "Sheet1"

}

| The **toExcel** function can be used to write out a DataFrame or Series to Excel (**.xlsx**) file. The output format will depend on the environment. In the following examples, we show you how to write/download an Excel file from Node and Browser environments. diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index 9a4469a..f37e09a 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -67,7 +67,7 @@ The example below shows the plot of column values against a common x-axis (index ``` -![](<../../.gitbook/assets/newplot (2) (2) (1).png>) +![](<../../.gitbook/assets/newplot (2) (2).png>) The example below shows how to plot two columns in a DataFrame against each other. diff --git a/getting-started.md b/getting-started.md index 99afb7d..0aabc1a 100644 --- a/getting-started.md +++ b/getting-started.md @@ -2253,7 +2253,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. ``` -![](<.gitbook/assets/newplot-29- (2).png>) +![](<.gitbook/assets/newplot-29- (2) (1).png>) On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html#pandas.DataFrame.plot)method exposes various [plot types](api-reference/plotting/). And by default, all columns are plotted unless specified otherwise. @@ -2284,7 +2284,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe ``` -![](<.gitbook/assets/newplot-2- (1) (1) (1).png>) +![](<.gitbook/assets/newplot-2- (1) (1).png>) ### Getting data in/out From 1224b1bca7f9acd60ebe391f0b07b9933d4b1ec9 Mon Sep 17 00:00:00 2001 From: Ian Zhang <1217021+ian-zy@users.noreply.github.com> Date: Tue, 8 Nov 2022 10:31:29 +0000 Subject: [PATCH 190/202] fix example output of addColumn --- getting-started.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/getting-started.md b/getting-started.md index 0aabc1a..90c21c9 100644 --- a/getting-started.md +++ b/getting-started.md @@ -1341,13 +1341,13 @@ df.print() ╔════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╗ ║ │ A │ B │ C │ D ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 0 │ 1 │ 2 │ 3 │ 25 ║ +║ 0 │ 30 │ 34 │ 20 │ 1 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 1 │ 4 │ 5 │ 6 │ 35 ║ +║ 1 │ 1 │ 4 │ 20 │ 2 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 2 │ 20 │ 30 │ 40 │ 45 ║ +║ 2 │ 2 │ 5 │ 30 │ 3 ║ ╟────────────┼───────────────────┼───────────────────┼───────────────────┼───────────────────╢ -║ 3 │ 39 │ 89 │ 78 │ 55 ║ +║ 3 │ 3 │ 6 │ 40 │ 4 ║ ╚════════════╧═══════════════════╧═══════════════════╧═══════════════════╧═══════════════════╝ ``` From 5fdb08266746c4ac11fc7ee796470300c85a5e13 Mon Sep 17 00:00:00 2001 From: colored <10601293+colord@users.noreply.github.com> Date: Thu, 26 Jan 2023 00:34:45 -0800 Subject: [PATCH 191/202] Fix Reading from a CSV File Rename read_csv to new naming: readCSV --- getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started.md b/getting-started.md index 0aabc1a..9daf3a8 100644 --- a/getting-started.md +++ b/getting-started.md @@ -2368,7 +2368,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 2f1a3f5..320170e 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -82,7 +82,7 @@ console.log(jsonObjRow); let df = new dfd.DataFrame(data); - const csv = df.to_csv({ download: false }); + const csv = df.toCSV({ download: false }); console.log(csv); diff --git a/api-reference/input-output/README.md b/api-reference/input-output/README.md index e86d5de..310be54 100644 --- a/api-reference/input-output/README.md +++ b/api-reference/input-output/README.md @@ -8,11 +8,11 @@ description: Functions for reading tabular/structured data into DataFrame/Series | \`\` | | | ----------------------------------- | -------------------------------------------------------- | -| [`read_csv`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | +| [`readCSV`](danfo.read_csv.md) | Read a comma-separated values (csv) file into DataFrame. | | [`read_excel`](danfo.read_excel.md) | Read an Excel values (xlsx) file into DataFrame. | -| [`read_json`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | -| [to_csv](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | +| [`readJSON`](danfo.read_json.md) | Read a JSON values (json) file into DataFrame. | +| [toCSV](danfo.to_csv.md) | Writes a DataFrame/Series to CSV file | | [to_excel](danfo.to_excel.md) | Writes a DataFrame/Series to Excel file | -| [to_json](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | +| [toJSON](danfo.to_json.md) | Writes a DataFrame/Series to JSON file | -Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.to_csv()`](../dataframe/dataframe.to_csv.md)) +Writing to `CSV` and `JSON` can also be done directly from DataFrame or Series objects (e.g. [`DataFrame.toCSV()`](../dataframe/dataframe.to_csv.md)) diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 73ba658..0ccb71b 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -122,7 +122,7 @@ export default App;
Document + Document @@ -85,7 +85,7 @@ df.print() - Document + Document @@ -142,7 +142,7 @@ df.ctypes.print() - Document + Document @@ -220,7 +220,7 @@ df.print() - Document + Document diff --git a/api-reference/dataframe/danfo.dataframe.diff.md b/api-reference/dataframe/danfo.dataframe.diff.md index d623940..3b15c8a 100644 --- a/api-reference/dataframe/danfo.dataframe.diff.md +++ b/api-reference/dataframe/danfo.dataframe.diff.md @@ -45,7 +45,7 @@ df_new.print(); - + @@ -117,7 +117,7 @@ df_new.print(); - + @@ -191,7 +191,7 @@ df_new.print(); - + @@ -269,7 +269,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/danfo.dataframe.pctChange.md b/api-reference/dataframe/danfo.dataframe.pctChange.md index 99248a0..542029f 100644 --- a/api-reference/dataframe/danfo.dataframe.pctChange.md +++ b/api-reference/dataframe/danfo.dataframe.pctChange.md @@ -41,7 +41,7 @@ df_new.print(); - + @@ -109,7 +109,7 @@ df_new.print(); - + @@ -183,7 +183,7 @@ df_new.print(); - + @@ -261,7 +261,7 @@ df_new.print(); - + diff --git a/api-reference/dataframe/dataframe.to_csv.md b/api-reference/dataframe/dataframe.to_csv.md index b4429c0..101cb4b 100644 --- a/api-reference/dataframe/dataframe.to_csv.md +++ b/api-reference/dataframe/dataframe.to_csv.md @@ -53,7 +53,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/dataframe/dataframe.to_json.md b/api-reference/dataframe/dataframe.to_json.md index 320170e..3a6f4db 100644 --- a/api-reference/dataframe/dataframe.to_json.md +++ b/api-reference/dataframe/dataframe.to_json.md @@ -66,7 +66,7 @@ console.log(jsonObjRow); - + Document diff --git a/api-reference/input-output/danfo.read_csv.md b/api-reference/input-output/danfo.read_csv.md index 54812bb..c389d5d 100644 --- a/api-reference/input-output/danfo.read_csv.md +++ b/api-reference/input-output/danfo.read_csv.md @@ -66,7 +66,7 @@ dfd.readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-ch - + Document @@ -106,7 +106,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_excel.md b/api-reference/input-output/danfo.read_excel.md index 65fd184..75d2fe2 100644 --- a/api-reference/input-output/danfo.read_excel.md +++ b/api-reference/input-output/danfo.read_excel.md @@ -40,7 +40,7 @@ load_process_data() - + Document @@ -75,7 +75,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.read_json.md b/api-reference/input-output/danfo.read_json.md index ad28bcc..3fd26e6 100644 --- a/api-reference/input-output/danfo.read_json.md +++ b/api-reference/input-output/danfo.read_json.md @@ -61,7 +61,7 @@ dfd.readJSON("https://raw.githubusercontentdatasets/master/finance-charts-apple. - + Document @@ -99,7 +99,7 @@ By specifying a valid [file object](https://developer.mozilla.org/en-US/docs/Web - + Document diff --git a/api-reference/input-output/danfo.to_csv.md b/api-reference/input-output/danfo.to_csv.md index cc9871f..9798a11 100644 --- a/api-reference/input-output/danfo.to_csv.md +++ b/api-reference/input-output/danfo.to_csv.md @@ -48,7 +48,7 @@ Abs,Count,country code - + Document diff --git a/api-reference/input-output/danfo.to_json.md b/api-reference/input-output/danfo.to_json.md index 911c1bb..18816d7 100644 --- a/api-reference/input-output/danfo.to_json.md +++ b/api-reference/input-output/danfo.to_json.md @@ -58,7 +58,7 @@ console.log(jsonObj); - + Document diff --git a/api-reference/plotting/bar-charts.md b/api-reference/plotting/bar-charts.md index 7934ba3..5dab386 100644 --- a/api-reference/plotting/bar-charts.md +++ b/api-reference/plotting/bar-charts.md @@ -17,7 +17,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + Document @@ -46,7 +46,7 @@ A bar plot presents categorical data with rectangular bars with lengths proporti - + diff --git a/api-reference/plotting/histograms.md b/api-reference/plotting/histograms.md index e19c892..c2691cb 100644 --- a/api-reference/plotting/histograms.md +++ b/api-reference/plotting/histograms.md @@ -134,7 +134,7 @@ a - + Document diff --git a/api-reference/plotting/line-charts.md b/api-reference/plotting/line-charts.md index f37e09a..89a2aea 100644 --- a/api-reference/plotting/line-charts.md +++ b/api-reference/plotting/line-charts.md @@ -17,7 +17,7 @@ description: >- - + Document @@ -48,7 +48,7 @@ The example below shows the plot of column values against a common x-axis (index - + Document @@ -79,7 +79,7 @@ The example below shows how to plot two columns in a DataFrame against each othe - + Document diff --git a/api-reference/plotting/pie-charts.md b/api-reference/plotting/pie-charts.md index 89c6a1c..096de25 100644 --- a/api-reference/plotting/pie-charts.md +++ b/api-reference/plotting/pie-charts.md @@ -86,7 +86,7 @@ e - + Document @@ -131,7 +131,7 @@ For example, in the snippet below, we set the `grid` to 2 by 2 and also pass a s - + Document diff --git a/api-reference/plotting/scatter-plots.md b/api-reference/plotting/scatter-plots.md index 61f6815..55e6a39 100644 --- a/api-reference/plotting/scatter-plots.md +++ b/api-reference/plotting/scatter-plots.md @@ -19,7 +19,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document @@ -56,7 +56,7 @@ In the example below, we use the titanic dataset, to show a close to real-world - + Document diff --git a/api-reference/plotting/violin-plots.md b/api-reference/plotting/violin-plots.md index 0ccb71b..3609a01 100644 --- a/api-reference/plotting/violin-plots.md +++ b/api-reference/plotting/violin-plots.md @@ -44,7 +44,7 @@ export default App; - + Document @@ -113,7 +113,7 @@ export default App; - + Document diff --git a/api-reference/series/creating-a-series.md b/api-reference/series/creating-a-series.md index f1f4740..ef11bc8 100644 --- a/api-reference/series/creating-a-series.md +++ b/api-reference/series/creating-a-series.md @@ -31,7 +31,7 @@ df.print() - Document + Document @@ -88,7 +88,7 @@ df.print() - Document + Document diff --git a/getting-started.md b/getting-started.md index a656385..b0510f1 100644 --- a/getting-started.md +++ b/getting-started.md @@ -39,7 +39,7 @@ yarn add danfojs For use directly in HTML files, you can add the latest script tag from [JsDelivr](https://www.jsdelivr.com/package/npm/danfojs): ```markup - + ``` {% hint style="info" %} @@ -70,7 +70,7 @@ import * as dfd from "danfojs-node" - + @@ -120,7 +120,7 @@ s.print() - Document + Document @@ -181,7 +181,7 @@ s.print() - + Document @@ -242,7 +242,7 @@ df.print() - + Document @@ -291,7 +291,7 @@ df.ctypes.print() - Document + Document @@ -369,7 +369,7 @@ df.print() - Document + Document @@ -460,7 +460,7 @@ df.print() - Document + Document @@ -568,7 +568,7 @@ let dates = new dfd.dateRange({ - Document + Document @@ -653,7 +653,7 @@ df.tensor.print() - Document + Document @@ -733,7 +733,7 @@ df.describe().print() - Document + Document @@ -806,7 +806,7 @@ df.print() - Document + Document @@ -876,7 +876,7 @@ df['A'].print() - Document + Document @@ -1293,7 +1293,7 @@ df.print() - Document + Document @@ -1382,7 +1382,7 @@ df_drop.print() - Document + Document @@ -1600,7 +1600,7 @@ df.mean().print() //defaults to column (1) axis - Document + Document @@ -2213,7 +2213,7 @@ Using the `plot` API, you can make interactive plots from DataFrame and Series. - + Document @@ -2265,7 +2265,7 @@ On a DataFrame, the [`plot()`](https://pandas.pydata.org/pandas-docs/stable/refe - + Document @@ -2360,7 +2360,7 @@ dfd.readCSV("/home/Desktop/titanic.csv") - + Document diff --git a/release-notes.md b/release-notes.md index 16a0cd7..934d0f9 100644 --- a/release-notes.md +++ b/release-notes.md @@ -181,7 +181,7 @@ A simple example: - + Document From 1361cba82bd179b92d44e0d38cd8705883161672 Mon Sep 17 00:00:00 2001 From: Rising Odegua Date: Thu, 3 Apr 2025 23:47:59 +0100 Subject: [PATCH 202/202] update release notes --- release-notes.md | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/release-notes.md b/release-notes.md index 934d0f9..9450854 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,24 @@ # Release Notes -### \[LATEST] Release Node (v1.1.2), Browser (v1.1.2) +### \[LATEST] Release Node (v1.2.0), Browser (v1.2.0) + +**Date:** 3rd April 2025 + +#### What's Changed + +* Upgrade of SheetJS dependency +* fix: replace does not accept falsy strings or numbers +* Adds function overload to NDFrame toCSV and toJSON so danfojs-base and danfojs-browser can use the same code +* Better error handling for io functions +* Update io.excel.ts to use default values for options +* fix dtypes not used on csv parse +* fix isEmpty bug with bigInt + +#### Contributors: @risenW @BowTiedAztec @kgeis @geoextra @pensono @acctsi1 @babennettdev @kitfit-dave @ekynoxe @nucoinha @lyhue1991 + +**Full Changelog**: https://github.com/javascriptdata/danfojs/releases/tag/v1.2.0 + +### Release Node (v1.1.2), Browser (v1.1.2) **Date:** 12th October 2022 @@ -110,17 +128,14 @@ Minor patch update for column name display after aggregation functions like sum, * Add loc indexing support for Series * Add configuration support for formating DataFrame display in the console * New DataFrame `applyMap` function for element-wise apply function -* `and` and `or` logical comparison support. E.g\ - `df.loc({`\ - `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ - `})` +* `and` and `or` logical comparison support. E.g`df.loc({``rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))``})` * `read_csv` now uses [Papaparse](https://www.papaparse.com) and supports config values for headers, separator, etc. * `to_csv` , `to_json` and `to_excel` functions now support saving to local disk in Node and downloadable in the browser. Also, supports config parameters for output. * `read_json` now supports config values for headers, authentication, separator, etc. * `read_excel` now uses [XLSX](https://www.npmjs.com/package/xlsx) parser, hence supports all XLSX config options. -* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g\ - `df.query({`\ - `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))`\ +* DataFrame `query` function now accepts boolean masks with single or multiple conditions. E.g + `df.query({` + `rows: df['Salary_in_1000'].gte(100)).and(df['Age'].gt(60))` `})` **Bug Fixes** @@ -138,7 +153,7 @@ Contributors [@risenW](https://github.com/risenW) **Date:** 30th May 2021 -\[Bug Fixes]: [#206](https://github.com/opensource9ja/danfojs/issues/206) [#203](https://github.com/opensource9ja/danfojs/issues/203) [#200](https://github.com/opensource9ja/danfojs/issues/200) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#188](https://github.com/opensource9ja/danfojs/issues/188) [#181](https://github.com/opensource9ja/danfojs/issues/181) [#175](https://github.com/opensource9ja/danfojs/issues/175) [#183](https://github.com/opensource9ja/danfojs/issues/183) [#168](https://github.com/opensource9ja/danfojs/issues/168)\ +\[Bug Fixes]: [#206](https://github.com/opensource9ja/danfojs/issues/206) [#203](https://github.com/opensource9ja/danfojs/issues/203) [#200](https://github.com/opensource9ja/danfojs/issues/200) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#198](https://github.com/opensource9ja/danfojs/issues/198) [#188](https://github.com/opensource9ja/danfojs/issues/188) [#181](https://github.com/opensource9ja/danfojs/issues/181) [#175](https://github.com/opensource9ja/danfojs/issues/175) [#183](https://github.com/opensource9ja/danfojs/issues/183) [#168](https://github.com/opensource9ja/danfojs/issues/168) \[Patches] [#191](https://github.com/opensource9ja/danfojs/issues/191) [#161](https://github.com/opensource9ja/danfojs/issues/161) [#206](https://github.com/opensource9ja/danfojs/issues/206) Contributors [@risenW](https://github.com/risenW) [@steveoni](https://github.com/steveoni) [@jpjagt](https://github.com/jpjagt) [@sponsfreixes](https://github.com/sponsfreixes) [@bherbruck](https://github.com/bherbruck) [@woosuk288](https://github.com/woosuk288) and [@adithyaakrishna](https://github.com/adithyaakrishna) @@ -209,7 +224,7 @@ A simple example: }) - +

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 V-AB);3%S=GWd)5(d2%-%{V&z0yWs!; literal 0 HcmV?d00001 diff --git a/.gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png b/.gitbook/assets/Screen Shot 2021-02-14 at 7.22.16 PM.png new file mode 100644 index 0000000000000000000000000000000000000000..d0e4ab156d02124918aad2b5435958cc8bb7c5e7 GIT binary patch literal 45524 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (1) (1).png b/.gitbook/assets/newplot (1) (1).png new file mode 100644 index 0000000000000000000000000000000000000000..8ec8c53db0afdbeaa2534ef20bb14eda71a6f90d GIT binary patch literal 25882 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (11).png b/.gitbook/assets/newplot (11).png new file mode 100644 index 0000000000000000000000000000000000000000..e916b5c83cd83d60d5eb4979515ff184ce8cd082 GIT binary patch literal 25611 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 GPW}r=gwrJe literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (12).png b/.gitbook/assets/newplot (12).png new file mode 100644 index 0000000000000000000000000000000000000000..6f09ebce2278b5d69344480d0ba0f2bbb0037dc0 GIT binary patch literal 22859 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 MRn)p$C2t+^UkQT5W&i*H literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (20).png b/.gitbook/assets/newplot (20).png new file mode 100644 index 0000000000000000000000000000000000000000..4f2ac2e84e7b31a1dd278f9eed0e07c0e55562d2 GIT binary patch literal 22185 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 FzW}=EVX^=K literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (21).png b/.gitbook/assets/newplot (21).png new file mode 100644 index 0000000000000000000000000000000000000000..caf3da70cb5f66af25ada213e0b3d238e453b391 GIT binary patch literal 20622 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (22).png b/.gitbook/assets/newplot (22).png new file mode 100644 index 0000000000000000000000000000000000000000..b6aa9f1140bb5af026822d51e13c00dd72d9ef0a GIT binary patch literal 24563 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 bnSFaxj(m0GF2w}+AU0t&4K)feHX;83(`m?@ literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (23).png b/.gitbook/assets/newplot (23).png new file mode 100644 index 0000000000000000000000000000000000000000..1fb937a2a36fe875f02b797c227d7618ce0eefd0 GIT binary patch literal 13536 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (24).png b/.gitbook/assets/newplot (24).png new file mode 100644 index 0000000000000000000000000000000000000000..cd8f8b0259654d6c3826440a615b610a37a3202d GIT binary patch literal 15366 zcmeHuc|6qb`!0hTWXqae8)YpqvPZO9%9iYvlx;}N*v%(PCA8Q|wj^a6k)<)12t~GR z*~ZKuJ2MqC_VWzs^F8PMan2v-^*gWgI{j66zn|rP?&rR*`@XLCJyYXT9BjgD3=9k$ zXHK8I$iM)>GB7aKLU+)A6Cey{V31@ubMk~a(tdV`tINV76-JK9V3lX|)+Nawl(#Fh zJ?MO}O8E&vNb+6RA(1Dp$1i87Dd|?Du2^&2OyoFfrp)%sCHd_^-s1DR9sVs%#R0(% zEy=o{H>`;cS5A)3S1x*s@8BNAM^(;ixumz*H5<^LSGM8PheH2wg#I`BL%KZ>2)t)ZMeX;`42-B=(e0PH zKV8-(v|zA1PHn#|Nq)w(^&%MEnjMO@PU%hHAK!jZ@?mKhF2&cMBX)CtU_@Pl z%FaJaC>G#GmMEY<@NDk^iv7O*;NQ*uJ=rZM`|HMkF3jIMyB&A_2B`mt#)xDl6HUrV zWQ&_UZ@{k!O7YXTo#L*mWYK;RrD3JRKj%O5{zZ!udRk(AG$yp`>!ONb#vG)S3yT=?wW58L*1o_z&|9;< zP#+`&^R(p&Fwt7*QVLn6DP8$^SIL|7k>t{xC@)(`R&b~eDlgaW3f9}BL-&$n(q0SH zP%&-9&vP66Z>Lp!zFctndKY%A_hA+*_qQzFS*H1h7?EhNm4V@P)#tuF*2JapbS}i8 z_bHyRmBm?+h6j6iUm2xXuI_P=wak}UufEaoq8;s^V-~$>&Y34T)})O<+M0ywOjko@ zFxM`f)P?btu0j~EBzc&=evsYSe~!0tl@IyZs1d@LYM-gN-S^V)o$6{YacNU>?Ru@` z)|0PvYxI+z$HG*%)7O`0>Vs?aBX_a3X|Lojo!rdMm;*)r(`8<(2|9hVfuZYf5#jbL zRjc}4L+X!U7WM?f9j?MvA@$>7{X6kU6&Svz5=kME?$4zn@YaLrfs1`Ef>uFSX)#n< zthiP{jx5%$5mAh6HKLE*E$9_dzN~WWpC9a9+GKm*ZVO_g&boKS`to$Sm28NTe2DJs z&-9HTZ!S0%qv2E=P8y#h%5S{v(FfKwKZDc4TI42HTUul+qF~x6r@6uR^&ae$x|?yD zKTh*_UTxPJf9`XCKrB(g?y_cfCSo4%)D(Xx?W<{bU*Rw~f0;L7ImhDPDPa;~z*)et zQPinCv_cxD$f+)pq>ZPE;*kmER%rWrAEe8dWFE_c%NBgW?HMNwbQeYO?jbvOg>Sj_ zCtI)pMB{SxS6D%TU8U+rX>};(>4u?@_*SfVm-5HL%+qb~+6o5@Z+mPeG8aA;q zi__LHFS_?}YRR0Kezt!LDm~-jMy7P!l0#KNSIMZH+6M;I$l<~vQ_-boAv+^w+tgH7 zCwW3Y{)SN#55sT+QplVZGeVc*n#?MRQmVl**MgoE^nAXWxcVz9igQ zU}Qo`+~_Msh*htg<7*#_TN`mJZTmdK3i-7nd$2UZ!8{A};$`N{9* zM%pmH*#k)_bLTi^TkKxW&1LI%_FGL3SJBf0o1s~Z8p zGn=4EZ}S0eiIaXb@i}5J`M&pug`r#B=iu~JXJ~`hf?YjcdT^^Pb~cymJkFoKP3gEs z4f$#&+>e{*+Z^1n90Eb#JCP9qDbJ_b(Hwe*MS48G*}e;CM^)7d;t}pb!M_LsX$EGS zPlxF$gF%%q#~x_U!1+wW1Wql^`{>@8_Y(SjW6tUlj1J`4{W*Y(;E1wi?il~62wsBy zntgUn+P+d5d|<#sO&PpfxS>-rQdp#C@{Kcp6hur!3j+5 z44Yfyxy-FPNfH!WjDOs1^I1#xUx4B2b0>W!!4AJBo!-eBujg3TP(XZrE@`$* zQFdc7-iyGvlJFv3{Y1tTSZ}xN>y2!%mUGquse4V&0?(xXujxD}B=a*O%{ak?qQ33y z5DRWFVYbtN0`=IhiH?1mzxv)cPgeW7j8lHX&m+ z;1dzKs;r}j=)tNku|Ol#wO~9%s}`+@h=8@-7qO5AgK*#9h(8v(zUnm+1B;9ifkmci z1xBX8Lnb%8(GE4*U!EUV&bNJEOj{v*xKsE1xKAw(#iVgTaXkMnSnVUd$%Clf(4cF? z4c79tDXPZ8=qOA~xH@QY;B32wo#ex)Fr0`UtyZv_+p}hE(W}SWCF1SXMuAM&jse=` zBF7V#im#nXhQaM8I&(~tHT`c1so%bltQF`du8fm;3@*x*XSkD^vns}%D-&?qBycX{^Je!RyUoi1-v zmS0g@8MO3+TgRMW;D`YC+yBI7{At=}x`GRwE+~&|3tj(7Y+IjctJUYy;#(XJ-5?#F zpUg?OH^2EM`G`~hyPNgtl+r8p_et~70`hEY%L}q52NqtMgM)w5l&Q=tygNB?V2wj8 zY2`$xvG!4_l&}K_9p9m=7W<35h_&Q2Dpp$5fAkS?ePy0&czvIez0u2t*C~bfnMBn(9dFX6%R9 z)s!EYG;YK=4NVEH$);6=Zmf^ZTrvnaK(-I`pv@s_L<(!xmuC-DPP~Y&1wgWP@V!s8 zY$Y%?SJtUGg%G@N1cE}U&x8+GD+c;qF_V&;JN_kfxK6PhVS8H`N4#>b!v@-Lgh>`2|s9G6~O;Y z&>rc8q|^)6B~|~*=AI|USRtg(C!4N*(Za5%5~qH6mLKcN{@QRR!xz#M(_`&=4_8PB zdXy#1eBkg(?V+6K7d27Dw7@x53fuhg@#kjYL$r$G>~l#1CO0RBDiO&?o$u!yqiOZ$ zg~hm`PjX7?ItnsQM;4yjgsHhC7jn1$^J3O3=?P=(?J3hb9)PZr@FxU+~N{D8AYr(qCGz`FJ8c5 z-o}ODjS2kB%=VpkbRpm`^!)qD7KeG{kK#aQ0S`L0l&Wb3{!o~pq5zp>&KH?og@F8fP3sQIl#`os+eL1L(o*TZQ-4m_VDg8Zb^hb2f`!$~Q{)C%_1k@?jn8ISgD6vSC01G&hjHTMJ}qtf45#5aSmD)r zd^}vaRV@ozVTYnVbxC7&N%OzX6CS6%JaK#X<%0mBi&(KAQ8CCk2%_~fzJ4W*z4TW> z%fJgv6x9|y=cB=b7lC7s1W}?Lc5UXj6FbGac=k&lXwMIe$+JGv$SdhMq_h+Il2^uv zU{@XFPhl+OHPJjW7&u?$L?aUo7}m=}SIWtYT-an zs3KD=<#!&~4#s8+8X815hn36Uik+MN9+qRrlU4dwP(&f=s1#lx&Bv@?l_3Csc4k=sH`al zXJa|#JKYmul%g8J$h0HAGn-vQh5S)nNV5%n% zl@1%y@U;C=S+VMe_uR%7uRe+k+K-*Kn`fivL+`YO>E5WP$}W)!vQ`425}HV_WMvm) zAvG_@;*c8^%V4upz3ouwI~yFP!_#{_?+N{cvy<$F=iZN}k%6oERBq5Sxfo*bLinJd zL(mb;U+ww^++xbt&o{gAp$QFepFr^J{l!Yi{68%0wT};+tHt{N)JxY6t{wgSq^>^{`?7^li49s~ z-PJfP0RaWuZ#1Zg+O418Tj(taV!J*U#}OLmo}54EdmW73+eDQ zqWWj5SBpw-cnZAweYQnRoMs>>JEGw}(dCLWLdcPBJZQ*y)Z}8f5!sK?yNQ-k=mvLN z|L)Ek(0BS^U!2b4uk(Nf;kz)vk#AIhMqMrAPSK(&aZ1yCf2mt^QQ&N8ufWE;qvVFg zE65nDn31eD68~5suF_+m>_3}IFHG{R&Vs<$nd}<)u(4#$X7U^_a%8PiV&z+-UR#=0-P=ZS8_n1m!5W$Y^2cXsI`E6mtD%g8 zj@8Xcd5)a)kN|JlI;SWx%hPz@UOS=%I>170^5v8J@StcbWR6L?xM7^Q-70pPZJtyg ztv_5HT-Q@zLoI;dQ?qfzl0^QI0P+vBV$t*yJd*7J0E$c-`M7!mz}#@jjhF}gQFXKP9rT^0fmB0IfF zJD|P4%#9G!Moc|&)$mfOtHqH+0MhY&Z%v&(j;&ncpJcU@*jZmyNx9=jX`@d-j5iCK$Z>yi-DHginRoHc;({5$BfV7F!apPpl25^GS33- z_sf#t5moFnx>u6?{oXiWc* zKB|0()N17nO5vvNPHHiG{9f|hT|V?O{#LVmeF=PIBNjaptDz9I+?lRW&DfHM1^e=M z>wJ^OicNitZuJj#Y6W}?^L&Xj$-~B%c}l9o3?q+9KZGP!@h)B(lEx?jV$(cEd2olzU0<5 zC(eeQ6+q*cf}D&NTzg{0149rR@zcJsXPNN<2`@2O{K!0;N^>ni(69O4S?Iej{c@S> z{+<}iGp;V1eb5_EL8fz#?>lyFr0G@s=N(suP8-_vMHYx8$lJZqP#`B_G`pvs$K+jJ za6JY0u$?t6Ts)pH(p~6qA8!M@_}bMBK>o`h9l7ptR^{lcC_dy|jJgDS++kVfG;Qd7 z&T1-_9h#Ic-=vo%Dj*6T_F=&xdS5C9;02xNP{;NME(k z{p?eB$)1>N?-D$|VJ`H2O~8zRinZCSptY|emwuF>gy9@>O|QdTm|f1EsPf$hdIl`^ zJ{is+86{r0-uW;_Hs#_$k-NV8_INmplzEz$-Oiq?z}ZawFwgT*Ep+Y96RRrqF4ceE zKVIZ%UK#RMln2AWAo78(1vnG{A3B|xYXq3}zow}S`G3_MvlZSJdE)^o7YP&>2k7u~ zHO*Z*s}JLII{XX(V&a##C3)Jwb~E)B`J>7s4NO!<3u9z0R{9GHL0B2;&z^hlyRX#C zcc9$Uyxh-u<~`1)A=mt!iH7|fZx!?l19$K8k>_67uj*evRdE^ml%F9l6ziMCa`zeX zDIg{KFSKrnKi-LgCta8;t zKN+hP(ViIBUPXiX0+B=JrH6oWL!P(DyY#`)lt_2mzWAeky7?lXZ^#Z5`DPVo%lbC5 z;4dcSTuvx|Uw9RSgwcpysUwF(TJ&P0|Y#^^k>@6`dotL z+STw?m3zK4?S2K6B)}dG-A9|;g^Ruan&W?Mj*UD`x86by5mk3+lz6~|CwtkyY;M>^ z!FNx70Rt^Bgq6Mm)7S>UIg6W_gd{Zm&O=3fQn{(0)<~! z>pthDLlD~ckHinpUx#R!Jpj}|=H*#c7QAaOI=>1XOt34tZnOzgZ|0;5*so1lMMba+ zMy7aT-p~+LfmBX*0XgWoL^)P~zS)D9f3ZH1HsREd;^Y7&h=QAuMi06$Chw}47wIeL zv}em3HEJ9r`(c^0r@=+UJigYE37Ad0JleObaS=XkS}uKu)56rM=vB0F>;BhE)tu}ACDJ}8g#aCr@ zyKxr$?J^4wYeIqRSkn+3g-BYKv&X90`n0GJG1G;zbG`KHBw5wtGQ}mR;L_U{w3QbI z(Rwu@YfW}`Rny71X~oMIpRdq)p?ogm^BHU)=kw=w;k7|BUMOttW5$ae4&GR!M%65( z)Ub{;#IT#aI?qZcgtH7|*h;Rqu?Rrnz5}oplo(Sdj3Z*_Qp?i=Oy*MVO4;|tWG>Q1;<%FR111-XMC?Yiu#~B} za8_Qn>s0bwoqJw~&CplVtScf@+N?-Svo^(f>ADHxb8)_yggNMi1`S@q20MK#a;oPQ z!f4+WNdM;bNh&IQ>F0RVRzLNwiO1c>fV29I;~tY5fH|r@seWlUqY2{B8L6}1IKaP7 z7Y+|*1LqOCj>b&oCM76oXG&?mk@}Bb>XAD;IM{r~TNgy}Y$nTox9zqNq9kEbVZ+YA z1kvYj7>GH?SwkG#qYsvpm3?>kW107e;feAKMb9Lp$vr_3A#Ic=Xl-Cn-{qNw0g)mS zeoF{-9Yo!h8^;qFP%@xOCa;sBfkhve~a-4ZbU^?Fg0FwoEu1q~f= zlU?%0gxSAUxY`EkOSc<=Dhx)%#^^GE6J$EgDfK@!LH=&z?`iyXs{fDg#zoC*Ll|GD z&R0fGxG+YJ>N+Q10nj6RzuaJ)5eV8zbMO5HQHCIRRml|m2NSDyi%j_7)cX9m69I>c zp{c*phaj|Qx1(BDzup|y*(fBn0iqw@5kiOPv1!AfS-Ef6>JmH#n;tPgUVX*(&`LHCI$*&N zDzclwmwH9xKLul-oSPH*t&mBI4&p#9_o(pbWxO=1P&R+1>+}xz+%Nv`yPzDIh7cck zWldIAYTy7<{ZdY9(8*IPM*x|q5fCCR{ZLPrFcdwNeB^5FyPKVQtIE}u`Ij!N26wzL z$aJU)Ipq4nh%TO(2n*Xd`fE34<7gM^^LYGcz_eLO;>$d2gj8J3lU3X-g^u64<~=&q zomcnr%#+&M2zELSxS#I7sSR0RnHx}jw|wWu2Wadh zu{1`&y;qY+Y+q2b0C0B4Bt4Tte%CdOuEt# z2%3>Yth@*LPGO>8S$%Ms-?9*S`pL!n|95>Zu~+Axk`8f{(z=ySZwW#q1sPEY#e@g{ zwy?ZMGfv#0Q?*)Au%uyzk>A>?VnL7)PeAn z{2x_{97tr=hcmZS8}ymafDP`?7yeh3^1r=|M+rEL?{qB?1lEQzG8GFaeE=&mb_9^l z3CIuWUBXG@7tRnB;I3|$k#)xVibB?wm3+Q`DY`Y*L}I?PlZzAlz{<3f^SqBEk_?TEI5km&G?g~u<8|~uw2h?X?mVlgGfxgi(8~fT z{m6$vxQY`8J-{b-{-72aZuE?Cy0+GXEssbeE5q&brh5X# z2^4!k<{yPW&iWe^KKcEXIPFgRM>r@(QKTAdn(a-Tk2L>JP4 z)K&x%)ZUo}oe>?13jLA;vPoldDIH0==S63`xPk~wMD+R;`f=(sAP^5h)wmMc)x688NIR0AEyII zP&$Paty>L%z+O2nAtlM@KCQ>=S1|VU*yga*WTiI~xUs%g2ZA)cRJSF1%<_E|W`ytq z+CkP_&hCJ2Mk(aT4eiBmSBW5Qa?xvWJz^mmIq!zutqGVdQZlU{>+hpB7H>wEVb!hR zsnuSMVu*0M(7nFx3hseb^ziC;SXBDjj0-U{N}O$YZ4RLi=)(KyZGg%i4Eou!sjM#~ zrvb9cfEE+lV7hj;u~GIzC>0SZ=m}UVav`EB5Bh}?+K3AV)QA989I=oM`CvGY zpP-_>C?``Xq}U z`cV<9SLWDjmb=mS2Y5(%)Av1_P z^W@&@#nKn4cJy7(V<4jQVj)A*_T{`Mut~7U31mHuehs2m{$atJmz=Bwa~XlT=)5`u zDiN9w#N?~Xy*2pt6YmNQVea2d2UpYq=;Tg!7+4^du`5($&>q?Z)vsJ>j1^lc4n!gZ zk-hoWW`oy(W=~*#C`KYIdVa`^5S%?C5&Wxz3?fAZO&Z@{G$L#NCbnGZ<4;lVk37U^ zhgH&|L}Ole%~A_|ux{Y-(<~lfZy8|kx30_Q!*JT{A9D_T%*&vho%<}EF3PDfQ$(^Z zr9?}TW;rC*CQd~UFp*?K)Z}*z#|6(^CBDf?JDm2ITsgc}n28e^mKeD2u?YNu#xRg) zzmTi718=3Sy)GA0G^?{dqI2J;X4V5PJEs%t@civ?$O^yHa&fZ)`|!p(b+bhj7%?&{ zO!>@1v1D%}4vpW;0(k8(kaJnS^THT~;i_5lZORo^M|9S&@(93yD5L5v?L#S&MFlV1 zzOYP*3$-1T5RqUKa5!?l!BJG=kYB?d7rr=&Xo>SHy`gKpN}%_c^HBt?|6FG&)zZ^c9rLY7QnOtOo}zGg&Jwp1cpBqR*k_a&5l&Ay~$ zU$gI?bGq-l`}2KX&-WjAUY}p^8rSu{&g*@h%W)p(am|zK>PplH84r?>kWedMy{tt- zf+!^+A^n6RCw}72XiGxEPNIDIl8&q4+z_?njjq`BUve~li}r3Jr!Gew)YVfsCM5mt zz@ZUeQq6RYT1}(K?rU_W{t@SIb|i@8eww_Qb|RK=R+%E;ZN{Pcn`0Stu2#G?pLH*9 zMWSdQb2g|xMZcxFDw?y$Wb01pGk9u!Fs5XEJ-zFSLd(U8*;en84O8*Qo>l zE}=_B#SV%;rz6vkvoGpl4H*OeTme0jbmWf(sGI!gk-Xwk(ZhdT z4z7u>RAu|;>PVU_J$&U|CpSyxf6exZko{u}`|UgupPuQZ4#|H_MhJTSF$P^}MT*Gm z8cVwWugOTmtv|-#@m&a{VOpc==)WeTN>~0ELqhuB4fwAI{5J&tn*;uv1pmLR0wW3N zsq#dv;)TS(VGb_~Z)G;=%IcJn4k#D+0VoXxGa56r=t^TBUJaY@r6XyA?h#*q;;kcP zx<`4wFAcAKE`bf4tz2aJ@S7E$f(PaZ6yI;l}cg?f;*A-6=3J#C* z{P=xVG@KCHvpS^|B$plF3b* z@EA(n)%$%M^@e#^#L(y|ho)zNPt$vKdAssfpUa7;3H$RT{I1P3Mx+Q^ze`2LLK}~` zCFg+^4`+LIzxt?vq_@PGV+Qr#lfPc(-58i5y-cjGkF!X8BtFF(5bHLoJU#hn&S#vF zp9 zD@Gn7BKb~9<67z}`PVZ8S>F+IJ>6MOUK8LzFC``Mjs7D$?n9K1i4x{OPED{AUc z*ab&DUv=BIth9uP14Q5#Z$n(#-=Dm`wKbwSTB4CV!hlmLgjwjj^KhwKN0KT-eO=wN zD}l%B{V3^z7UM2@m~^M#G8?wFx6h`mV@9!$Bv*3n=P2p!?%`MFS$Vv@u=de7osws9 z<%MfFThB9Md8@+9g5-@ZJYMx`7J9)Xh>jd{4f=i#*tM>9gV+jv9UT)zM^zP-rkz3C z2g}iBHJIwmmS3@=mK{=DrB%yLevx45Af0Q*Qe>0onp5XuiS3DVlw|_HkO|YHB1@mx zTGVZBIxVaUTV0jYn6JJ9x#=51`plPhXVQrS3v?P6I5Nw(KBV8uN!HZFUF&4{%IdYE zDH4EDa>>cgZd!j`J+RjDnTIy(3L0a2V!0aAv{p5xuD;=zD#=EQG+?lkUG#Ux2hQa>|EQsC-z-LAd-h)>>|)r|{xmzas257M~KrSoOTllY(xUdS>_>03S5 zc2V8zowv}BnYsKmO()ic<)j5=C!4a@dcS&Ox%50JTOcVSV~(;fO5eE07)XN1IM&8c z`zoDJf&)`+`Y!+Qy*UTbixnTnb1AtrD9B)` zx0%6D8xN~)R$0+Gurw_-b=F@MtB-?=mWJ+fX|M$sY0vU-sb1Tf5^oU-P+vdamo|GW4s_(EsH> z?O;XHSmfYCo?DG{8Gn9H|1G_a=AN&k-}+|HT6CvVsxWmq1SV7rPNbnbDWqKXJL2JO zZYAy}?@oW7ZNw$;NkB~(HygN=LM(5byy%hOcc**cK}FKHMST5yVe9GS8^{+8g+`P@ zeIX+XwyE!*vuuY(NA%?L$5g6X3t`n*Vaqu=;6y*p9@vq{<85Ks3Tq~2-mCd+Aumt$ zTp}T5f^8Mo2@{8HjV9a4x3P<6>iFqvEyv8OOzUN{575|OMh+e&;KeizYJ%pWk zbhc9wNh7Jm?#Ls?WT)7-^B|#{%dvrPT3doow zpPzIu5nwKs%~Zc%cOvc-c!z<7unlo*7@-|>BuCQNsobv3SGko<7_??cH|hy*S7+(! zZc7u);V&1vA^hdg{SWh^$012U|6h#t)(gdJBNCRKQ$kLh!kk*M|FG+kCi^N+=17!y z4(}uFq?C^+NkR08Q#ln09?ygzG!K+rzwx?tM$tPZ9K~)&An}P{h03CiLiP+eSq{%X zI>;2$D#LG+b&C*0Oxjsk@N|zymTU-AB*WL0D`K$)X&f2~nT-MErO9_`W;_kOeAI9z zzi-$YOzJnl_WP3{>_>We+cSKfR1_4g-o86cah)~{9%>*|gNQXp*-U|3pNZwH_bkMB zUUn`ODKe;XXfp}W;(LRzHtpn)tBTy0Z_l+HF}3aDc`oaSFMSppLJi(^I|KHeezS5)%?r0RBAz!q-gF&N#Y9s zx-*{kW_G@T?n|AhU~aP@l}kzC2v|Rf zHVJJfA+{UokL_{MzRQgponmx$nlZZA`zRyhsV5-I9Z0OJ`d3_u!JUV1kt^G*&(PA= z=Na|qjtoC3*)Kpd_$b3=osfN>wInMK`&9W$y%w#Ss@{^_UfM8wxtCuh7ZxuUQu6(G8r9qEeAjR6Q6Lz%5=iCP+9&_dHWHbP>{ClylR^F^%80Qi8zZZB|H6(e`Hr{J;>67q#>byBu6$A$5-pXfv}=s>CnKYTm8s5v zIB+k`WkFEeA07BAgG?AW{B{`lPsZq>heG zo%jB_cVnsB@=rjKVL?HMZsl5pU5h+l^?0E#N6D-?%2f76OpJB1oE@ar73AI?gN*6& zfYQ(Bg)K`NnMqd*3R~JsimF{YB6|0hUAD)r?V2wIht)6D?X%2hk*g`OZy_QK?3Gt+ zt=d^AOIt7U2$ropC*q@z>ECweU6S(ib(fZwn(F3vHkVC1-YHK6EgnC1OqreLnTG6U z&D(jjHqBx|<+|Z8cg3Jvo!`(vrt))Dk6%a7qI_#9p{;d-`>u6JY#`d_4 zNha@yGOgV$Xd>-bEoBh0^ldC(voU4&pu{^luhyP<#ky>iAkV4{`G}!UbZ2^;ep4jV zTuIzJA}B?nQVNvl{XL*7z zv9BQ=4^|&|By(l|Ybq6^<0{#ikltf$dRB{Fnz)QH<4(ovoxS`#8X@>&zzpy;T;-y9 ztmbo!JAA1o`Cw{lhJ^MBVJ*78>zv}MZo}F$p2L9J%nWT8=I;ydCmTJNa(~R7k$4gk z_FV*W7{&#yfp{{+mV8u87yppU*WA-i*U_K7qU0Nd`~JQhbuN<|hGGHnR;5x51R4|k0+qVGQUANrB4kXp8x{;`_%A4nK2@bO-XAEBJ26u zMSV(iGQ0b1Su#Ij>%a?g+)$SMk=UNJ#ImLZo50g=AO_#5o&ysoGA7-R$y~HRyNKd4j&Zt;s|ytKJ5JPjF^;Ug$sD8 znJLA^mD+sh*f*%GVd25im3cU{j%1OaR^((M*Q*qE%CJbmM6L*fNqcKAp=L`;Ezf)^B7c2k}c1 zwQ(JSx%%zmRg~j9l1l|#t3@t%k*M;F_8$iSLP~TZ$)$)EnluFR+szE-)?i5dsM7YF zadp&&7CwHaF?;d44GsH7K51|$`^aNJWMT51*N{M)(5Ty+}Dhsa;`<<7(7UAoNvHgS&dm1 z&>@gmo`!2&`n>2x8}1V+T(^C|yoa0}NMzJO`UsZi+%paPrRTlZC3B1}TiKHU!L?x! zUo=v((X9i8*^l<$rt^yp>5!KS2HPgLigH}A$|pHJSv(|Yv0F>lLjEljKwnGDdpYLm z4~MsSVD$HofuHXCBws4fH!wdban2`x#E|olvZd?jnB? zesO~@0s+anK#EwfE)qt>p+vE698T9On>xqXj5G?1-j5=-s+0VOmwdYvA0{<1FVKj} znZbh-(wAl(6eEqrz2_4|;;tIIi1xUX%*|c(NiNBsqOxgPn5%ngXN%P1L66wPGMIDG zIFYg#HEeq?)IGHcA0IA#c6{}yodUEtQRTg_q|6@w+ zySkM3_japykSQE(4}6kmrb4bw-F>C<<5BL~fIS(q|7`rS$EpOs%o>|SMBBIgtOvIG zVw=o}c3OyeNj6D4bouU_ZKImR&?&0p=gxnVa$9=$b9}skfGuh2QC3#Yw(b*FzIyes z`lG_Y7YOMO+vx9XR}R=Nvgu&W&Ly}=@LaSIMLeK?|3Qksb}Rs@iGoDBt98Fv(Aw6= zn-^XzL;7zm!H0~PnVB^J*fRwlEZCNbLmRE+?o@+OdaydCNnJMEJ>IJKOJ^RE{FQg*<%Z); zueqK)dGfYOLQ1MgXi@!*EcSCKn_ypGUvh-?U|~DJBL)Ul;6(@Lq;fC(Krq^^CgqMq z6>r_`2>NbU&4;zS2d@qv#f zwwMy}@pRVc?XLuga-v0{^vrPr3$H)-!)S(#cEuIn!UB+2Ib#$#TJ&JaT|utcP{ z3{jICQs5GPHgPBlbOp&in4a(0 zLc4_7;j)1kDZ3GLePg3B%W(dxgel+rb!<9>YO>)_vApkIgS}q=?Jr^$z+QoNza945vNMq&DeKC+&inSp1Fgpxb&?dUt$jnw-9vmJHm{l?#Z0 z&*5pDZD;IOkL)Q~SU;Y~PA34T#tH^ptQqS-y+?Pq8b+v% z1@t*SoCgp!fts|%KW#kHsFwOfYq6jw@qZkQFMpYBf|Xi!ojMFCEd*`1H~&Ll+buP` z+z0;!Zambd=mKKvZezRLPTuS8ctOGxl{Jz2&&QX)2WL(ZdHHj=j&bOo3xysV8F&}{ zvm!D?mFBSD@Q?}clV}=r<$cm2J9+ODW{!YT(aVXzbp$htN!Vl2N^WwJ&QFU<2`l5q6&fRU|!13?l zUJ)7kF6|^cSU^$bpf5o--yj&?v&M2Pwm*K^jk4_C+5x?}WW2vYY=Qm_hp6zAgR_X- z;sa1iSsu4$4AHf<$40;Dw@Ma2|E8yGtMiTvnS3=t-LzNI<(%M$q5&2QHwy4>8IoB2 zV*dE$_4$VV*jss*Tyz-$R)iTAlpr$-4A9l{{jqFO{C-Y1{JZ*a#u%~2yXwn3P=r@; zYOb6VNO=XpPA29vl4_2+?2aZ8Su@rW@!w?uBX7l{EW&M$>P@_(kP8~sv__a7#^>)epMRGlnz zGWAIiqV~ZpOP^{)m6LP$2#i48c3NotumRf#)Ybz4v#~ji@X|cvzT0SeML8*K#8g}w ziTKD9pI8J9;pGFFtgjOT>VBlAe(a%%I{}>$s`U8r@YA&f{NBNpsytIOG75MQiDlRB zKOS;l`ZSlUwuzK;&g)HdX+Bsr>0RO&v6|zQ0z?u?@I0d{8 zGZ|j!^De};^gz3|rO!w_EfnmN%NtRqfz#Z|Aa*TdepFfr#vUNur}PV%p6(QSROK!9 z;|UE4Vq}U6wQ&=z6zrIbaWSI`Sp!tlsCZ14a5B`a0^icrwJ#3P?jB>BD%1wTp13~% zx__xW0m*)*#|u{DYlr6QRsL8Knv7h3BU?ub4qzh0UkK`C03`zq8$pe9^akJepR1~&K> z@x~`=9U<^Vz-0XpdYyp%*)O;v_B~=`#_Uae*LO;bwl23~0Obb1L3uGu$36GEbsp#+ zW#usE81W#E1jD$Le%3PJUS@jl&Jc%@w~FkO()9~kcCenFrS$albz7@5rkhJ+9f?Xu zUSIUcfA{WP9ZW*Ka0aYxYNWej>4c%}{s|emsTJ~}RDLHK8M&f9E{oM#WWy2N!1 z7K*Ncfq_ZdDeBIv@50+yf+sU+ z1-NpwPV)QrSL58qPu?nX&wHIIu79uS z3K0ZTQ&T?=3*!hp&i|Z}?sTNc`fMLpj#;y?HXBTzuMkHp?8lKX2|ln{Z~N^8x*gsq<4QFp0wmJtUA{%Qus!V&%qMLi_P$`JD?DQ9j{Z6NXXe&<`0{6K11@`~Y}qczNG8aQ z3~fi?UfS-CjU62cDAV;=@(H1P9B6F!_Tm=OkhVPxOPwb%Xy<#*u(VKU_H25~_pbJ# z^z?J1P0Yh&&8J!5e#tP_h;7I3DqeYArKX83#98vMBvKLE#LgViVJ-nx{ZPOAN|Ssau=3 z#BfadQ+;+5;;qy&6S^fn!B#wV)EGm3ux>piIlCru`QiZ*)Da+V2C(zt4Wg0 zy^K^dcWQtn>@+Z)lQ7_If!VGD5tY0i*{=GiJ-*=dPR-Yry_`=A2t9O42Ym$Faq3cc zgKoiLRI( znNC=Cbkd3V#whuf(&8+F71-E|567}mg=g9vA3(!-LgL&d&`&vp`HBbdUccd>m#?EE zrjENEcQ4W|2IhlC#I`^A$7N6kVbBr;S38?qqrzs_98j2+jOD24@tlN zjlG3Eq;Io4OcX~I9MO%gxYK#CU|X@XnTx~L?0rq=5 zVLYCzJZPBmrIjpiS=*#pRlg6CoNbr6uji8-g7Bj-QNm+@xn;{Cua&)eL#=D9ry#?{f$69d%d!ym;B!GVs^d zG=Q1xYG8ehJC9<0jDCIndcyWtXebOAA!LHbrhm<%ZgN6jS(pCvy0*UUr}?k6^>3qf z?P}ui<&pW$69HxgqC>}TVs66-n%;x@`xB6{oCV8njJ*>=)e!LH+|*^6b23(pRrCS9 zX{M9(N7ac86noqtsIM(jr_v{!zW zs)FFSxPy}xM%^EJ#(a%auJv}crG1a6mV>ww1JP1hIGF{Q{mKkjk+J;48c8#WCXE%`s*H*qr*tHvV3`|x9ET5?Cdb@yoo%5t zGZgzB*Hpw&!uzAGpj-(C5YA?xZzi6~zM`0EjI1UQYKYEHS<;?3p$`5_3LOTLrU(hx z4}(@ZxzMoBk|3cnn_%SPwAK@;z{2fv5BjSx=+jufTuxKvFhaJ3hxwHWRN5jS zwDA-N2S+|%YbV$3BJ`wqO)=R=a$LwV*-F3xNRnCD^B2KutU+Frf4%R2odu_6cs+FH zxE)NAu>K?I)T~}-mnCt0!VdH%sm0dHl<X1%ic6?zLtlCv_x6yU^}_dBV{O@f`YG!iAmktD}g4T{3yqpE_$rh z!AR9)tReh)Ow2jC{ms^a8zi!zW^JcE<0)r2Eb08D#_4DgVgKY5OAk#f)Ap=@*lO(0 z;820EE%LCLt=KS2oa9&z&(HfnHcOH228$>S5cjut>d#zuylDhwtEm}=M3B0z^_dS4 zT6sWW`vFmLf&N)6PqC^&3i(Oe_u+>3-&|SUWAVxfosns5nV#4B)~2kuk{Ukn;)Bdq zSfLyOxNbWTulc*3P7x!r#R<4c4ISy?=HX+%o>z-26=VSply8@OJP6wv)O2S9h81KqhEu^M#sO|>AsqGwbFz`Hz&4^8(! za8A=7oa6uPizFTCH_AeKcgm9TnFkj@XX=QD!fu&yRE zPoOK^pc*V=Nl2hRADryK!c6>RPJ)E!Y_{q7T?k|ldcwqP7|0%!9}1?(Ly_`5)4`7v zdV0HpxmVa{Kg-v;f;{SRGTd}j{~+jl?#Qz{N{A0dep*PtR1?UZoHYZV%-1S#;?e)` z9MD$olgTUCLYG-S6s)E&52FJ=?7jyuRu@UvxYbV!O>zT@RyFuL22YnQSofC%FA5ls4oEd5KF5*r63L6zjAd10U)-HSU+mvu5Ze+2 zfY$bw#HZj2r#g|Gt4V)IV~|+D6~Sk`Ddf&Y{4eO?Y-gG`AazTg%`&kmNSrnE!d(+0z>e>xg@c>%hOkFMUM>Klvi?9qGq{m zsP%i6OoP&ZmO75koT$`RL}Tt1Zl-1|0W^Fb#Y_|1$rQ}B@w^|HEz{A#k095hcASSi z-3^c^gO{5crkxg)ld8tvWjiiQzoy(@OW%10nybc6eIT`Oc7rdL71!2#53P&Q<^Hu1 zpI{^WZEIf>!z>X$e=pwzTlBg$O`8eg@?v{Ct!ZpS{IUxuB(25|LtFnpZw6*Q*$>u= zt0yAaW*nXOr20Nwx+eFSumSN-{g;V*ghwrfrmUzSfFn9)0YZ`FMqifB1;nVTr zXgwgOVT|}wntzTc$?AuCXCuKuMB~VogGd*nyRB5#RSaFdYQcuUOrS2qLuZmwC0YtJ zu8tqP3L$pzb)ul{s*Yb9Lzj3HOCvd5$U09HK)Zh{JPG2crw>2q4ut&+?hSnZTSnxn z85}~qLl%t!Qb(k z@%)LULGv9x#C`a~Qq$P!uuC=!01avqa`KMuy~1AFV&MacB_Ym?M3;>t^1owaKVWA+ zpzUh?;f)3p6P0g)!n3{J1_1Xd`9uo)^(`a-co56JUgQiQj2A%nxgGe0ZGKA4Amd17 z6kFX`T%zuLj1d;p1Y%N=^tC>0YcvA0KjQr^Io}X8Z()ELqplF=a;+8lIDr`kTjv{p z#lhoJ$S+ID1|R{WIsebg9!0%JO{*fh{#M6@{eFLP5e;rYdNzWnv(#ZPq!)G=E6(SjImDA!ZykzMAsnkRHx z`ucoNo-{86>1bO|GA1qT9{nQS?7}14@x#;mhn5l&_OK}R8 zZ@l%~oxw$bOunHZoX>Qq*lB#>$LMHM{QowRWNeqW6Z*3hsVz}xrgrO__r6zsQ`1W& zR=3L?9UUhB0dG?N2fQgwJ&3vTml@aK~guDX+TkJ@h%!1IR7>+P>S3b-l{q^g*-Zugf6Q z4};unJ;rmfilTWbh*_$`uWuwl`{c@4URq|k9_xb*qp887oXuAuvn}xE#%Z-Elk&qM zi_=%n$7Zrz3=Jg)`tKz*k7h|P`rm!eRl;axTlk&)R;lZKZ++Xa=t~HTNaHE;p2O?2W(Fs~ zMY163?p~s`gjaT4dEy5`X7q;Sw%SAAsYVD451k3(lMofH(|E8%w>c*0ZP`-(^SSEJ zgaB4yrU}p*!UYU&!W+vA#Jd#Wyl!YHusq%@A|n7iZJt7g^K7q?_@{QY`-Gx#Mz^JU zp0R?8-Hg(e4%MI)XA9FpDMcPPkjAf*ej$(?-x|q`{%SUmT`PrNOoe3=rhR5ZbR{^L$mC9E$Z0pV6c%A0M5JV?- zMkwT-m3gc;$n8|iMdnX`eL{TK#eTr1AhySudcZx{dvC(~-p(*lD)BeJ>R5Q}2yxFh zh(em4hD8I&>Qp}C$)f2uKgt`rjUC(UYklC{qJv<`=nDJR(4gWrlTq+(v*F(@Y|r`d{1+MW4=6p5My2?^Oc@p}OT%2u@8 zc7Ad{H#x>~qa&jHl*ihv5Lc;t>DF|bnUoN9 zoBJWw3%#Ye$%(n{YAi+6tkP_l2>HA2kf|8ceOuqAU7W15x7!nZM69(m7Vx&DYAZ2@ zKhdjtWl~c_>@6nKaKf_!w7`x}iKKPQ>(+t6D=P*p zVyvPTG&2kSnlkFd2ld}C5cuymDE#*;Bz^tCeo#MkRsLq0i<_`h@c3lG^I-KozP1VR21pG zg`o6a69j=h6I|>4zH9IQ^uPAOd&0F=@?<_^jycLb?lGn>b+uKgD3~dTh={1v)o$w( z5kVS=h=@NyPvJlDVRj-S;v`bPt!U_FwK_>2V>I{yyP5Oxd^o)*k7!;|UmMpon6h%n z5YbDzFp1y|*c&cBH_moWYCgUmO0JQoPZX|Y^5{Jux+qGjr*@I{^f_L7ZoS)=xYO^5 z8tfK%T5CVG52`boa9zJ}^jO$L>+#3|j(sDqQ|@4fo{^F96%{cljRFzj4 z+^jBy2m<8{!vDdLLK`NafBy%3@|KZvL#3|4jr!l81)(}*36B!~(7=cxPMIB=^ZzVL zj9-A{zYF|V2miH$|M~(x()`yB{;Pxk3wH36^Q!;ol;C9Nz4%nC#rv%;oCryw*!1Lo zQV~jzRA@un8mk!M|H3jL0ouUu=ois{a^W3HFGTeuKb3ydPX5{ISExi$CK>L3^V|ai zPN|J5nXG_XEwkNe6Ae{NvV36EqaW|n!bO@)J*WIVYll0BsPDkq<8BTspQKk}(!Pst zickl?IF3zaJXU%nr~ERej?g4In z*dI5U6Rjg>=8IkF-C68My3A?}7MdAY)_V-P4_oG#Bkg|wyp7oniH#;~tj)@%Rbw&U zM6GCCQ&RY~>}jGSiU&L!a@djk=1qRJDSlh(5$v+&r>R+cDq;P1RptL|C{Zzssm0%Q zd0AXL$LzoLjrR&hZVwY|H(ph=Ry)sr2)5c&RE=K3riwm%McHj)?T-}ECAG3PmEy+( z422akV_9zDT1)A)EU}g35mzEiiGl>g3AZ*mSY#o&yV$QPXk6HHh?^2g?6;_Pw3Pj` z(YoKtarANOaLu#$7vqb-oeYjzls!)aqk}Le09QZdE+2>;eT;nA!H9E}mw=RTud$Ug?8I>o#oRzGt=%m z{_|bQ#aDNie(s<^PeUq6N(jBux z-kKuoTbFaj+Gp`nwb+YJd020H2oNwUgp#RlO3iM#xQI*XMef6nI7ev83ARRvlCi^h z{Wp)^av0?aOg7w+Uc8H<*-%DNHZaK6rj{_S^<{+vXUtj}ET~7cg7Y&DK7F?M30;4A zpaZ1j5NnfBb4k)d-tlMK%PRxsiVhVylyKsiCjWzc&vmrpt*TD(GWh1t&yLSM7yGgt z!~XNyI5gMcY+75?+9>roNE3xArf5ZCWvgG%ci~!8MZCtye*Iv+k!yj}gC$~QIWt2d z>fpOz$&Du#EXDV~MoO{%hsa2xL*5+4^dfL0b6g@`=qul}797h|Wj^Cd} zY;`5eROjaMs74xES*3i5V9C)=mWHj2lwG+vUKMcYBgyKt9SCRND7LKUcD>$1i;v5Q z9dg6N8HPcheQ7qkrwHuM`_v{n*X$k&;DNlA@UyWnjkEwz(}qhawY zu-bF&AbzSe!3$K8#R@`@l18ewp^yr_aokkkl<@UOg4fS5i?tW^*@W|sx55~m@FKVWQ&>{Gt|hKgL&tIU0R-U988X8!}WP`s&=5 zCx)@;`NjU63Th|Qb+54qu=)cHusT1i_&$Wu%Y^ltD1U}qO)|)I#!!z+$t?ffL6a+` zmqol*#3#|z<*@$CIG_6Rxsj2islx*totu)beL@&mh4fYsiX}|6Et}Q~1D}-Jy)rJV zfzg@_mnC>1jl#$0M2L6`?r6w2gk)@wJ#PLfsg>`;4W+YeR*$9gQn4ZnAcLr1_D$(S z+Fr}zxcWJ{%Srh0xER_)`mdaN>>;$WL0;TcF z(ED1t!>x%JMjKkV_^u*{#U6gAA9d3o?~*%kn0)$`ZEe;X>-fAH?W6fP**(tU_tJoY zj(fMp=(V$QdmpPDC-YsqWrt-oA0A}d^K4{mzS};je%}ZwU}gi_GZh%YX?CN0+o$U6 z3QR}!i`SbDihcElFFa04YxKp{&03Em?dQ=>HU&0^bCS(ZMb_)~eufWL!VH+goSJ?= z+Fj^XinsE~ixV;gllgfm@)Kr&)M^bOL_x~80W#(8Qcqg2W8<#z>8+9b zQMJA33^Md-b}t1M2?svc!BDrC=e+taee?bcY#41cNN`G*$sqJzP7RwX$$neknC1Lx zBpfGlzeV#3%F7?;B8ESeMr@fYH2r)fhzB&nmUV{M^s6jf+Fw;LTA|$YCxpevOkh~P zz_5rZ8U#&>-JD91Oddu>=7Ws`9djFUTkSkPKVR}r#Jsq0{Skft2LRAm$mQG?-W)WM z&Ey&6Ca|fp9Xx*i~4{{ zb^-{>1s?U$_=U%3UEs2<>HQB09&`p+-u0j#muS@R(I$b;my3XNb*}*`=X1jd3o!>7 zv_bBtiyh(V^OQ7R_wV}Ev5SGPdjxLz62wU7Qouy0uq`TI1Y*49<4GnQ5i|*i;e07g zag%{_<4ZMmhZQddN{1Lyl3JIlG2JAH0lEXX{ z|1^y;SkY8awVnq^8DXQhc#d#@L}0tbd=M=KPN0BU?GwX9odp}jBTs||euJOCD4uLE zh6g;usK|L0ytg%rPe^EBt}}74^q$h}++3VM56Fq`7!>hfiM9OI&ly~V-w=cIJ5_T- zOxO`pM$v#r^&b_3E1jm~I`Ii~2oH~EzD2t)^l;%Cj}8wCRHN9}wkPX7?ROS>&Feji z4(ee2*$EQx1ZHtN`fA^hBLdVnyd8wHpcTd{gR)|T)QY905g@kRG5eC*(j_vqtS>ef zpzWp6ik$tO#S9R*)D5!l^sbCn45lknb|#2xQZii`czxlzVZ8^O>VoKPVT-DP=j3#L z!e@9@@zw{e1xGeRmib%nT$mOHiL$$gJuSb7I9MP<&vwMy6L5@iiPhv_l`n2>X$)Dg zk6kT5H~JPRg;F!$aQ=8O`tx)6By_zmOEWe)nl8&1(L`|2Oaow_+FD&9sHfy@+#6TS z%5OLCeHPi-`xVuZE%Im0vssX$0S~BwT64%K8R-?N*`y7N%#nQn#ARQxta~z2dT%WQ zZa-A`)Ve!W-Wo&zBSpoQrwl>Cgk+V@|EA(zmP>$p?7$K?!^EDSn2dUfz(w6GjaZ7+ z?yg0;Fh7j{!D=;#mwb|1(}fjXeFi$RMnW57F=Q;WS}FZ9E;DMgv$L>?nx{(xdC^}Y z*$N`rWTba@mxt{)Ff9q!A4evL+h?ziSLc*4Cy^5@Srk&6+LYe#*k{3J+hc!j-}~(% z6I)(G5LHasLsiZ##PHl$)9<;&{p!F2N!~xW=3~o53Ajr?JwD=sAfEe!7ClsCVc!-; z>-fNPZ)19CqSm#H){2F;tGl~fd$2};V5l2p@B3)}F!z2Mf!>zeI9k*R6fnQnl5fY; z1d!5OeEo)dGgeU2WNt@Y(m93nZa}kIu}rdEwF#={f8WZID9_?X55&D8M+{lt{QXo6 z0;31Y5QZ7KXapDaIRmUvAKEX3xnfau#~?>r*gWgr+>Z~A^dsy(1x5vN4gn$sVws!N zGlsyb6%0W<(JK-e9I?&`jWy4h zv^P#u5cGQqIIhN>mFEhVfvAo%`sbKv_+TfKWv zfa7Ku>G%*L1r0q|LRUahhK2?apGW{FM8xu7wSZg~ZBl_t3Ya2#meYTuW+Wc%kRnhZ z5|J2CFh3&%4}P#f=6ChSpM(`KRGx=VWC>@Y3-q8^bY}Hc8t|7F$~heb$u7`009$!-?+GJeEA3z_Tq2yEQSX4v8iSc41mRjh z;60VYSa}f(gd3TH5D|pi<5oCf9ds{%wH^-KIE6naBE%NZ=q&lBE2-#Z1x)98aVEmX z!(zdT#J zrvosxio9+lE#GCDaFj0qg-e4b*1}6(fF2NskBNZ_zuVvG^DBmgo8ILh*v>SqO*J?B z>?};nO*Q&ft3(m?q`O|AD=xvnZ_{!O9uz-~(U#Q2LLWzdFipOG+fK!F)eHThe%TLNP1 zvUbwKE%@%z;AAmKoFZd6psL0r+Edi53jtMLo3@gl>fILgXJ=;GcAL_s2!=fi!b1n$ z&w1#BJDd^-Pryj{{Mr1v8{hm#84yT4c;-#oeQ9AaCv~X7d%M!6b?HvfPuqgIa*pFr~{0i#$g;V^=E zwg$+s5cl!rUtNural0#_WcW21ML`=(WD*t-*Kz2}%U2n1eef z;S)7wEVHs>P^aagB5~U`sARc}-=4Gk+C=RLv?KyLKR;hDg>oP)3ys0U++UKz`5!-% zjj3X0PrWrPFcxMlzerP$vhR|ptAF}S1;=S_=IRBHEb07(^lp*}9aix?edatyqm30U zG?{mo5kvxLB9Q^}C*x~lEcX!Yr>!jHhmB!1*fIObd`f)Tm6&cLc-^Z&Y~&Rcp7i_Q z3CFzh$y>^=*u)Q=>kngJK#yO3v&)Pcyd_-^JVl(kx6hGZSE3KJBR7F7=XpYSZl zgdZB9qnhc9LH0-S^M zCx}2{Oz+o1)bUAL@CDfvc(CrH-ST4G1O){J;7Biv!}@LmibZgD8)W>w5ZERR6@k(VLnnWfJS?8+&(gt!R3Mu1JOR zAF$7Z59p+KZ0551vL!nl2V}=dhD;NJ6>b7?H*>Ey-p1$V_88QUz<7zG%NvirCoXfo zc?Num?4k#uE>hrph!D2V3hfqYlrdn|zx+Uzv=5|Yt!ln`B|=`e8Ee*%kzjk;{#I3WA*zhYv;wu= znl;!QLqU12F?akf^HF4`z`ZpFxGHBQP)AQ(v1ga%{aE95?&yFWvnt9RLxx_8dAg{D^Z|&HncHpt1Mve_H zDUDhQP*h_|(%*>y*lc$eLv&{F!8vB$6dtO5I#FP>cq|o%sTCsR{5CS7jpFx73l~f1 zBfZKNt$Ofqri5mdph;*BSS`stWAH6_yGnVX+X)z3#@j=D&?!y~UT&tpa#y2D>NS_+ z*`(|pwHCWN7n>-+aUkfydi=M_SWbL^pL}KVvX-Nfk4fAm&6iQhG#dcpEQbor6AnGB z1a(aH2AyJ3cPu5mBy1?oNx3HR3e(q4dpwREUM!j&ENNC zJ6{7z1GZ61_pkcpr`|oftH1vmUL4~i_n}Mh=@szEKRAkjM&6X8?#HXAHtG4{)+#b9 zj(BDbN_ha$rvpTl)9iYVe-}V67_^W6J;kRHj7(~hB8pIA(sI0~LZstQc3X;~^i&T# zTJK{k)HkX-D1dq<6?4(t1;re`dRtg7X&!pXo07|FL0Q&j{C~*v`GD_tE>Q0v2wyI; zVdw;dUpSjnM(u>PSE95P1PNcpZ9%ulvVMr6)@OHVX{0Q}v3|8GJ-x)V>{c|d&Jf6G z6S#fcdI`JiInD1Y=theS)u=1dP5-0h98Y`^NicR+CCn_WFB}(#PSX%ybd0<73$4h> zg3rkK5^kW@^)b?6RKKKQ>lMhyxqzNoTB+!ci}>TQJfsD-WSA=FzXRGBuo{j0f_T zE=(CCY=*?wIwp6YhMb~e&IDCyJ&{A&kV+tY8QoZ4=dqgqmtOyW1A#u#9F^N^)M-kD zSH#loefG>M;?wr zXetaPNx2Rbnq7xaHOaEZX2%k?aDk!yaED=5wqNOVVs*ddaCgT7vext}*?GPWD@%}? z;KjueKLP+8OOSHS20e=TfhdVj<8|)#5$CUciddoMkelcv)@GkZ(oX;R$ZcDb}$QM@h%0%v620S)MM!ksb6DfIP4t!AH{)h4&_pnnu zG*$$lVEp4*0US5!nVOhylL&C9!8wPSVRqY!(0+$z(2%KRU~MpBb`bOGO;>h|eE~Wy z-{x@T8cJSHUgnX&?H=3#E_luE%5%UAy*=B26(zTDESz~HC_3`}Ox0g(FqQ?J2IwIE zU<|UItCvyvziU+C^)7%3f&Wf`=<>9gWFat!l$*oL09jRA10b+IfERc=LO*o05}J6f zg_2jF;h{VpOU!|=_;*qBuTe1Wkb|t~o?X9>NbEHpsSB#iv|iQUMS*iijBNxiKKT4_jMz;kU|3 zV*=K=E2z^<0@y4n8@(qdY!)fVqqKb7mSL|z@D_;8 z9D48aMtxeJb>OAJAMr=qPWr1ank-+@@dTmDz}_cLpf@zr0@F*G)oCA@B%briZSq%N zb%_=(_67$Cct9>K;+K|xL#G)k@w@I;(5W1Cr75-FVk;o#E`ka@yZhbsle(I-$j8)N zw5swp0ee8Xf)p5mux1ML?+7x|GJ1I;#G0)asRNd8!`jCF21Kw+XM3fS5cf&oYHdiR zr|RZVb-nVED1V`B`Xuz9g5Qe(P!uR`PH2y99lgz-oly(6ic3ggXrJrjBTc^oH0=|z z2;>Hb`-n`UNuYDha6e&iS?#`jhl528GXx51YY|BZ{sAC5{odeUUudAv!E2m@&V1|* zz!d+>ZW1^`HFXTrRCHA_??(3X&)U!jD!}$GJT5+A3z!g7Xzs(+Z=yblJd+i|S15Mq z5DFk)k{D4lpAZs0h+&R+#-lH(khIMBNB1Zs$_w$)q6S+}@!sY_~*1 zlAl+V`KxpTBA+4RWdwLcA}c$CpyCU3H93xpn&OUvlUo{J5>O#D3YaiJz0?!qK`;@* zjq=ZK;3bwt;hPO&W=HCM-Dpjm5y9~OVVO_P!3^^uF;l#oeYDXWz8D#p?RNu=c_{b* z8(!R<`CHhifu0GWha5!>!UWh~BAMHjmjpk$hj@Hi-AUG{F8F38<8*pI@*|!!w&EH) zA&svfyd^c(WmPd$CWBAlZD3Vek*kvgfYe@!`WpB)W$)evMD;7NwdFICFFLq_g7C2D z>|dwIL50(0#&hufdJQVP!q!A>yRHz0d^`~h+7ac)Am;0T|Ju~-z5PhsVMG^9BxD6N zxz1~|-EdX_grm-2+#zA1pL`o?GK=B3jx{MK^YCA6im4==G>IsCga@E0BmMsDZGK(= zjiofuep&8GQ(8L!@z^AaU3Ox=-gA9up*I8Rv1*QU@6Xo4m;89{lV~=BoNx*VI?UiF zgdjQ9Elx&+Cul+wW>5l;11z0e$UZ~XLDfEhpX68>HSpix>D3fz%;Y!7eu7;Ywfj%s z-0sWk3;CAyRWHt5NRJb?u>16!d_tD6JT!*U>(A*v-jZvdIvNoQL8P{{Uho(XP~YzV z?hY)*bJ~;*9q}T=Z7=C8bBnAR>jbs%!y`z0lik&E6HxUUhf=eNfsqZ|b;@pulRAFn z-1WcbdXZA7-o#w0s8T&Pzi-m|9w>gyXaG9cy$cs;1+{ZH89FC5z#MQL{m;lKU+sal zz~F%SV%4~#LHrdxZWyIHrJHQcc+%rxp#P(_%Oa|KdBTT7dIA{`|iibJL(1- zWTgdC=_-&LVY?7TE4|Y815tN2J=7H;6_({R!G)+RlER!Uqs8J zQuB6lx;3=mf3&`>>pfP#JCfB(6Ji;L)MfZsQ9O0oWT5!j3wY&0HWSIPHgk*_0`M0P zu+Q!msc~Wv)rBAz2M*6|`heQq%@Y+wOdTQB@Mn=wQ}LPD_>tscY&IvmR<2k|)=wyn z0w3%X0r=6rBVu$Q_+Y)+nv9IBZn?OAg2b+hz2yJM7vsx!i>x%DbJ^e3yaO|Tc{d5t$;sA7V7r~T)h;h7P@To=c64$AUtoF-V z35Gk{fal6HDY06!x0t>+kgI22?U;N}_w?771UY}{<&77MS8|Ggohe)ymSlm1T9 zDJdLdULAFf+ESHM2E@pf8rQ)v@}2j!8YKZWMmkguIUYG;VW#T~Abw;DZOldYxmL6K zzHd^O%(c!Q{l=#_WGbjJ@BE#dO8|A^~;_cxM&5P$D&={K1UQ0kqZJRGP z&PU39vfuWc^13yKG_y4)siyt6m#3_Usi(8*8J=1Z8AOr=iwxk*2g7aS7wNzXmr8Bl zRoc4PTCK(5vXm~N%jeko9i442jz|p6%v#;zybrYTTF*6&kD`*@0L$7C=+u9^!f8K% zzWz=s7-$eez**=7#b$=?+^noRPApG$SSyYo4a}(?*md4e25k~Qz;5nq{~${jxO#+J zhhbCY1uA@v3T76fcx3Xu8_o4rKjIl`oR=^{4fWVWkRw&Q3oO;#LYRvdt`a3yn-nj(9QbZJHIj3TiAoL z1U~}_<^u2hvwMuC3>Sn}0`_;=ha&`xTnu$}_hBn^b|(E*lP^uevG#%GFDyM0w(N~4 zU58;Zz$m$|9^QeC^L|BFEc5hvI;zb&tN^3|1IRC%{9XTT3lwB+Z+@!3PyD60=eGUa zQod`#V(i)KrB>mr`K4Xyl8~W*CWFB7_ogi^pVn#w$MX+x392lw&|Ea0h+~+De?W}M zX_IfU6x15BsWD@BFL?6rM=7Y_#hsnAy+>c_UDqG)|B=m?I#?NWZJj`0MMEnufbPMHusya)-1qlw zM`4)L%S)6j$y{)=c++n!aTo6cI^i`)t=CmLLq1)$$*7a?Z}BZ_%Zu1@TU?CL(9-f+ zPnDVATR#dWv(wF~vxqFzj+n5WMA|sCcuuuIJpYt-=omDIYg4n3uPPHEGRQ}Ai)AaT zJnMHv;?+Bkh0BebXETuQ=^{ralm>a61z?elI6-YF1XaNXSd0(sco>VAlEVme^ zn-H<&vF|~bJeJ$_)V=jnvDVAIuhaZASl#iB4xQn%V-oiQ)}MZJxe6hs*~k_hS%4=B zMxr?>QBFsf%k)VMSRlGL5@?w40A4^#K8oKaqgHe3U?Su$WdnK$+vaEKqrxK@%Vjw( zU$xT5F%0jGY~usI2OB z38R>N+x|)_3a+%!IsmyA7}EWl$XSJF%xjQYZB64pNv&0_giXiYpiZApe=2dxnrnmZ z31S)_cE+)2y2CAf1ry;7@Xo0*XAe?pfQD)rY%kfIO=;XfKa#E3?@zC-We@7?MSk>c zFklj(u!HZ9^N#OCiFhzX?E6gP>ej`F-RC793s1dDFPDdWpf}wOtDM2Mg%w3?#8r=4 zjG~hSLB;VUrsBDo_dLGZdV_B{UApW+Q6D7h^{Ai0L79y5{Wq>*$XZ^+a;E#(t%r>c zMyFYJg)amMhfVqQe*1wd5)%5#g~gvRvuS51RWDHDkv`?0Y|YjR@BxilGmyV1~CP|mx5(C=HL=b9ez{o=qfj%LcBk3 zv71*oH!StGEv%J#W+k|{j@=)NQ21xiLs$nh2;3(2Y_rSRkC){A;_|#}XOSi4^72D| zQ) zOshBwZ(QpByjurzlB&QwK7P1AU2(_2cN*7U;wh6j13PPFA@oP0#AIA+x&{-oFP&!v zS9x~blCPM_l9;kiqTF8OeQ8m{;+d4^7U7=7ZqC-W8o`av(9*hRmbdpE)UQ)EW6K&&Pw6+G z^W_c-x(L{FMPpKj7;FXH_f<9ztKf(^iSQ4Jd;_K5NEb`BaNim&x(uhl4PBow znNutEloNsa_H!TYw)t5Pb890xRzekqNFBP0m|P?q{4UOz2Rpb8eS)?2e-9jO>y@_2 zXiRP58tveFC&?o02nL1Ka_Xv_hTha%g|vVqajID*%_%Kp+=v4%obc++pQ~oyy3F2m zmV8Kr)~s#Yt?^jwlR7LZxzJ$cMC>)5TMn|2S6y}J=Z3Z{7LYxr_!ty1Hr8GMT)&3V zD_YVwF(IPKoU9k-bveMmMvQ;oV*-KP>nM_fZ(qC~Co`^o1`s3~eEn?HsX zhFqjzbcWYG^Zzj*YCCip3|{P~d#x8zVNr<@M`M8?=IIuLIh(uO9%@E5iwWK02i+_h zMR7LMLy0diowZuKNh|UG#0Mdt6X_g?YaT$mN{qCsBsNMrwD0dLVLOy51-L;>!@dwp zj7n@6r6;4T##&3OJ{9b%n(>G43`0sOTR7-bjqkxLW7&m>D!77BdLWTZu)=81A0Obv z4!SvNUA;RH-UXLTIc>w^6u9@+JTx=C&we#aW;&ezTnM2p(pRmPWb_F1{`|JKg3$$@ zub|9+vm-7NIjNGqD!<-RTO4(f-3y;IMDZ)1htWQfeUv5>6*8d>PrTX}&p7Cu)He5E z97H-6kKZt64{x#*!?UVPu!r-4xo z%&^5Mm%(-fiJ1d)h{97qPI%rPBb_TbG7L1`u1##McU^DENCAU(oy*A1IqcY6h%L^$ z^R7x*zj5rAPRvc-;e&~|YuoG+H^+kQ(I4Q0r+mGNtPi3;bm_`T`aZaY@}+(5@8)VP zFSq3aUEgOs)!iU*-qo%D-aA&G#%=HIH*ojU>#pnfrHj8w(LmpVuyy-0g@M6pYArl6 zr;)bP>ahO)x?*EB?BH6kv)Q4hm6PPAw-LleO7fN&@esB8>mGI&)%a?5C$spCIG&1O z#_<6LmTySOnro^ucLGIudW=PW_?&%O`@7JIS9H-uST-386BRFuZD zt+Z6V>&T0}8PDWrpW^(08O(o*q}8Nvt#Cj%{Nb~* z$1yj3l33pee;j2TVlwt37N3qgFRMdcIveqceVJYQIOdeHe3iQgyka-1F^~NDSneVD z8Joa{jRaQn=wOGfR01=#kZClQZ(E8uMIDaigWb_t}fuui;hTYa;57Uh{7wN2Qw0Cc=ga+vV zN$Br^#&RAQ{LBqFY=fS+xJve&qFsW!Zf-+ut4t+o(#0-fd7-bLr8a9&6nS{Rhy|(bcp|s%1a%1Oin=;EbgtbS-bz%AWz8^WUpDGvCY}- zTJQ27Z#&i4YQl6N-BfYtB#S>Yj8=^%za)+WY?p{F_Q)L8O37@UA~5e{nXz4O-|lVT z;@F>q!4eDY-oLZ`{~sI$myo2ETpS8@Y$@z(k)-8XGyNy-LW_n~>yXtL>Ydevd-L2M z&Xu}5rm_jGYW^6MUz+QzMzXz=uP%Yd46FD~cE3~czdjgx!;05iYdZt9L`ivi_X%F7XUNF7Vf|5V2q`h z-x7P8bbS5exc!g^Xu%^ zEbm%NlfNZ)*r&!*bcJ#}kZBTpvAi&oclw*+ppTwQila+z(H#-{IZdr@ZPrEE_D3CQ zm!cL-<{DUo6%s&&GOOUR*r(k3f-3rd4>Gi#y_1=DKIyVA82KJH_9=x?p(`QsbK7Hv zFWQ#9aqZyti3$cpfLfP0vUeshXT`l_9x9E1($0`Moyg|0ORdf>x>&ihV^3VRa_wDA zwT>Dd0p2~VTp23Xu_n@RgjImmG?=gHs3_bP6dzC zvpcIRs@Sotn{0+gt436-oq3CL$12`0OJY+3smif)OCPr?$1O+fec4t$rb>QPS^gf& z=5dmnc+;Q0AU1Ajf^~H|xS8{GY+wIF)tA}#_3KSCS1hUS%9A(D#K8Fxki_FK;ch=KrzO(13X;KRpnxYjixuX)7 zIM#34*u9%Ll;rpET|JE$UwiT1w27OmMWdz%cH+G)6Aky- zP42HV<<~y0Sh>H3uq>vUg?n^4HMy6Mui7}W`5Vl~w9OB0RW5JLV|TGWk7GRr0#cL_ z;J)0AaFZxp7TD;(6tIkiHPADgNck}xF~xB{am_}g-D|eB$Wa)BJ1g>ZPJP6VqAKP? z=K*r|^HJ5N{b)iR8e5c5Yd2n4Y~h~$Wqq_RYy91^KQq!sBV0C^UY(| za5x!-lQ_k4vzBb>;sq?D*gA3PgZS*nm#x;`+&mr(=#s9w*X;WwPyuh*^tOO{`wtz( z46bbzh>_0BbsAsySdsdewGQ_n9x-+wsjc3TmmI6BO>UmNojfM-a5lt&;ngzt8*<|H zw40R8j8E{Okkn!WzMaw5>YdsYkSWgSxQe(!SI0iZyYcD2i#gjJUW)z)Jf$XEXc|mPW`3g zf*-cXhB(Rb7ri&!C$3-L(QXLh`ps4Q{#-AdR1`nspyvlhtj3xHYH-PC* z=h7AZNLRRbFAYC72RKVR&?A>V-02qw*HhCOM;F#J)uSJ9Y;SKHfg6?X>u5`S7kp(T zC&fntw4aB;9Jc%D!}vTf1!o6tp)mTkWdVuG!R-cQGo^-ONh3BP`_6}SFf3TdkqoBw z>V8GaOiYn;_-!EYcRoQ=_*V1LZVA$T*|_t=bybfa!DrkOkFc(Y$I?5l+cY_IprI~1*Aux=7moMe&J;)m9ZQdfLYydjXrOZYTfnh*E zsO#Ye$A-W_-1V*-t%uKKp8mWIrUkn~CaR|b#{CPyfHGjaGeHNwE(+YrtvHaG!QYsC zcS&=i`QoU!i;K&xT%~AQD5z>AYmjLViD^rZVQ_TAXv8PK!`@INF-+5D)m{h1*4t zoSqOF#(HXvSHTS&XzKy1BLLjaFlL0e3WAmYSWsN2fuBYMw|wSUg=PZgWu~6;)S{n6 zMf~uxaKRv9RQT(E$C)1*w34Nbz&zsXB0)A)Fj@OGq0gqD6~vsifZxbw5eH_a2xjq# zuu>*3(Dg7E^RYL`Kzq+8>jyH8kd!l7y6Ks|d?E=!fVgq0Tu4lS44e46s>H0<4vupMPa++K&eV2hqzB> zb>Qmcx{J@T5iF8*@;Hgd$4~ybgjCh63NBP#W+9dXqk^xFl==N`Rh~!K;K%9An9Lc7 zh($)m42C4^q8rR;&`A4ucJCS5!`+fVcOJ3vY9~(}v+-dtzY-IHU72d0626ZG_w^Xr z9FHept^xR%?FadKa(hXzY9#dl7|?fcLsqH*i+iqRxd*OH&OzW?Brt4=lEgVbaLXg~ z9`R`QO(YmQ@Vf!TAOeLv$z9e2Mrz^%j@ZNQP6><1_GfG0LUX}(w|sLhNmX~eb-?1$ z<3~C$P$(;ik*##sX}L>pw$V*$T*-5&@=H5B)CD&M^|ucVq*6dv zMd4ct2Qw+siXxc>j-7*hP$`)lbQihq7ZM4SpjqFjrM`M;kaY(VG<);n!}a;*yA#l=K} z(Fk5s?Qs16;8*6PIRhf_)g=YNe^LzK^Z^&XPucQM_U+yCo$jsepuZ*QBIDKvMdQ zxz=*M@7~wmU(bhg{$IQ~tH*<)prZZ#kG*ClI%auJ zbe=8-wLc2vuYY9ygAybE{0D=2u^I)ld~_+#;XhZ8Vdoi@l0`)$upk49Df5s*6zIp3EuT#eUurEXb zBMbd!fEd)!uZmRv^$~jhL6e*NBTxSMDDcaD*!jN~`}>bV=$n*76Ti{?`&A$INACRR zb*aSEOD;l9y!Zb7Dli3N|6cq*Q}92#0PNlWF@*n_g8$hC|KB$R41ehKNKHO*Ui&#( zCch>sY8{%qJK`NvsRS}+VH825^huJE?UMPpb2&0+FwnI9g9Pd;vrPXASors;mm*Xv zEG%b0R2)?vxP|{$oO%MwbZqBrsA?LyT&=Q@%F_?E4#R`CNr6Cx`QON5+HOf7{}t`#NI;+y|5p9zGx#~_czyHlAd7*?m4<@q z2S$8#oag*^6ip_gUb0CDBgd0h0N=+T27CWkK!t8W4z;bL_18*y(c_~y;+B2Sib$Sf zVo<9xfuL;mcTlEohrCvtl>ak}@|zVcq-FR~a%~)7Nsj0KLafNXceX zZLX2!^xnX^Rbf4&x;a5341ZAl5EX41xqjhqQ}E=oQhU$quG+!x&u|%ts`z9?Tg9}$=-+yIojWJ>X8$oO=u2lC!aT{-63S=d?&wHg8 z{m^MM_OE~1`NgtmU@m`Tp_oE0g`jFY4;*FMVrGdhYXl)mKv+UK|Tu>uG3r z0kb_x_v`|1U(2{_zTNQ)7c9~6BJyM4q0>yaQ|v(ez)wA|3+ks*)L)S=iFzpbGG^9h zwzlWFwjsmC>0aU_%&VWiO;Avf`(+0P3kL_E-`4Zz&tG4AU0o1Ze{l2LXf< z*S**|<#Z8U5x$RJ?U#pG*ic@;6|Jv=F}w`zQll7|X@I$>hYsXXX@eO z76Q1|%bm$sZ;nkpXA4}&HO7Ab2l2AFcmBZh6DGz$g84K*oI(JsO8jwcgG@c%+Ni&<@{ugO;j)=Tm-6(d<{JoO{y z1mLX(u&Ms`0#!l?Mm-}yKYG#@DnlTOydlQlBCteltWi}fkIbitCl`AWo~0@m*Gu<- z67~N4(UZft4Wy$JIH{hygWAZDL@}J!`ZBzNF9~;u@U8zV;QJ!cU^dM5piT%MsTo5$(N@*{z8IGw-$AjDNDPR#V13_ADjT)LQe^fG=} z0`QL2%Su*0gcZWPyhj+WmizeW+4%O*Hct2P{EDIR0RNGoHstJb(rYq*f>cuJ9M87h z(b36y+KewB1@87t^?2$GqD2n5m)>q=+Z(RZXrs%)ncIqKmnuFcy=Ok6zO>p?1qUx)yaz zYHy%<&cVCK8k}{gh7qJkBM7qI1mDN~FGfE_|6gB*HHBL;=UVz&M4wusY~`Xy`OIhr1Vf^Yc1d+3yd~b&S%jzG-Adn9-wAjR7R)p*Beap$_;hGz z=tTPLs4e>Ua0rd_vhp8o-SFDb{aok04DJrM17o9l@SDp9QitF>+ z6gqEzpg<)`4nu*w#pv)=?5LA?+wH&w`31JXxAhJ~3|>}Mwd3eGk;3uLf8y z(L_KfKgNi8na!4Y=;p%OK7I=xPAQT#d7gIBpV923!tJ;9g+QgbA&D*|XI9Bv5E6kk z^~P%F($`1a1D-4Y&eKH_=f9tV2ZpAB_3-gSgqY-aeDm|>7ZHMim!EbEKF-e1G^K2+ zIFq7@fE?ubLELgS1D-IqlgEoXM)GpHCU8&bwS*OZm>jjMUflfPQGxqd{hfdgu#g0Y z%eEkJRmfqHIQK*^`+6vCX=>UeZrSjC#cy|}MZ*gt8aitfigKH4qg*RrXJ0UJ^%=Ig z+W-bgEPQxIr0~Iekx}{ja!|RqA z#3`NB`Vt#^l6KC>TnKWEPIjIUX7^@;3B#QWc(!I123dLPd339UpkOQft%tls0Z-6g zuJ6qZ8(c9Ydo(#LI$%REfo(JTcb0-NOrcxBiIQv;hzC2r*0{%kSun?#x^k zt+uk+du6}OylY^*=i7>#_pm!`83_0AGtY_gZ3S~rx3%L9FsSjA0;V?a!YOpGPVp{a zSwhdO!c3{M#^=FJp4$o*`1nH8)6HgJTa{OOdnty!r1_Z2aK6B40Un|I|b z#S{5vPm^Si`h|6s`z$RY=_cDPKThD4O{vcsgXi4l;T&UKgq*Y&yX`7)7yC^HSvK0Q zYU#E*iBrAAEOOw1*kX1lzdb){Q#)%-5fdy6SlAj?6RNi9w8gOvPMa`M1@7|AZxNv; z$lHfc)LP>oLhXhMo$-h~8(VoW@y7iuJh%3m&%xYI_h46U zjhrTu-i`K%m-Y>C@1z~;!%Ku=hSusrpH$Q%D(*6v zoVUg{>oa!#lkh(?NYZ}7V2qo}yfv=&&XZz6W!a`MeMGBaiC`E%b>xN54c_ zpR|S0%UJ2>dWL{t9!<$>#iGI)&hc4GlexBZ?pK-;-ROm4kR%ZOiIDzV!Na3LBpx%yvVOKyyuUEiy(=O0)`VwkLIxKeh^=jas2DZS$|X<& zK44C5sve*2`TG3qI=Gp?IjW!VKHL-Tc00c`L@aDd)+I~TJbQzs+gD_3j|MWl-Kk2c zvX*nphNTelm8$QY7f(&Ty(gu6a|bseCg%R(X9mTDkNETN-eFk`XUo{rDkzQ68m}*G zcE67t%5|K^eYCckm)&iJj}Zmcm?hm6Hej=A6>-m2neTCQ-2U`~?3-)I(pw%roP6jC z!F(djQ(?DZolCoiIw}_GA=WIN^UYmJ|$zc%>9!ow|RP4|21W+XDCSBaGrP^)* zCU&v&*;qC~?~HbTDucggkhnBv6kZ*>9M}|>uBO&(I6qsf?aO_j*>G}mBwxgiM7&>! z3k97u2a?ak^J6COU3&FcjIw57ZEsWQU$=Pl>(^ard@Wbmcro`-9yQIjC%y?eGNue~ zbtG=QIpDgX^|?5S=d+sV-t)WhN)qv?djC*R{atwY>+_>cZj)}joF-d@P|~9pfgVZ# z$K>VbGkW;INQDA`mCy|~HyVZ<{iH8gON&##(zaRPD*rUiK$4NpBu);TXWS!?#}HJK z-#>(BS8LZNwKWvNZb1YEcZQ;$c2O_+ z94MUqpt@l`T%=_!bR!MoU zp&R1$+M4NWpT}lfYbkaK;K|?pF1!4~2A0N$5x;(PrDQw~6}TQ)ok=@+GBkC?qhXVS zFp9m!tRBB|42YG?tY){^(o&zn#lj^MbPq#KB#hX)hUdsdC17*bx9zm;pUm2YNAAPC ze%3HfkN@ob->{FA^i7Ss!=kj0(7ntsbF=K}==&93d&GZ5+9D+xW0iS%7YefNEU;{_ z8iN+^hH2A2PAECA`G?C5IdSfbUt3~L8U@Pn<0abUCj)81DMj~o+P7bD-BnOKkz$L# z#k3_bP6_=IazL|*rb!ThhJM6+;I!uz?9f4e_CzM(k!B{aX7Hn=Om+n+-(Za;`jK+RPjtPstdV=fjFbZ6xjTWbKz{(NkRv zG^w`mPRnEcugf*Y9SM3tiXd7T{K~E+y}$n|?i+uwM-wR)Ym`iz8ERUU^J|Yh!DuxV z)1!l`@X2&emY8fcxRglmW(A=2ayM<%x&a zHi|zl{ghn!HdjIX%?FWtlLn)MCUcauNzYmR#$l(6Tn?ok9e9)uTN!?keVE2ge&4qL zxt`q>yPaXJwwA~Kx`7pZjirf2q8a4m4O@Xy!p5CMszhJ=@rT8HDLqV$EX`EM+0THl zS8nrVTj|;;D;>77a((A3<@`7HyjfxGEx`)|l$o70M2RPsq+&KYZTyOmbWEUuP9nt% zezo}0t74!WmcAu_uMWX; zMk@}3rb2uN5T!=w7vCKnTD@7Q^dFevG~fhmfD~AkYpwbTDykPeIb)R6+GVHu_SMh` zE*A((7#Yx=fxEtuyLw4e4NW^!crDkG5u<=9OA)h5CzM1LcQY#-e4%Z~L&X(D5zI=r zp9d9^bK?*a<{!GkGlzkg=0Ud`R_LD=TF_4=P!YPJmhKDd>pIj(tisDWO5b@rFd!K2 zbjB*r51q_HzFGD%mkT`3C3FL8hKS(cP?Uhm=?^xq6Ma72T@6O$>WA(SJ`KOg6Dt11 zRK96`P*o)5P4zso)pYJH3PcHWYV^VA*XRaNzu)EVowfd0j~dX1G3DcSJmnzjD}phppW+st-ljEH61(w&5Tu6G zl3x|Mpo@wD;F@yEAw$R6nt{RyQCl6hENs=08VzY#^8R*wjA(yls-e}SV= z)CQFW<-g|fgThopsX0s_et)a6UavF(RLKx3ssfS zHA%pCyzVdw+-6}NV~7PgSJK$}bO3($7^Xr$YDeVQhIZ^Z5d+BI(WDmN3$ymY5Svfl zJ{~5XjU{(c*>khyQa)Opi}H5@cMb%{-DY6Tq`G@vldEijF(M)|drz1us+o@gR*Dh3xAl1cCW;aMhK0l-xSX{tIis|AcTt7YXu?|Q zCvRRSS>Sxx;2ER+!z_~$hZz&H4jAiqSBH$f>@Pupw9ADl zp_*O-^&*R?nj@IZN_GdrzqZ2gz}i->O)5Z`MC*I%DtTU^c2^r0{rHu;3q{)>cumBN z6<`lmI)n{2HbEDV$pv1OREa%>uU~BoNCE7k+}y?+x4&PqEz?S~jQ5V$_%N&u zncnmBYW8sjWTq7+m<#`e@cU3u8Nc0f5QlJ>@KOEI0u*8P>DH?4dbj8WIzyG5II0eB z%nUS*m4kjrQojSMruN>mW7e9a82y)XuDet_q}DyJ9v4`T^PsJ$y1V8L=ZNsBi5>Q7 z5pSuT%&{xWMlu~T5(hAY0mwey!nbvrA};15W+kqWsV5jcdXL%RE1Ww@>Z~XAfYYaS z$O6ZkjWEPqO|BJK%2iC>929G+lM&dZX*FFR2~$O|py!zAdx-0<-^Y9&9kYDCpvo>a zGcI&U{Jxf!Rxj1{{++Y^cHC9?c3JF~H+Q}_pU$(T3Aw~L{P^ZEZQJ`U6Z!x-Z|v;G zikj~)@a17`*Iys5NLi9uApjINS?aY}8zM`)7z~Dvp+RE*CCcSpU27i-I!ZG>`$(N= z;P_VLcueCUW#LkmnA3pSW~TbBp0|0q90ZO7D4HhPbF&BHpU7Sn3I}jB#$(#Wq_-m?i zR$^6F-m#TEdTZb6dzEa1CqS)g1YKBhd0hkhar?yHmQYi!6p8p}3fL;z#RQTl-$RGc z41jCPe}8bh)J-kJ8550hiGzhD`W}T)H^Obf$KdP5oYP zP$hUlT!=%)E3Z{%z#=0f!-$G3Vz8~JIz`U8Od2ZtkA@v#Y1&RPB=2vXNWhmob!zdS zYO=Vda4Wg<{X!-JW9U!Qb!gyeS<1KUU(c6B>TF-$fQpg2SnVSh`lnE8G)RDg`}kIp zS$cFArPniLf-VIAJRqd#d-;P(@#5sCRGR|P8%E=G1kP3po99r_caqt-hKGhT37Du} z#mU#%-pBsC1J6Q7)T|IoGJa}nM>Wrm*wd3R1E35|See4S*3(roCwmKA2)GMRPLlx! zJ)N=mr>{-LLc^}JXCB^Rf0^+^EfsJy6Cw`yk{D<6uqCa{YSSd%mEH zq;j!F@R2X2Wk4H!6OY+I91)uqZ`d>vq!ehoIX(fK+2__|^eVsw7mn9w>)-nY7Oc~q z7TZvh_-&Fu>DBaJy7~IHi0rrBib+Y?))!@d;)2?UlcadKyZpTJ@bDYX4hxSgQO5=M zF3{cJ$F6LZaSC;fciPFfisZq zAAp^hM1KkjCshtVWMji3A3XkgsI!4lmcCZ&b!w~8qU3Hin9dPS%n>6;<)b-MYr{ss zq#U=4XbflEF!(}f??Ya-Ha4CA=`UiX9dd3bC+B)BN?&Ja^;y1uJh)5?y8dg6t4H{h zlAo?gXhd=3dn+CZI7L8Kn4_HQwp}?w;k4k_QD%1yogK-VlJM*Kv*Dy~W6oo1MZKr}kF(j05A*HR-Zerh zom_LctMtW_E9sj1HeKq<`~fPH8#c)1B#8F$jPmM=l4y z2WfvFU3o4S;j+y`p;n8zSNW$G=<({-)5Bps6D!r@pgK< zV`pmJ>%AqthTlg6BQ-wT#+vL>HBAI6vL9tEKZ=PjfR_A4uc&I56QkFA-m;d=*-tLB`p9q|Otc z1$NXocvY1;7&eDg=siBBmQ9SkI2H|)-}_5z>#jj=Ujor%Vq@u&37ycT7K^9t-ucE; z1qUn`f5gRh(Ye%#i~p;LWxgZ&eKT0Sp%8t z&h9o}-Zi^7hv8+PB%7p%b}M$@l4suM)R3ptxIF}CZ66Z>*@;o)j4mmI_x2@@w@wZl zAu=XQ6mc7e@J+m$k46+t9cBQR!>n!K5WMlHM%NH5*aYkG(pR1y;Zv`5EFqrbrLWW=J9@FYx?1J_>*Z%fDG>2==e}{`w1m=R-Raov%`7R_wRRB6ur1G})Ag+U z;w@7zNBGH;-%+%*N?6ukOLEGD zX5jWqlGAV(s~O_Aa<=ygEHZqnw#?O#QXvp8$h zRy@xYU{t24SF7bKZ(Ebo9yq7(7G4{kp*JM?Z@u6bnkiWz-YnzVS;SlOLme*j%DfK~ z)pDP%dVO$tIGD1DK0SrF>e0KTOxH(O_=7<7=*7| z8Y~tG2&6RghhMBJo=r&>;)TUQufW?(v=;>GlSzh7aVR#&#izeyd2sDwTO=*9 zD;P?M=KORJWCF?gTXheGs>sLF9>he{wb*UY>QFFDZiAFSw=aR6vHW`&RF(iHDyZZJ zooe-KRd5^>Tz}}~ZJ#0L(-&Cjwb!gYAadCEzHNWV7`wyQ|FNCGwNB^2`sytFQBAX_R>kn_lHDQT8-=w*%fYHnC}a`k-&u{M^}2Q1mj(Zh=cS)%m<_ zHPJ}up$W?DHjQ)9KAY<~J>+{d8-k9zvJ7Wcyuk_!KVxA<}Ks59V4*r-{5tU3vX z^jGrPyA;PhK!DIcUw3|U%*xIlC%jwVp6dUN2+-<3yQZSQG>RF!*$({-NvAaGn2ebp zR#(4`=G>K_zt&907aEyNK;j~IpSa+R97D--+~;cGDtk0{m)s}BVO^5i91@`D{wiSN zlkThgMu@1>)|-pgJV3Td9Oj5w;0>9a_D;u}?mbg-J>FIj>u3syqR67zJpLA^&P|8c z_#u8%c{564r^lK-OsQ2|#TrIEgjrsCy`JI6$)R6s-NHAwl#0?*c0|*gAcZ@GxY)reHouPx3&e7#`P%c4p&{b-jv^yUI;OXTJ8-fV)8|dpLz3 zyRRo(E7;l0bHH7aVDFC@OS-o&@j!t{DxO<|*my~yHwcrY4H6gB<1P_`{<4ml9q`l6 z;p}C7*d4p$jlc5`r% zE(oafwV>Y~dgy(jIv#ntulv8oR*y`IK8u~7)Y^*!^(51AzEBMl#(N?)4gpgQS8(z- zltg_*BB-M8blmKWC9L;f5_FP9BLM@d&F6v6MyD5iJ+{zg4FSo~{P?~H&y8KX7A2`M zAm?I_&CX=kPVUe=P#U8-A8Wc27$aef2v;w(UFmJN07r;Sa_?)UfbRzg|+<4iYCq&QWEnQsA$Jo`xxTx`>rWo;cEcP(~Gomt3jHVK;oGGhPsXu!^J7XHdd|lnUS| zc*(m;-7oYUr{Baen=>fn%V}JSqRnYqihA);ACzU+HiD~n`KQNanBJVPRk3(aOo#B5KLy)bX-^UX_-ib zKU+So)Q^k5w@nA+a*QyPawzqmnZ1O#=D5qc{t&<(O#?UP@V|Ix;J(#+iP-NbZb;^i zsspLxE|6-K8&$Lp2zSo$b`? ze4YvlU0KP+X{n!=H>k}*JvG6sZ7`%X01Gq(8MGqQlfFvS0He%>HuMT23!%1!% z887vgR{5^`e%}5z`XgND!~M$-!TBLTB8U0>GZDjILN{+@xfnCyrOY4gityu&?z?Oy zh+QH$M1S3KJCIQHt&)n#56L!cFfjmIs@=x4d$f$#srMJmwlH_vX)>&(QoQ93rOfIn zEBiVTe%6GF`R>*@AT6lFjQ9hBCew66N*U;zUWDt&Z&^j5yq>p}hpfHe`^jn@iFb_0 zw=6R)WA#tXOwNFAuHWeIf|=42Z`wJByRUvKxVJy3@t>Twl}H$63~$!GMakA$+=ZX* z+avqgpq9ajY1dkDO_{xY;{N^l3K@2^;~GE_ehZ@35qmxyx%{Yio4~%~-RdHy8>H+O ztx##!KSG9r7uEFpfN2Q8RjX(1-mtA-UNy5JT|L$i(0koQ$?@q9v3;<1TY7EJ@Ykh? z7dloTT1|ALSI_@f;dvDl!qKV|G}$O1e|bFdz1P8rmFwZF(O>fEOBHSCt?p9uvs!fC zPK5K+vv$79+c9*Cj2R^JA*zR}fT#%Jw*FFjgxuRwi~!tx5&QH7M?=pt|H^paKq;SU z!~7lzqzGd};I^BX5eKN=$EaO3=BpEy_kZw5lz0Jw%cs3=)w|i3I``+9O{F#~jzz6L-pwLN4rYeub2epAM zNd{5#Ky1`TXt1cqCN>OXibW%JZX?*#^Lydnb-<6yaWL0(VmcsqblZOhh;g2$W>~aK zE{t&j=3!;KlZM7e%g_{P5PjLx4odmYKwUU20leb~=z>VGbqLMqin|^9CdFh_CpwM( zA(xeA+iuTy0fnVa`V$f(#ETqforV8$a6AhSwA9VSZc7xQvQ@pgk6E{s)v9B(KSX}8 zRB&e+hY>BS=8lqgsZ=d{!=?x^Pbjr%nO1brr90Ho$%*G7d{JzEH?fEc3fGsiZJhX0%FcIa0F`rbcGec( zpRyZuf?>VKuh1ww5|v%BlJ|TwEPAxi(sF0R3pMl^8Xe=9B>e&A9_W5qnKsLaSLAGv zRuFqGH)65r1l1frsOJ-WWx z2zNOQokO~e{fVfqJ5=7(pjsKL``J|C#fz->q&%{>aVgmu7#P+j{+IG-+gH-mt&Kaw zM62;@%&IZ-iyfVV$sLT1LdA#A6!0}jFVPCD=`!Dr6RrC3j~2>%@+`1eSCxz=rL&yX zzQrVgNPtA6lq47(o4A`UN`!V$it$KA4Dwx(jMLGw6 z8FG2)v;`LRw9sBqcRvvYdAMSTF9N38)Gqh7CTOM$9>nDselm$RiQ^L(pOL zUj6@Eh$jplp*=-z{g>Ks<^${)9P(*dp^TrV`9FboZWim6l?^Q8;8L@D~iqe zbn~t)44frD6K-|;O)iTq$y8x^A=Ys6*3D#LN$;#NRwYhxp!=1wU2=Azlk3gz0oOD4 z1$@B2+< z!}{q@nUvgYZJ%)g;ry<>AE1{`YtKzrNgzmkDnYX5&QP9wt*vEO5)Cq>k3U0>;7HMr zuNvy1%P19A`jo#vrTC|CQ(f^zztci-J0p@JN9&54T@e~Vq%Fb`AC--s9QN__-@EHd zle{}MRHVVg!o`)?8BUU7Naj3wyE)O2EN0vK1;iLu2~JqC7uTX(F4z%H(+^8DIT ziJsT>yZ{D=TmVn6v{R3V5#xW&&42xt=wL0xFkcVubt}A}DMEFp=?WRFcPfJ~N47a0 z=XtQ>ods#fP6Kn;XZr+~db2y0d9kmYCiGmZ9A>k-`3IPm-=R=DwPC61Ru!3rdWTapsZ-*8q`-;POpxWJLZ zgm2iTOqCRZjzQ7_u!<*pqtOpUIW{N1^G`6ez~46QuC-}~KEd~aD;02VFh}~@6eSJ} zHX$cRB4v=TXNrigIKeAs^ocG^_EkE#9Ojpsv5gP*_NnhPq9{q^KB5m3DbSGlV-0n)v zFl{C`2mXu-+oCIf#t5nX)dy1Bhez87N&gf$G_+B`MOI^W% z7zQZp46`THIC;q(?~x^$lwTK??e_j9#bwr@ha>@AK!2*J%84p8R`{x71f4}qygS=B zyJVEux%}A`-mB_w?aFd$1DIn}KgWyI&%bAtjOICOYTvn>6=<;fv}Z zWx?;a;Dp9A2Si|Igo0xsI20yXR66jbCaauOA=W%91KzRoE#nN8&&|^K74}CKTOgHrEkTT2XYvz# za*Cv3QSP4;FCP*{N6vTfWYcH1O3(lDc0nYB33W;=2!Hk7FS8Y)NqLS+i65FTiwJ}p!dSYb(0xdZI{|(ab%%OHLtG?Yf7*MbgCo^ZG}!` z`gQYporNroc)$S_u)IRo49eyBqFb>=*e}8;UG9GNzYg?}Im_tJ*12+(FSr}busME; ztu%A2PjiKSmK0;h6HL>W77b@Y!eByjF04lA)%cVIRSh7fr-n&I&*bG?3{#>Wp7_dK zA&7@^-7X3I;&H`AA0+1r0QlQdHhUF2!3VNLMclX5{*6Xh-_lY`tu&%{F{%B+5R67zf87(dzFmV{9CZBm8Bf`r(ZX!W$|3jZggA zPMt|*{3An0&21#cR)R2&=(|vMZuqmK5m9clD2|m|YdO=*d zeL_uwc%@y(I%aWKk2xRo%Rk029&%eCNV5 ztxz*Mf9QMv>)9q`zf(WZ-QL+vp`jQbA2w_TvJxz7b>#v{YD3`JHe=QVv+%+UBhq@J z$%VOd%s=JdlbOtl!6&R}rN84~`KBdtQ=Ye#U9RHQ$jWWt3pO8Mj1hoLh39cIjVsx$ z9!>;7z#`U$b76p6t93sAd-5r|N23ufQxT@INxc=`Ged1-Z1vH(rfMJ?ija)6c=Z*+ zzd25jz6W^&BPkQwA>a^W&f=(usUTQiWZ2( zfwz;T76H#2hSXc?_t;@A~0dU z#7;|RU9@W;gHN3IhY|p3=ra{fGB;b51!b)fQP*|$S@V;bRjGHJZ=vpBAGZ^*S(4cR zGQ+$pW1@>DGo`N;=nBhonp_9cc56yf+L2mWyI3tcE}ja`eD)0u_z+ zp(ZUgSO!!~v~i3w|MYKK2OU^EolxzU7Y>{6EYl>_#A;OmyMFNtqgNUQl?v@B_Zw(D z`hAY=kUd`83N`wt<~f|`Bo0vqAWn!>i)^*V-&Qo&$>VCucz(Ap)5*;Rn+7R`iE2ZF zJ0q<()f`DaD#J!23k}UrL_UrYqEdl{_36kncSGBW#PK{&<}^M$82S0eSvn+*v`I6M z9qp2&@Ztmrf|7nvTHrq$EadeAF4m(YvE%!mfp_XqTCe z;Z5`C`d4eO;`l5>YymevF?QoN_9)p#Dfj`{mo~dNPhJkBrx%|9y@HZQifP1Ms@r_B)Y%Y;Ij_1()e0s%Xi4q*q}LZND!J+=`#+D8VZqnB0cUdvckh*= z<^>;^g-Jw&6X>6K=$_O{9u%g22dGsm7LGRNE*=@cPyFp-zT&ZLZ4>|wC<7k%GxhHa zw+&7+CGdgeM961aO$b;3m1)W6b$xg@+O1f0Z{G-dW;X7iLs;MVxD)jt$bgPpVA=O`wirwNh+Mya%#IPY9DaqZZ@JmviMFf|iw^KYa{&0eRy!#Q$! zKmzR05;$u>G=v|^vs?J6U(qy($yK-t$Zir+ceKjXhdI$wfj2wa3b-e66FgoUayBXJ+=L0z>J{ zSW^}_Fl)7q#0^3|EJSwU77!`j)s#6- zp)bw37W|P7A$7AIgpNn`Qh%^TzM%uuU;jvXoz`O*6#FpjWMqP?0cJ-0TJ}K22SSp6 zn1Xmf33rHc1fbKSVp5Mo+isx>CkljVkRK&FiaG~2G*Y4^)20HCY{U4TPWJtWkrDM_ z@#Es+V(uGJziV%cg_dT5G=EuoCgUg)(UJ=m?m|0n4FlHVTE*j9vOi4?j<{>jfkGc6 zV9LnbrHk0GgE*)p+p|#+Q@MbfJ%gWj*QooAs@s;ozY*9#O5K$I7g);ewrj9CQ&V!e zCeZqejX#duJ|ODe>mIrkA$hIvSL$QGGS5C2m7M5c7hTfp9}SXwdb6I{Sl*hKEC#1h z^kYt)qBg7CC}nsaEUm$ow+FR{QTAXLU z5ah!1O0_}s5Q-zxE86(sA7+2=)%%L+gi>1nIs~N=Vh>?0Xj=cV~w+P3??)NK500WmI~Z2z0-L zsvWaq`fx2Q_=>zkYY0i{RHr2%n30{t z7R97dK%4H2z45Y=t@p;-)qXe{W;nDpneZCEIt3J=6CA2u`75&uRBq|EOzELeI1)n; zE+AR1zYw5uIWrGSDeSx@20+UYOzu2GXuVw285t6 zj1Ai7qN&Ru!&@Gg2T$?ROMK{&pBv`mN;i^WZfXgpujuTTCE6C+&N82te(I{mvgznpM9D-1+gFcL>rAW(;a$^p|dSf4672Sl%xHz4AqK`p%7@ZRGUxhgltHGS zv1=c+kNg0`Ji3P_LRdj%QrXD6FR@DVNQP!H%wIGMh`R3D5d2ICNgdjdAF_~@1>1$E zcd*@%5Hv?*|46Q}n2;w)QAh!;*D?Vh&19$Y^;9KGo-r=q-uQC=djXEpFNG%1IsVs~ zHSX;8U%2KUk@s)sg+EJpCN}tkNfn%XQ%`N&ia+uy)MX}C)K|yt_0Xo;Inx4O1D?eU z-k&CzCk&bTxXmDUvls=KwyExO zAwbPc-{c_aKo0qZwGq}|o@mEir$Rar3L2S$e~6*cvKqG%ZB5Y3Vr;mYJd~px9)N!K zLB2R5A@J|>49sC*Z-h0+c3So~I@|$$gJ5m5JDdMLPT)6nrbgDwa?n`gO>>6ap{j1^nXqS`v21*6+efgZGeSqfeL|HhN zA)n0#6J)}Pdvc=0SOKXW|CWI1>FF-$%IHhNPs}<4>Zp%x7kjN-u}mrnR~M&>uCDyx zzzKAa>VuRVn%BL7^I0;vR9HmDP z=m2H0g;G0!&C=2Djt&ky*a(bWUVfP*<^#V=%H1*d`JYyqzBFNNxa-e%$n&Iz3XwVL zEz}z%qW_$?f`PTsz59=%s4HThQ>Oyz=;%nxEE$UrrG|k=Bc-ze9l*p11bz^K&elvP zcNb^3%iq7&DA)E!bb*oopRQ7c!8p&e@)~(JEVut|s=q=orF-O`jqYu?1>8DV4(ECbl*GAqp!6lWyA(>5@N>5AJ2-MeV#@pJ1`O#2!a3pHlk0W}`13Mw1V#f$A6LB= zF4FA=&woYvS>Hbg`pol_yI8W|Fq}Xn`dryi6#z#rC@oG^zB;f&Y6-0-InT;(&bcRLIhoD65#ZFueOcCC$8c&l%qih z+EXA;CS5wN#a1H&P*EP(ob;FMVqhYr{*1|>tPwD0-;RUq@rxy#Xm#E#i9}P$5JSx6 zXxrG78rXk92j{WSA{*Jj0V+zqC!aHtGAsg%ayrdY9YQWwx%{Fd$OU?-Zhp&wUdiAy z4_)1)rv0zj2OvTu&|N5~7^$%jtq&YZH(xB89{$LAp1sjC0^nnerqr z>usc*GSSc#EHDyjfT;p*x%NW!e;;yNZ~Xr=?WgZ{zn=yyqGmOjF1(@=ad?xpw z-bCQMSVr=4#}^#$&&)JF`@gHJ%V*J=&bQ_JKFfmED!*8?^+wC~oxe+e9i18;m+98C z|Nr0jvwywJ_zYa|o_b+{)e@~oYzXw`Mw<34a*(q%Kzj>DeN2PuMi*bg1vl!-=-O5zkSod^l z_><@M|99GaI-#t#aNYb5X65_)B(gtMUGh}-yuB^=^}NNLyU$r(%M`WxwC1vo$&VO6N-|GUW z!74vLJNdruyS4H0@aKH?-)^rU^WG`llHKW@dejZtMYL11240sy(?z#st0b^EV^5I zedhm{SK4lPyRRzcYPMSrOjVyw$N$^(?zmOdUtp#;YQH{to-=UpNx%(QSs1wWS^=xs zQ%t*}oBEnwdA!?@cz6kL9d6qCC|eGv<>r4Lu-hA4X8v;NXy&XR;KjVa+ikxS-;+@qx-o<*w29b25{Bx-Hb!Gul)UG9D5@yHa2%&?YEohvwt41DsVeJP1o0` z_Ihmj$<^!kX@Pc-7Ppq}YI`TMFj)6SyZO^RXGWldf`AU1z}A-qbWj!(Fm+7@X7B$d zCm&5zc7Mfnxi#CWX;m=uo3G35|DHV4e>L~OmrE%@!pV1o-h4W(Z+^S~<)JO=^D3M^ zeg3>ZXyen<(`N^tGiki`t2h4s`rOKBZRy48H%r^oUNl+C zTK)r0`<^v6sl2XjZhpPzPg-i~#1G4^rB;{%b8ZAM=N>t@_!Thc_BN5;{bldhr$N0Amsp_gSGEn`;MH#* vu$yBgmoN)BJOHU}N0orXVaSEcpZc?*{?DSOR>%R5Ze{Rv^>bP0l+XkKbRfUa literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (3).png b/.gitbook/assets/newplot (3).png new file mode 100644 index 0000000000000000000000000000000000000000..d63d2657bb4ba54db85ef0a02bdb9561de0afdce GIT binary patch literal 24476 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 z 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (4).png b/.gitbook/assets/newplot (4).png new file mode 100644 index 0000000000000000000000000000000000000000..6d5d7f71af16cb3f295a1521adb983e418b83248 GIT binary patch literal 23001 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 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (5).png b/.gitbook/assets/newplot (5).png new file mode 100644 index 0000000000000000000000000000000000000000..0c92dc78c47e65a23e566f00e1577a6d74c4e456 GIT binary patch literal 26223 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 Y9b5gPV8c%MBN-km^OHwknqIu|AHM}5RsaA1 literal 0 HcmV?d00001 diff --git a/.gitbook/assets/newplot (6).png b/.gitbook/assets/newplot (6).png new file mode 100644 index 0000000000000000000000000000000000000000..3840faa177735e7334659f9454b20de0f9d9e6db GIT binary patch literal 12968 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%0D44x&shRtgH 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 Nl;t(#DrBCA{4c2le;WV* literal 0 HcmV?d00001 diff --git a/api-reference/dataframe/README.md b/api-reference/dataframe/README.md index a45aabd..d48a28d 100644 --- a/api-reference/dataframe/README.md +++ b/api-reference/dataframe/README.md @@ -5,10 +5,10 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da # Dataframe > `DataFrame`(data, {\ -> **columns:** \[ Array ],\ -> **dtypes:** \[ Array ],** **\ -> ** index: **\[Array], \ -> **options**: Object}) +> **columns:** \[ Array ],\ +> **dtypes:** \[ Array ], **** \ +> **index:** \[Array], \ +> **options**: Object}) ### Attributes @@ -16,14 +16,14 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da | ------------------------------------------------ | ---------------------------------------- | | [`DataFrame.columns`](danfo.dataframe.column.md) | The column labels of the DataFrame. | -| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | -| ------------------------------------------------------- | ---------------------------------------------------------------------- | -| [`DataFrame.select_dtypes`](dataframe.select_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | -| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | -| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | -| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | -| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | -| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | +| [`DataFrame.ctypes`](dataframe.dtypes.md) | Return the data types in the DataFrame. | +| -------------------------------------------------------- | ---------------------------------------------------------------------- | +| [`DataFrame.select_dtypes`](dataframe.select\_dtypes.md) | Return a subset of the DataFrame’s columns based on the column dtypes. | +| [`DataFrame.values`](dataframe.values.md) | Return a Numpy representation of the DataFrame. | +| [`DataFrame.axes`](dataframe.axes.md) | Return a Object representing the axes of the DataFrame. | +| [`DataFrame.ndim`](dataframe.ndim.md) | Return an int representing the number of axes / array dimensions. | +| [`DataFrame.size`](broken-reference) | Return an int representing the number of elements in this object. | +| [`DataFrame.shape`](dataframe.shape.md) | Return a tuple representing the dimensionality of the DataFrame. | ### Conversion @@ -87,15 +87,15 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da ### Reindexing / selection / label manipulation -| | | -| --------------------------------------------------- | ------------------------------------------------------- | -| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | -| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | -| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | -| [`DataFrame.reset_index`](dataframe.reset_index.md) | Reset the index of a DataFrame | -| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | -| [`DataFrame.set_index`](dataframe.set_index.md) | Set the DataFrame index using existing columns. | -| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | +| | | +| ---------------------------------------------------- | ------------------------------------------------------- | +| [`DataFrame.drop`](dataframe.drop.md) | Drop specified labels from rows or columns. | +| [`DataFrame.head`](danfo.dataframe.head.md) | Return the first n rows. | +| [`DataFrame.rename`](dataframe.rename.md) | Alter axes labels. | +| [`DataFrame.reset_index`](dataframe.reset\_index.md) | Reset the index of a DataFrame | +| [`DataFrame.sample`](danfo.dataframe.sample.md) | Return a random sample of items from an axis of object. | +| [`DataFrame.set_index`](dataframe.set\_index.md) | Set the DataFrame index using existing columns. | +| [`DataFrame.tail`](danfo.dataframe.tail.md) | Return the last n rows. | ### Missing data handling @@ -110,7 +110,7 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da | | | | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| [`DataFrame.sort_values`](dataframe.sort_values.md) | Sort by the values along either axis. | +| [`DataFrame.sort_values`](dataframe.sort\_values.md) | Sort by the values along either axis. | | [`DataFrame.T`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.T.html#pandas.DataFrame.T) | Return transpose of DataFrame | ### Combining / comparing / joining / merging @@ -139,7 +139,7 @@ description: Two-dimensional, size-mutable, potentially heterogeneous tabular da ### Serialization / IO / conversion -| | | -| ------------------------------------------- | ---------------------------------------------------- | -| [`DataFrame.to_csv`](dataframe.to_csv.md) | Write object to a comma-separated values (csv) file. | -| [`DataFrame.to_json`](dataframe.to_json.md) | Convert the object to a JSON string. | +| | | +| -------------------------------------------- | ---------------------------------------------------- | +| [`DataFrame.to_csv`](dataframe.to\_csv.md) | Write object to a comma-separated values (csv) file. | +| [`DataFrame.to_json`](dataframe.to\_json.md) | Convert the object to a JSON string. | diff --git a/api-reference/dataframe/danfo.dataframe.abs.md b/api-reference/dataframe/danfo.dataframe.abs.md index 83c6cd3..8504222 100644 --- a/api-reference/dataframe/danfo.dataframe.abs.md +++ b/api-reference/dataframe/danfo.dataframe.abs.md @@ -12,7 +12,7 @@ danfo.DataFrame.**sum**(options) \[[source](https://github.com/opensource9ja/dan **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.add.md b/api-reference/dataframe/danfo.dataframe.add.md index 467c143..925a3cd 100644 --- a/api-reference/dataframe/danfo.dataframe.add.md +++ b/api-reference/dataframe/danfo.dataframe.add.md @@ -13,11 +13,11 @@ danfo.DataFrame.**add**(other, option) \[[source](https://github.com/opensource9 **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Addition of** scalar to **DataFrame along default axis 1 +### Addition of **scalar to** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -60,7 +60,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** Series to **DataFrame along axis 0 +### Addition of **Series to** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -105,7 +105,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** **DataFrame to a DataFrame +### Addition of **** DataFrame to a DataFrame {% tabs %} {% tab title="Node" %} @@ -152,7 +152,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Addition of** ** Array to DataFrame along axis 0 +### Addition of **** Array to DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.apply.md b/api-reference/dataframe/danfo.dataframe.apply.md index 01fab60..de42294 100644 --- a/api-reference/dataframe/danfo.dataframe.apply.md +++ b/api-reference/dataframe/danfo.dataframe.apply.md @@ -13,7 +13,7 @@ danfo.DataFrame.**apply**(callable, options) \[[source](https://github.com/opens **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.column.md b/api-reference/dataframe/danfo.dataframe.column.md index 2d70bfd..7d963a2 100644 --- a/api-reference/dataframe/danfo.dataframe.column.md +++ b/api-reference/dataframe/danfo.dataframe.column.md @@ -12,7 +12,7 @@ danfo.DataFrame.**column**(column) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.copy.md b/api-reference/dataframe/danfo.dataframe.copy.md index ef705ed..188179d 100644 --- a/api-reference/dataframe/danfo.dataframe.copy.md +++ b/api-reference/dataframe/danfo.dataframe.copy.md @@ -8,7 +8,7 @@ danfo.DataFrame.**copy**() \[[source](https://github.com/opensource9ja/danfojs/b **Returns:** -** **return** new DataFrame** + **** return **new DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.count.md b/api-reference/dataframe/danfo.dataframe.count.md index 9e9916e..637cbf4 100644 --- a/api-reference/dataframe/danfo.dataframe.count.md +++ b/api-reference/dataframe/danfo.dataframe.count.md @@ -14,7 +14,7 @@ danfo.DataFrame.**count**(options) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** Series** + **** return **Series** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.cummax.md b/api-reference/dataframe/danfo.dataframe.cummax.md index c46ae7b..fb69bb5 100644 --- a/api-reference/dataframe/danfo.dataframe.cummax.md +++ b/api-reference/dataframe/danfo.dataframe.cummax.md @@ -12,7 +12,7 @@ danfo.DataFrame.**cummax**(options) \[[source](https://github.com/opensource9ja/ **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.cummin.md b/api-reference/dataframe/danfo.dataframe.cummin.md index 53f4045..be026a6 100644 --- a/api-reference/dataframe/danfo.dataframe.cummin.md +++ b/api-reference/dataframe/danfo.dataframe.cummin.md @@ -12,7 +12,7 @@ danfo.DataFrame.**cummin**(options) \[[source](https://github.com/opensource9ja/ **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.cumprod.md b/api-reference/dataframe/danfo.dataframe.cumprod.md index b780cd2..06ad53a 100644 --- a/api-reference/dataframe/danfo.dataframe.cumprod.md +++ b/api-reference/dataframe/danfo.dataframe.cumprod.md @@ -12,7 +12,7 @@ danfo.DataFrame.**cumprod**(options) \[[source](https://github.com/opensource9ja **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.cumsum.md b/api-reference/dataframe/danfo.dataframe.cumsum.md index 4863805..07be896 100644 --- a/api-reference/dataframe/danfo.dataframe.cumsum.md +++ b/api-reference/dataframe/danfo.dataframe.cumsum.md @@ -12,7 +12,7 @@ danfo.DataFrame.**cumsum**(options) \[[source](https://github.com/opensource9ja/ **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** diff --git a/api-reference/dataframe/danfo.dataframe.describe.md b/api-reference/dataframe/danfo.dataframe.describe.md index 4dac614..0540873 100644 --- a/api-reference/dataframe/danfo.dataframe.describe.md +++ b/api-reference/dataframe/danfo.dataframe.describe.md @@ -10,11 +10,11 @@ danfo.DataFrame.**describe**() \[[source](https://github.com/opensource9ja/danfo **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. +Descriptive statistics include those that summarize the central tendency, dispersion and shape of a dataset’s distribution, excluding `NaN` values. {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.div.md b/api-reference/dataframe/danfo.dataframe.div.md index 54123d9..c98c66e 100644 --- a/api-reference/dataframe/danfo.dataframe.div.md +++ b/api-reference/dataframe/danfo.dataframe.div.md @@ -15,11 +15,11 @@ danfo.DataFrame.div(other, option) \[[source](https://github.com/opensource9ja/d **Returns:** -** **return** DataFrame** + **** return **DataFrame** ## **Examples** -### Division of** scalar with **DataFrame along default axis 1 +### Division of **scalar with** DataFrame along default axis 1 {% tabs %} {% tab title="Node" %} @@ -63,7 +63,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** Series with **DataFrame along axis 0 +### Division of **Series with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} @@ -110,7 +110,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** **DataFrame **with** a DataFrame +### Division of **** DataFrame **with** a DataFrame {% tabs %} {% tab title="Node" %} @@ -159,7 +159,7 @@ df_new.print() {% endtab %} {% endtabs %} -### Division of** ** Array **with** DataFrame along axis 0 +### Division of **** Array **with** DataFrame along axis 0 {% tabs %} {% tab title="Node" %} diff --git a/api-reference/dataframe/danfo.dataframe.dropna.md b/api-reference/dataframe/danfo.dataframe.dropna.md index 81006a1..429bcbe 100644 --- a/api-reference/dataframe/danfo.dataframe.dropna.md +++ b/api-reference/dataframe/danfo.dataframe.dropna.md @@ -9,15 +9,15 @@ danfo.DataFrame.**dropna**(axis, options) \[[source](https://github.com/opensour | Parameters | Type | Description | Default | | ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- | | axis | Int | 0 or 1. If 0, drop columns with NaNs, if 1, drop rows with NaNs | 1 | -| options | Object |