xy-scale 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/scale.js +13 -32
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xy-scale",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "main": "./index.js",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/scale.js CHANGED
@@ -1,16 +1,12 @@
1
-
2
-
3
1
  export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
4
2
 
5
- if(forceScaling !== null && forceScaling !== 'normalization' && forceScaling !== 'standardization')
6
- {
7
- throw Error('forceScalling should be null, "normalization" or "standardization"')
3
+ if (forceScaling !== null && forceScaling !== 'normalization' && forceScaling !== 'standardization') {
4
+ throw Error('forceScaling should be null, "normalization" or "standardization"');
8
5
  }
9
6
 
10
7
  const n = arrObj.length;
11
8
 
12
9
  if (n === 0) {
13
- // If the input array is empty, return empty outputs
14
10
  return {
15
11
  scaledOutput: [],
16
12
  scaledConfig: {},
@@ -18,36 +14,22 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
18
14
  };
19
15
  }
20
16
 
21
- // Get the feature names (keys) from the first object
22
17
  const keyNames = Object.keys(arrObj[0]);
23
18
 
24
- // **Loop 1: Compute weights for each keyName**
25
19
  const keyNameWeights = keyNames.map(key => {
26
- if (weights.hasOwnProperty(key)) {
27
- const weight = weights[key];
28
- if (weight <= 0) {
29
- throw new Error(`Weight for key "${key}" must be positive.`);
30
- }
31
- return weight;
32
- } else {
33
- return 1; // Default weight
34
- }
20
+ return weights.hasOwnProperty(key) ? Math.max(weights[key], 1) : 1;
35
21
  });
36
22
 
37
23
  const totalColumns = keyNameWeights.reduce((sum, weight) => sum + weight, 0);
38
24
 
39
- // **Loop 2: Build the new keyNames array with weights applied**
40
25
  const outputKeyNames = new Array(totalColumns);
41
26
  let idx = 0;
42
27
  for (let i = 0; i < keyNames.length; i++) {
43
- const key = keyNames[i];
44
- const weight = keyNameWeights[i];
45
- for (let w = 0; w < weight; w++) {
46
- outputKeyNames[idx++] = key;
28
+ for (let w = 0; w < keyNameWeights[i]; w++) {
29
+ outputKeyNames[idx++] = keyNames[i];
47
30
  }
48
31
  }
49
32
 
50
- // Initialize variables for scaling
51
33
  const inputTypes = {};
52
34
  const min = {};
53
35
  const max = {};
@@ -57,7 +39,6 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
57
39
  const uniqueStringIndexes = {};
58
40
  const counts = {};
59
41
 
60
- // **Loop 3: Initialize variables for each key**
61
42
  for (const key of keyNames) {
62
43
  const firstValue = arrObj[0][key];
63
44
  inputTypes[key] = typeof firstValue;
@@ -73,7 +54,6 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
73
54
  counts[key] = 0;
74
55
  }
75
56
 
76
- // **Loop 4: Single pass to process data**
77
57
  for (const obj of arrObj) {
78
58
  for (const key of keyNames) {
79
59
  let value = obj[key];
@@ -84,11 +64,11 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
84
64
  uniqueIndexes[value] = Object.keys(uniqueIndexes).length;
85
65
  }
86
66
  value = uniqueIndexes[value];
87
- obj[key] = value;
67
+ obj[key] = value;
88
68
  }
89
69
 
90
- if (value < min[key]) min[key] = value;
91
- if (value > max[key]) max[key] = value;
70
+ min[key] = Math.min(min[key], value);
71
+ max[key] = Math.max(max[key], value);
92
72
 
93
73
  counts[key]++;
94
74
  const delta = value - mean[key];
@@ -97,20 +77,19 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
97
77
  }
98
78
  }
99
79
 
100
- // **Loop 5: Finalize standard deviation and decide scaling approach**
101
80
  const std = {};
102
81
  for (const key of keyNames) {
103
82
  std[key] = counts[key] > 1 ? Math.sqrt(M2[key] / (counts[key] - 1)) : 0;
104
83
 
105
- // Apply forceScaling if specified, else use automatic selection
106
84
  if (forceScaling === 'normalization' || forceScaling === 'standardization') {
107
85
  approach[key] = forceScaling;
86
+ } else if (min[key] === 0 && max[key] === 1) {
87
+ approach[key] = 'none'; // No scaling required
108
88
  } else {
109
89
  approach[key] = std[key] < 1 ? 'normalization' : 'standardization';
110
90
  }
111
91
  }
112
92
 
113
- // **Loop 6: Create scaled and reweighted output**
114
93
  const scaledOutput = new Array(n);
115
94
  for (let i = 0; i < n; i++) {
116
95
  const obj = arrObj[i];
@@ -125,7 +104,9 @@ export const scaleArrayObj = ({arrObj, weights = {}, forceScaling = null}) => {
125
104
  const stdValue = std[key];
126
105
 
127
106
  let scaledValue;
128
- if (approach[key] === 'normalization') {
107
+ if (approach[key] === 'none') {
108
+ scaledValue = value; // No scaling
109
+ } else if (approach[key] === 'normalization') {
129
110
  scaledValue = maxValue !== minValue ? (value - minValue) / (maxValue - minValue) : 0;
130
111
  } else {
131
112
  scaledValue = stdValue !== 0 ? (value - meanValue) / stdValue : 0;