Skip to content

Commit 29a83b6

Browse files
committed
Merge branch 'master' of https://github.com/opensource9ja/danfojs into browser-groupby
2 parents 053e890 + ae1ede3 commit 29a83b6

36 files changed

Lines changed: 1570 additions & 1966 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ easy and intuitive. It is heavily inspired by [Pandas](https://pandas.pydata.org
5151
To use Danfo.js via script tags, copy and paste the CDN below to the body of your HTML file
5252

5353
```html
54-
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.3/lib/bundle.min.js"></script>
54+
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.4/lib/bundle.min.js"></script>
5555
```
5656

5757
### Example Usage in the Browser
@@ -66,7 +66,7 @@ To use Danfo.js via script tags, copy and paste the CDN below to the body of you
6666
<meta charset="UTF-8">
6767
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6868
<script src="https://cdn.plot.ly/plotly-1.2.0.min.js"></script>
69-
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.3/lib/bundle.min.js"></script>
69+
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.4/lib/bundle.min.js"></script>
7070

7171
<title>Document</title>
7272
</head>

danfojs-browser/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ easy and intuitive. It is heavily inspired by [Pandas](https://pandas.pydata.org
5151
To use Danfo.js via script tags, copy and paste the CDN below to the body of your HTML file
5252

5353
```html
54-
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.3/lib/bundle.min.js"></script>
54+
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.4/lib/bundle.min.js"></script>
5555
```
5656

5757
### Example Usage in the Browser
@@ -66,7 +66,7 @@ To use Danfo.js via script tags, copy and paste the CDN below to the body of you
6666
<meta charset="UTF-8">
6767
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6868
<script src="https://cdn.plot.ly/plotly-1.2.0.min.js"></script>
69-
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.3/lib/bundle.min.js"></script>
69+
<script src="https://cdn.jsdelivr.net/npm/danfojs@0.2.4/lib/bundle.min.js"></script>
7070

7171
<title>Document</title>
7272
</head>

danfojs-browser/lib/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

danfojs-browser/lib/bundle.js.LICENSE.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,23 @@
146146
* =============================================================================
147147
*/
148148

149+
/**
150+
* @license
151+
* Copyright 2021 Google LLC. All Rights Reserved.
152+
* Licensed under the Apache License, Version 2.0 (the "License");
153+
* you may not use this file except in compliance with the License.
154+
* You may obtain a copy of the License at
155+
*
156+
* http://www.apache.org/licenses/LICENSE-2.0
157+
*
158+
* Unless required by applicable law or agreed to in writing, software
159+
* distributed under the License is distributed on an "AS IS" BASIS,
160+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161+
* See the License for the specific language governing permissions and
162+
* limitations under the License.
163+
* =============================================================================
164+
*/
165+
149166
/**
150167
* @license Complex.js v2.0.11 11/02/2016
151168
*

danfojs-browser/lib/bundle.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

danfojs-browser/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "danfojs",
3-
"version": "0.2.3",
3+
"version": "0.2.4",
44
"description": "JavaScript library providing high performance, intuitive, and easy to use data structures for manipulating and processing structured data.",
55
"main": "lib/bundle.js",
66
"types": "types/index.d.ts",
@@ -21,7 +21,7 @@
2121
"types"
2222
],
2323
"dependencies": {
24-
"@tensorflow/tfjs": "2.8.5",
24+
"@tensorflow/tfjs": "3.2.0",
2525
"mathjs": "7.5.1",
2626
"table": "^5.4.6",
2727
"xlsx": "^0.16.7"
@@ -33,8 +33,7 @@
3333
"bundle": "webpack --mode production",
3434
"coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls",
3535
"coverage": "nyc report --reporter=text-lcov | coveralls && nyc report --reporter=lcov",
36-
"patch": "npm version patch",
37-
"publish": "npm publish"
36+
"patch": "npm version patch"
3837
},
3938
"publishConfig": {
4039
"access": "public",
@@ -86,4 +85,4 @@
8685
]
8786
},
8887
"sideEffects": false
89-
}
88+
}

danfojs-browser/src/core/frame.js

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* limitations under the License.
1313
*/
1414

15-
import { tensor } from "@tensorflow/tfjs";
15+
import * as tf from "@tensorflow/tfjs";
1616
import Ndframe from "./generic";
1717
import { Series } from "./series";
1818
import { Utils } from "./utils";
@@ -183,7 +183,7 @@ export class DataFrame extends Ndframe {
183183
index: new_index
184184
});
185185
} else {
186-
this.row_data_tensor = tensor(new_data);
186+
this.row_data_tensor = tf.tensor(new_data);
187187
this.data = new_data;
188188
this.__set_index(new_index);
189189
}
@@ -266,36 +266,24 @@ export class DataFrame extends Ndframe {
266266

267267
/**
268268
* Gets [num] number of random rows in a dataframe
269-
* @param {rows} rows --> int
270-
* @returns DataFrame
269+
* @param {num} rows --> The number of rows to return
270+
* @param {seed} seed --> (Optional) An integer specifying the random seed that will be used to create the distribution.
271+
* @returns {Promise} resolves to a DataFrame object
271272
*/
272-
sample(num = 5) {
273-
//TODO: Use different sampling strategy
274-
if (num > this.values.length || num < 1) {
275-
//return all values
276-
let config = { columns: this.column_names };
277-
return new DataFrame(this.values, config);
278-
} else {
279-
let values = this.values;
280-
let idx = this.index;
281-
let new_values = [];
282-
let new_idx = [];
283-
284-
let counts = [ ...Array(idx.length).keys() ]; //set index
285-
286-
//get random sampled numbers
287-
let rand_nums = utils.__sample_from_iter(counts, num, false);
288-
rand_nums.map((i) => {
289-
new_values.push(values[i]);
290-
new_idx.push(idx[i]);
291-
});
292-
293-
let config = { columns: this.column_names, index: new_idx };
294-
let df = new DataFrame(new_values, config);
295-
return df;
273+
async sample(num = -1, seed = 1) {
274+
if (num > this.shape[0]) {
275+
throw new Error("Sample size n cannot be bigger than size of dataset");
296276
}
277+
if (num < -1 || num == 0) {
278+
throw new Error("Sample size cannot be less than -1 or 0");
279+
}
280+
num = num === -1 ? this.shape[0] : num;
281+
const shuffled_index = await tf.data.array(this.index).shuffle(num, seed).take(num).toArray();
282+
const df = this.iloc({ rows: shuffled_index });
283+
return df;
297284
}
298285

286+
299287
/**
300288
* Return Addition of DataFrame and other, element-wise (binary operator add).
301289
* @param {other} DataFrame, Series, Array or Number to add
@@ -916,7 +904,7 @@ export class DataFrame extends Ndframe {
916904
}
917905

918906
values.map((arr) => {
919-
let temp_sum = tensor(arr).sum().arraySync();
907+
let temp_sum = tf.tensor(arr).sum().arraySync();
920908
val_sums.push(Number(temp_sum.toFixed(5)));
921909
});
922910

@@ -940,7 +928,7 @@ export class DataFrame extends Ndframe {
940928
abs() {
941929
let data = this.values;
942930

943-
let tensor_data = tensor(data);
931+
let tensor_data = tf.tensor(data);
944932
let abs_data = tensor_data.abs().arraySync();
945933
let df = new DataFrame(utils.__round(abs_data, 2, false), {
946934
columns: this.column_names,
@@ -1406,7 +1394,7 @@ export class DataFrame extends Ndframe {
14061394
}
14071395

14081396
for (let i = 0; i < df_data.length; i++) {
1409-
let value = tensor(df_data[i]);
1397+
let value = tf.tensor(df_data[i]);
14101398
let callable_data;
14111399
try {
14121400
callable_data = callable(value).arraySync();
@@ -1659,18 +1647,18 @@ export class DataFrame extends Ndframe {
16591647
`Shape Error: Operands could not be broadcast together with shapes ${this.shape} and ${val.values.length}.`
16601648
);
16611649
}
1662-
other = tensor(val.values);
1650+
other = tf.tensor(val.values);
16631651
} else {
16641652
if (val.values.length != this.shape[1]) {
16651653
throw Error(
16661654
`Shape Error: Operands could not be broadcast together with shapes ${this.shape} and ${val.values.length}.`
16671655
);
16681656
}
1669-
other = tensor(val.values);
1657+
other = tf.tensor(val.values);
16701658
}
16711659
} else if (Array.isArray(val)) {
16721660
//Array of Array
1673-
other = tensor(val);
1661+
other = tf.tensor(val);
16741662
} else {
16751663
//DataFrame
16761664
other = val.row_data_tensor;
@@ -1679,22 +1667,22 @@ export class DataFrame extends Ndframe {
16791667

16801668
switch (logical_type) {
16811669
case "lt":
1682-
int_vals = tensor(this.values).less(other).arraySync();
1670+
int_vals = tf.tensor(this.values).less(other).arraySync();
16831671
break;
16841672
case "gt":
1685-
int_vals = tensor(this.values).greater(other).arraySync();
1673+
int_vals = tf.tensor(this.values).greater(other).arraySync();
16861674
break;
16871675
case "le":
1688-
int_vals = tensor(this.values).lessEqual(other).arraySync();
1676+
int_vals = tf.tensor(this.values).lessEqual(other).arraySync();
16891677
break;
16901678
case "ge":
1691-
int_vals = tensor(this.values).greaterEqual(other).arraySync();
1679+
int_vals = tf.tensor(this.values).greaterEqual(other).arraySync();
16921680
break;
16931681
case "ne":
1694-
int_vals = tensor(this.values).notEqual(other).arraySync();
1682+
int_vals = tf.tensor(this.values).notEqual(other).arraySync();
16951683
break;
16961684
case "eq":
1697-
int_vals = tensor(this.values).equal(other).arraySync();
1685+
int_vals = tf.tensor(this.values).equal(other).arraySync();
16981686
break;
16991687
}
17001688
let bool_vals = utils.__map_int_to_bool(int_vals, 2);
@@ -1754,7 +1742,7 @@ export class DataFrame extends Ndframe {
17541742

17551743
this_tensor = tensors[0].row_data_tensor; //tensorflow uses 1 for rows axis and 0 for column axis
17561744
if (tensors[1].series) {
1757-
other_tensor = tensor(tensors[1].values, [
1745+
other_tensor = tf.tensor(tensors[1].values, [
17581746
1,
17591747
tensors[1].values.length
17601748
]);
@@ -1771,7 +1759,7 @@ export class DataFrame extends Ndframe {
17711759

17721760
this_tensor = tensors[0].row_data_tensor;
17731761
if (tensors[1].series) {
1774-
other_tensor = tensor(tensors[1].values, [
1762+
other_tensor = tf.tensor(tensors[1].values, [
17751763
tensors[1].values.length,
17761764
1
17771765
]);

danfojs-browser/src/core/series.js

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
*/
1515

1616

17-
import { tensor, round } from "@tensorflow/tfjs";
18-
import { variance, std } from 'mathjs';
17+
import * as tf from "@tensorflow/tfjs";
18+
import { variance, std, median, mode } from 'mathjs';
1919
import { Utils } from "./utils";
2020
import { Str } from "./strings";
2121
import NDframe from "./generic";
@@ -55,7 +55,7 @@ export class Series extends NDframe {
5555
* @returns {1D Tensor}
5656
*/
5757
get tensor() {
58-
return tensor(this.values).asType(this.dtypes[0]);
58+
return tf.tensor(this.values).asType(this.dtypes[0]);
5959
}
6060

6161

@@ -95,30 +95,22 @@ export class Series extends NDframe {
9595
}
9696

9797
/**
98-
* Returns n number of random rows in a Series
99-
* @param {rows} number of rows to return
100-
* @returns {Series}
98+
* Gets [num] number of random rows in a dataframe
99+
* @param {num} rows --> The number of rows to return
100+
* @param {seed} seed --> (Optional) An integer specifying the random seed that will be used to create the distribution.
101+
* @returns {Promise} resolves to a Series object
101102
*/
102-
sample(num = 5) {
103-
if (num > this.values.length || num < 1) {
104-
let config = { columns: this.column_names };
105-
return new Series(this.values, config);
106-
} else {
107-
let values = this.values;
108-
let idx = this.index;
109-
let new_values = [];
110-
let new_idx = [];
111-
let rand_nums = utils.__shuffle(num, idx);
112-
113-
rand_nums.forEach((i) => {
114-
new_values.push(values[i]);
115-
new_idx.push(idx[i]);
116-
});
117-
let config = { columns: this.column_names, index: new_idx };
118-
let sf = new Series(new_values, config);
119-
return sf;
120-
103+
async sample(num = 5, seed = 1) {
104+
if (num > this.shape[0]) {
105+
throw new Error("Sample size n cannot be bigger than size of dataset");
106+
}
107+
if (num < -1 || num == 0) {
108+
throw new Error("Sample size cannot be less than -1 or 0");
121109
}
110+
num = num === -1 ? this.shape[0] : num;
111+
const shuffled_index = await tf.data.array(this.index).shuffle(num, seed).take(num).toArray();
112+
const sf = this.iloc(shuffled_index);
113+
return sf;
122114
}
123115

124116
/**
@@ -250,7 +242,7 @@ export class Series extends NDframe {
250242
mean() {
251243
utils._throw_str_dtype_error(this, 'mean');
252244
let values = utils._remove_nans(this.values);
253-
let mean = tensor(values).mean().arraySync();
245+
let mean = tf.tensor(values).mean().arraySync();
254246
return mean;
255247
}
256248

@@ -261,9 +253,9 @@ export class Series extends NDframe {
261253
*/
262254
median() {
263255
utils._throw_str_dtype_error(this, 'median');
264-
let values = this.values;
265-
let median = utils.__median(values, true);
266-
return median;
256+
let values = utils._remove_nans(this.values);
257+
let median_val = median(values);
258+
return median_val;
267259
}
268260

269261

@@ -272,10 +264,10 @@ export class Series extends NDframe {
272264
* @returns {Number}
273265
*/
274266
mode() {
275-
utils._throw_str_dtype_error(this, 'mode');
276-
let values = this.values;
277-
let mode = utils.__mode(values);
278-
return mode;
267+
utils._throw_str_dtype_error(this, 'median');
268+
let values = utils._remove_nans(this.values);
269+
let modal_val = mode(values);
270+
return modal_val;
279271
}
280272

281273

@@ -382,7 +374,7 @@ export class Series extends NDframe {
382374
round(dp) {
383375
if (utils.__is_undefined(dp)) {
384376
//use tensorflow round function to roound to the nearest whole number
385-
let result = round(this.row_data_tensor).arraySync();
377+
let result = tf.round(this.row_data_tensor).arraySync();
386378
return new Series(result, { columns: this.column_names, index: this.index });
387379

388380
} else {

0 commit comments

Comments
 (0)