First pass at removing danfo as a dependency · javascriptdata/scikit.js@2a24a52 · GitHub
Skip to content

Commit 2a24a52

Browse files
committed
First pass at removing danfo as a dependency
1 parent 6807edc commit 2a24a52

29 files changed

Lines changed: 1415 additions & 149 deletions

‎package-lock.json‎

Lines changed: 949 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 5 additions & 2 deletions

‎rollup.config.js‎

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,25 +94,9 @@ function getPlugins({ minify = false }) {
9494
}
9595

9696
export default [
97-
//web
9897
{
99-
// input: "dist/umd/index.js",
10098
input: 'src/index.ts',
101-
output: getOutput({
102-
minify: false
103-
}),
104-
plugins: getPlugins({
105-
minify: false
106-
})
107-
},
108-
//web minified
109-
{
110-
input: 'src/index.ts',
111-
output: getOutput({
112-
minify: true
113-
}),
114-
plugins: getPlugins({
115-
minify: true
116-
})
99+
output: getOutput(),
100+
plugins: getPlugins()
117101
}
118102
]

‎src/compose/columnTransformer.ts‎

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { concat, Tensor2D } from '@tensorflow/tfjs-core'
2-
import { dfd } from '../shared/globals'
3-
import { Scikit1D, Scikit2D, Transformer } from '../types'
4-
2+
import { DataFrameInterface, Scikit1D, Scikit2D, Transformer } from '../types'
3+
import { isDataFrameInterface, isScikitLike2D } from '../typesUtils'
4+
import { tf } from '../shared/globals'
55
/*
66
Next steps:
77
1. Support 'passthrough' and 'drop' and estimator for remainder (also in transformer list)
@@ -80,56 +80,74 @@ export class ColumnTransformer {
8080
this.remainder = remainder
8181
}
8282

83-
public fit(X: Scikit2D, y?: Scikit1D) {
84-
const newDf = X instanceof dfd.DataFrame ? X : new dfd.DataFrame(X)
85-
83+
public fit(X: Tensor2D | DataFrameInterface, y?: Scikit1D) {
8684
for (let i = 0; i < this.transformers.length; i++) {
8785
let [, curTransform, selection] = this.transformers[i]
8886

89-
let subsetX = this.getColumns(newDf, selection)
87+
let subsetX = this.getColumns(X, selection)
9088
curTransform.fit(subsetX, y)
9189
}
9290
return this
9391
}
9492

95-
public transform(X: Scikit2D, y?: Scikit1D) {
96-
const newDf = X instanceof dfd.DataFrame ? X : new dfd.DataFrame(X)
97-
93+
public transform(X: Tensor2D | DataFrameInterface, y?: Scikit1D) {
9894
let output = []
9995
for (let i = 0; i < this.transformers.length; i++) {
10096
let [, curTransform, selection] = this.transformers[i]
10197

102-
let subsetX = this.getColumns(newDf, selection)
98+
let subsetX = this.getColumns(X, selection)
10399

104100
output.push(curTransform.transform(subsetX, y))
105101
}
106102
return concat(output, 1)
107103
}
108104

109-
public fitTransform(X: Scikit2D, y?: Scikit1D) {
110-
const newDf = X instanceof dfd.DataFrame ? X : new dfd.DataFrame(X)
111-
105+
public fitTransform(X: Tensor2D | DataFrameInterface, y?: Scikit1D) {
112106
let output = []
113107
for (let i = 0; i < this.transformers.length; i++) {
114108
let [, curTransform, selection] = this.transformers[i]
115109

116-
let subsetX = this.getColumns(newDf, selection)
110+
let subsetX = this.getColumns(X, selection)
117111

118112
output.push(curTransform.fitTransform(subsetX, y))
119113
}
120114
return concat(output, 1)
121115
}
122116

123-
getColumns(X: dfd.DataFrame, selectedColumns: Selection): Tensor2D {
124-
if (isStringArray(selectedColumns)) {
125-
return X.loc({ columns: selectedColumns }).tensor as unknown as Tensor2D
126-
}
127-
if (Array.isArray(selectedColumns)) {
128-
return X.iloc({ columns: selectedColumns }).tensor as unknown as Tensor2D
129-
}
130-
if (typeof selectedColumns === 'string') {
131-
return X[selectedColumns].tensor
117+
getColumns(
118+
X: DataFrameInterface | Tensor2D,
119+
selectedColumns: Selection
120+
): Tensor2D {
121+
if (isDataFrameInterface(X)) {
122+
if (isStringArray(selectedColumns)) {
123+
return X.loc({ columns: selectedColumns })
124+
.tensor as unknown as Tensor2D
125+
}
126+
if (Array.isArray(selectedColumns)) {
127+
return X.iloc({ columns: selectedColumns })
128+
.tensor as unknown as Tensor2D
129+
}
130+
if (typeof selectedColumns === 'string') {
131+
return X[selectedColumns].tensor
132+
}
133+
return X.iloc({ columns: [selectedColumns] })
134+
.tensor as unknown as Tensor2D
135+
} else {
136+
if (
137+
isStringArray(selectedColumns) ||
138+
typeof selectedColumns === 'string'
139+
) {
140+
throw new Error(
141+
"Can't pass string selected columns when not a DataFrame"
142+
)
143+
}
144+
if (typeof selectedColumns === 'number') {
145+
let columns = tf.tensor1d([selectedColumns])
146+
return X.gather(columns, 1)
147+
} else {
148+
let columns = tf.tensor1d(selectedColumns)
149+
return X.gather(columns, 1)
150+
}
132151
}
133-
return X.iloc({ columns: [selectedColumns] }).tensor as unknown as Tensor2D
134152
}
135153
}

‎src/datasets/datasets.ts‎

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { dfd } from '../shared/globals'
2-
31
/**
42
* Loads the Boston housing dataset (regression). Samples 506, features 13.
53
* @example
@@ -10,8 +8,8 @@ import { dfd } from '../shared/globals'
108
df.print()
119
```
1210
*/
13-
export async function loadBoston(): Promise<dfd.DataFrame> {
14-
return await dfd.readCSV('http://scikitjs.org/data/boston.csv')
11+
export function loadBoston(): string {
12+
return 'http://scikitjs.org/data/boston.csv'
1513
}
1614

1715
/**
@@ -25,8 +23,8 @@ export async function loadBoston(): Promise<dfd.DataFrame> {
2523
df.print()
2624
```
2725
*/
28-
export async function loadIris(): Promise<dfd.DataFrame> {
29-
return await dfd.readCSV('http://scikitjs.org/data/iris.csv')
26+
export function loadIris(): string {
27+
return 'http://scikitjs.org/data/iris.csv'
3028
}
3129

3230
/**
@@ -41,8 +39,8 @@ export async function loadIris(): Promise<dfd.DataFrame> {
4139
```
4240
*/
4341

44-
export async function loadWine(): Promise<dfd.DataFrame> {
45-
return await dfd.readCSV('http://scikitjs.org/data/wine.csv')
42+
export function loadWine(): string {
43+
return 'http://scikitjs.org/data/wine.csv'
4644
}
4745

4846
/**
@@ -57,8 +55,8 @@ export async function loadWine(): Promise<dfd.DataFrame> {
5755
```
5856
*/
5957

60-
export async function loadDiabetes(): Promise<dfd.DataFrame> {
61-
return await dfd.readCSV('http://scikitjs.org/data/diabetes.csv')
58+
export function loadDiabetes(): string {
59+
return 'http://scikitjs.org/data/diabetes.csv'
6260
}
6361

6462
/**
@@ -73,8 +71,8 @@ export async function loadDiabetes(): Promise<dfd.DataFrame> {
7371
```
7472
*/
7573

76-
export async function loadBreastCancer(): Promise<dfd.DataFrame> {
77-
return await dfd.readCSV('http://scikitjs.org/data/breast_cancer.csv')
74+
export function loadBreastCancer(): string {
75+
return 'http://scikitjs.org/data/breast_cancer.csv'
7876
}
7977

8078
/**
@@ -88,8 +86,8 @@ export async function loadBreastCancer(): Promise<dfd.DataFrame> {
8886
df.print()
8987
```
9088
*/
91-
export async function loadDigits(): Promise<dfd.DataFrame> {
92-
return await dfd.readCSV('http://scikitjs.org/data/digits.csv')
89+
export function loadDigits(): string {
90+
return 'http://scikitjs.org/data/digits.csv'
9391
}
9492

9593
/**
@@ -98,6 +96,6 @@ export async function loadDigits(): Promise<dfd.DataFrame> {
9896
* Samples 20640, Features 8.
9997
*/
10098

101-
export async function fetchCaliforniaHousing(): Promise<dfd.DataFrame> {
102-
return await dfd.readCSV('http://scikitjs.org/data/california_housing.csv')
99+
export function fetchCaliforniaHousing(): string {
100+
return 'http://scikitjs.org/data/california_housing.csv'
103101
}

‎src/model_selection/trainTestSplit.test.ts‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import {
44
getIndices
55
} from './trainTestSplit'
66

7-
import { dfd, tf } from '../shared/globals'
7+
import * as dfd from 'danfojs'
8+
import { tf } from '../shared/globals'
9+
import { DataFrameInterface } from '../types'
810

911
describe('Testing trainTestSplit', function () {
1012
it('Testing train/test validation logic', () => {
@@ -67,7 +69,7 @@ describe('Testing trainTestSplit', function () {
6769
[2, 3]
6870
])
6971

70-
let val3 = getIndices(X, [1, 2, 0]) as dfd.DataFrame
72+
let val3 = getIndices(X as any, [1, 2, 0]) as DataFrameInterface
7173
expect(val3.values).toEqual([
7274
[1, 2],
7375
[2, 3],
@@ -76,7 +78,7 @@ describe('Testing trainTestSplit', function () {
7678

7779
let X1 = new dfd.Series([0, 1, 2])
7880

79-
let val4 = getIndices(X1, [1, 2, 0]) as dfd.DataFrame
81+
let val4 = getIndices(X1 as any, [1, 2, 0]) as DataFrameInterface
8082
expect(val4.values).toEqual([1, 2, 0])
8183

8284
let X2D = tf.tensor2d([
@@ -85,7 +87,7 @@ describe('Testing trainTestSplit', function () {
8587
[3, 4]
8688
])
8789

88-
let val5 = getIndices(X2D, [1, 2, 0]) as dfd.DataFrame
90+
let val5 = getIndices(X2D as any, [1, 2, 0]) as DataFrameInterface
8991
expect(val5.arraySync()).toEqual([
9092
[2, 3],
9193
[3, 4],
@@ -94,7 +96,7 @@ describe('Testing trainTestSplit', function () {
9496

9597
let X1D = tf.tensor1d([1, 2, 3, 4, 5])
9698

97-
let val6 = getIndices(X1D, [1, 2, 0, 3, 4]) as dfd.DataFrame
99+
let val6 = getIndices(X1D as any, [1, 2, 0, 3, 4]) as DataFrameInterface
98100
expect(val6.arraySync()).toEqual([2, 3, 1, 4, 5])
99101
})
100102
it('trainTestSplit indices', () => {

‎src/model_selection/trainTestSplit.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Scikit1D, Scikit2D } from '../types'
2-
import { assert } from '../typesUtils'
2+
import { assert, isDataFrameInterface, isSeriesInterface } from '../typesUtils'
33
import { getLength, sampleWithoutReplacement } from '../utils'
4-
import { dfd, tf } from '../shared/globals'
4+
import { tf } from '../shared/globals'
55
import { Tensor } from '@tensorflow/tfjs-core'
66

77
/**
@@ -115,10 +115,10 @@ export function getIndices(X: Scikit2D | Scikit1D, indices: number[]) {
115115
if (X instanceof Tensor) {
116116
return tf.gather(X, indices)
117117
}
118-
if (X instanceof dfd.DataFrame) {
118+
if (isDataFrameInterface(X)) {
119119
return X.iloc({ rows: indices })
120120
}
121-
if (X instanceof dfd.Series) {
121+
if (isSeriesInterface(X)) {
122122
return X.iloc(indices)
123123
}
124124
return indices.map((i) => X[i])

‎src/neighbors/kNeighborsClassifier.test.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,21 @@ import { crossValScore } from '../model_selection/crossValScore'
2525
import { KFold } from '../model_selection/kFold'
2626
import { arrayEqual } from '../utils'
2727
import '../jestTensorMatchers'
28-
import { dfd, tf } from '../shared/globals'
28+
import * as dfd from 'danfojs'
29+
import { tf } from '../shared/globals'
2930
type Tensor1D = tf.Tensor1D
3031
type Tensor2D = tf.Tensor2D
3132

3233
function testWithDataset(
33-
loadData: () => Promise<dfd.DataFrame>,
34+
loadData: () => string,
3435
params: KNeighborsParams,
3536
referenceAccuracy: number
3637
) {
3738
it(
3839
`matches sklearn fitting ${loadData.name}`.padEnd(48) +
3940
JSON.stringify(params),
4041
async () => {
41-
const df = await loadData()
42+
const df = await dfd.readCSV(loadData())
4243

4344
const Xy = df.tensor as unknown as Tensor2D
4445
let [nSamples, nFeatures] = Xy.shape

‎src/neighbors/kNeighborsRegressor.test.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ import { crossValScore } from '../model_selection/crossValScore'
2121
import { KFold } from '../model_selection/kFold'
2222
import { negMeanSquaredError } from '../model_selection/scorers'
2323
import '../jestTensorMatchers'
24-
import { dfd, tf } from '../shared/globals'
24+
import * as dfd from 'danfojs'
25+
import { tf } from '../shared/globals'
26+
2527
type Tensor1D = tf.Tensor1D
2628
type Tensor2D = tf.Tensor2D
2729

2830
function testWithDataset(
29-
loadData: () => Promise<dfd.DataFrame>,
31+
loadData: () => string,
3032
params: KNeighborsParams,
3133
referenceError: number
3234
) {
3335
it(
3436
`matches sklearn fitting ${loadData.name}`.padEnd(48) +
3537
JSON.stringify(params),
3638
async () => {
37-
const df = await loadData()
39+
const df = await dfd.readCSV(loadData())
3840

3941
const Xy = df.tensor as unknown as Tensor2D
4042
let [nSamples, nFeatures] = Xy.shape

‎src/preprocessing/labelEncoder.test.ts‎

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)