Skip to content

Commit 878e21b

Browse files
authored
Merge pull request #360 from javascriptdata/fix/308
Fixes issue with sort by values
2 parents 133515b + 06a5b51 commit 878e21b

File tree

7 files changed

+215
-87
lines changed

7 files changed

+215
-87
lines changed

src/danfojs-base/core/frame.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,7 +3348,7 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
33483348
* ```
33493349
*/
33503350
iat(row: number, column: number): string | number | boolean | undefined {
3351-
if(typeof row === 'string' || typeof column === 'string') {
3351+
if (typeof row === 'string' || typeof column === 'string') {
33523352
throw new Error('ParamError: row and column index must be an integer. Use .at to get a row or column by label.')
33533353
}
33543354

@@ -3370,7 +3370,7 @@ export default class DataFrame extends NDframe implements DataFrameInterface {
33703370
* ```
33713371
*/
33723372
at(row: string | number, column: string): string | number | boolean | undefined {
3373-
if(typeof column !== 'string') {
3373+
if (typeof column !== 'string') {
33743374
throw new Error('ParamError: column index must be a string. Use .iat to get a row or column by index.')
33753375
}
33763376
return (this.values as ArrayType2D)[this.index.indexOf(row)][this.columns.indexOf(column)]

src/danfojs-base/core/series.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,10 @@ export default class Series extends NDframe implements SeriesInterface {
674674
* //output [ 1.23, 2.4, 3.12, 4.12, 5.12 ]
675675
* ```
676676
*/
677+
round(dp?: number, options?: { inplace?: boolean }): Series
677678
round(dp = 1, options?: { inplace?: boolean }): Series | void {
678679
const { inplace } = { inplace: false, ...options }
679-
680+
if (dp === undefined) dp = 1;
680681
const newValues = utils.round(this.values as number[], dp, true);
681682

682683
if (inplace) {
@@ -816,24 +817,26 @@ export default class Series extends NDframe implements SeriesInterface {
816817
const { ascending, inplace, } = { ascending: true, inplace: false, ...options }
817818

818819
let sortedValues = [];
820+
let sortedIndex = []
819821
const rangeIdx = utils.range(0, this.index.length - 1);
820822
let sortedIdx = utils.sortArrayByIndex(rangeIdx, this.values, this.dtypes[0]);
821823

822824
for (let indx of sortedIdx) {
823825
sortedValues.push(this.values[indx])
826+
sortedIndex.push(this.index[indx])
824827
}
825828

826829
if (ascending) {
827830
sortedValues = sortedValues.reverse();
828-
sortedIdx = sortedIdx.reverse();
831+
sortedIndex = sortedIndex.reverse();
829832
}
830833

831834
if (inplace) {
832835
this.$setValues(sortedValues as ArrayType1D)
833-
this.$setIndex(sortedIdx);
836+
this.$setIndex(sortedIndex);
834837
} else {
835838
const sf = new Series(sortedValues, {
836-
index: sortedIdx,
839+
index: sortedIndex,
837840
dtypes: this.dtypes,
838841
config: this.config
839842
});
@@ -1828,6 +1831,11 @@ export default class Series extends NDframe implements SeriesInterface {
18281831
* //output [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
18291832
* ```
18301833
*/
1834+
append(
1835+
newValue: string | number | boolean | Series | ArrayType1D,
1836+
index: Array<number | string> | number | string,
1837+
options?: { inplace?: boolean }
1838+
): Series
18311839
append(
18321840
newValue: string | number | boolean | Series | ArrayType1D,
18331841
index: Array<number | string> | number | string,
@@ -2254,7 +2262,7 @@ export default class Series extends NDframe implements SeriesInterface {
22542262
* ```
22552263
*/
22562264
iat(row: number): number | string | boolean | undefined {
2257-
if(typeof row === 'string') {
2265+
if (typeof row === 'string') {
22582266
throw new Error('ParamError: row index must be an integer. Use .at to get a row by label.')
22592267
}
22602268
return (this.values as ArrayType1D)[row];
@@ -2274,7 +2282,7 @@ export default class Series extends NDframe implements SeriesInterface {
22742282
* ```
22752283
*/
22762284
at(row: string): number | string | boolean | undefined {
2277-
if(typeof row !== 'string') {
2285+
if (typeof row !== 'string') {
22782286
throw new Error('ParamError: row index must be a string. Use .iat to get a row by index.')
22792287
}
22802288
return (this.values as ArrayType1D)[this.index.indexOf(row)];

src/danfojs-base/shared/utils.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -774,27 +774,48 @@ export default class Utils {
774774
arr: Array<{ index: number | string, value: number | string | boolean }>,
775775
ascending: boolean
776776
) {
777-
return arr.sort((obj1, obj2) => {
778-
const a = obj2.value;
779-
const b = obj1.value;
777+
let sortedValues = arr.sort((obj1, obj2) => {
778+
let a = obj2.value;
779+
let b = obj1.value;
780780

781781
if (!ascending) {
782782
if (typeof a === "string" && typeof b === "string") {
783-
return a.charCodeAt(0) - b.charCodeAt(0);
784-
} else if ((typeof a === "number" && typeof b === "number") || (typeof a === "boolean" && typeof b === "boolean")) {
785-
return Number(a) - Number(b);
783+
a = a.toUpperCase();
784+
b = b.toUpperCase();
785+
786+
if (a < b) {
787+
return -1;
788+
}
789+
790+
if (a > b) {
791+
return 1;
792+
}
793+
794+
return 0;
795+
786796
} else {
787-
throw Error('ParamError: column values must be either numbers or strings');
797+
return Number(a) - Number(b);
788798
}
789799
} else {
790800
if (typeof a === "string" && typeof b === "string") {
791-
return b.charCodeAt(0) - a.charCodeAt(0);
792-
} else if ((typeof a === "number" && typeof b === "number") || (typeof a === "boolean" && typeof b === "boolean")) {
793-
return Number(b) - Number(a);
801+
a = a.toUpperCase();
802+
b = b.toUpperCase();
803+
804+
if (a > b) {
805+
return -1;
806+
}
807+
808+
if (a < b) {
809+
return 1;
810+
}
811+
812+
return 0;
794813
} else {
795-
throw Error('ParamError: column values must be either numbers or strings');
814+
return Number(b) - Number(a);;
796815
}
797816
}
798817
});
818+
819+
return sortedValues;
799820
}
800821
}

src/danfojs-browser/tests/core/frame.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,17 @@ describe("DataFrame", function () {
13191319
[ 6, 9 ] ];
13201320
assert.deepEqual(df.sortValues("A", { "ascending": true }).values, expected);
13211321
});
1322+
1323+
it("sort index in descending order and retains index", function () {
1324+
let data = [ [ 0, 2, 4, "b" ],
1325+
[ 360, 180, 360, "a" ],
1326+
[ 2, 4, 6, "c" ] ];
1327+
1328+
let df = new dfd.DataFrame(data, { "columns": [ "col1", "col2", "col3", "col4" ], index: [ "b", "a", "c" ] });
1329+
let df2 = df.sortIndex({ ascending: false });
1330+
let rslt = [ "c", "b", "a" ];
1331+
assert.deepEqual(df2.index, rslt);
1332+
});
13221333
});
13231334

13241335
describe("copy", function () {

src/danfojs-browser/tests/core/series.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,45 @@ describe("Series Functions", () => {
688688
const sortedSf = sf.sortValues({ ascending: false });
689689
assert.deepEqual(sortedSf.values, result);
690690
});
691+
692+
it("Index is retained after sort (ascending=true)", function () {
693+
let index = [ "apple", "banana", "orange", "grape" ];
694+
let value = [ 3, 6, 2, 9 ];
695+
696+
let sf = new dfd.Series(value, { index });
697+
sf.sortValues().print();
698+
const expectedValues = [ 2, 3, 6, 9 ];
699+
const expectedIndex = [ "orange", "apple", "banana", "grape" ];
700+
const sortedSf = sf.sortValues();
701+
assert.deepEqual(sortedSf.values, expectedValues);
702+
assert.deepEqual(sortedSf.index, expectedIndex);
703+
});
704+
it("Index is retained after sort (ascending=false)", function () {
705+
let index = [ "apple", "banana", "orange", "grape" ];
706+
let value = [ 3, 6, 2, 9 ];
707+
708+
let sf = new dfd.Series(value, { index });
709+
sf.sortValues().print();
710+
const expectedValues = [ 9, 6, 3, 2 ];
711+
const expectedIndex = [ "grape", "banana", "apple", "orange" ];
712+
const sortedSf = sf.sortValues({ ascending: false });
713+
assert.deepEqual(sortedSf.values, expectedValues);
714+
assert.deepEqual(sortedSf.index, expectedIndex);
715+
});
716+
717+
it("Index is retained after inplace sort (ascending=false)", function () {
718+
let index = [ "apple", "banana", "orange", "grape" ];
719+
let value = [ 3, 6, 2, 9 ];
720+
721+
let sf = new dfd.Series(value, { index });
722+
sf.sortValues().print();
723+
const expectedValues = [ 9, 6, 3, 2 ];
724+
const expectedIndex = [ "grape", "banana", "apple", "orange" ];
725+
sf.sortValues({ ascending: false, inplace: true });
726+
assert.deepEqual(sf.values, expectedValues);
727+
assert.deepEqual(sf.index, expectedIndex);
728+
});
729+
691730
});
692731

693732
describe("describe", function () {

src/danfojs-node/test/core/frame.test.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ describe("DataFrame", function () {
12661266
[2, 4, 6, "c"]];
12671267

12681268
const df = new DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"] });
1269-
const df_sort = df.sortValues("col3") as DataFrame
1269+
const df_sort = df.sortValues("col3")
12701270
const expected = [[360, 180, 1, "b"], [0, 2, 4, "a"], [2, 4, 6, "c"]];
12711271
assert.deepEqual(df_sort.values, expected);
12721272
assert.deepEqual(df_sort.index, [1, 0, 2]);
@@ -1297,9 +1297,21 @@ describe("DataFrame", function () {
12971297
[2, 4, 6, "c"]];
12981298

12991299
const df = new DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"] });
1300-
const expected = [[2, 4, 6, 'c'], [360, 180, 1, 'b'], [0, 2, 4, 'a']];
1301-
assert.deepEqual((df.sortValues("col4", { "ascending": false }) as DataFrame).values, expected);
1300+
const expected = [[2, 4, 6, "c"], [360, 180, 1, "b"], [0, 2, 4, "a"]]
1301+
assert.deepEqual(df.sortValues("col4", { "ascending": false }).values, expected);
13021302
});
1303+
1304+
it("sort works for Date string", function () {
1305+
const data = {
1306+
date: ['1974-02-19', '1955-12-06', '1963-11-18']
1307+
};
1308+
const df = new DataFrame(data);
1309+
const expected1 = [['1974-02-19'], ['1963-11-18'], ['1955-12-06']]
1310+
const expected2 = [['1955-12-06'], ['1963-11-18'], ['1974-02-19']]
1311+
assert.deepEqual(df.sortValues("date", { "ascending": false }).values, expected1);
1312+
assert.deepEqual(df.sortValues("date", { "ascending": true }).values, expected2);
1313+
});
1314+
13031315
it("Sort duplicate DataFrame with duplicate columns", function () {
13041316

13051317
const data = {
@@ -1320,7 +1332,7 @@ describe("DataFrame", function () {
13201332
[5, 8],
13211333
[5, 2],
13221334
[6, 9]];
1323-
assert.deepEqual((df.sortValues("A", { "ascending": true }) as DataFrame).values, expected);
1335+
assert.deepEqual(df.sortValues("A", { "ascending": true }).values, expected);
13241336
});
13251337
it("sort index in descending order and retains index", function () {
13261338
let data = [[0, 2, 4, "b"],
@@ -1330,9 +1342,9 @@ describe("DataFrame", function () {
13301342
let df = new DataFrame(data, { "columns": ["col1", "col2", "col3", "col4"], index: ["b", "a", "c"] });
13311343
let df2 = df.sortIndex({ ascending: false });
13321344
let rslt = ["c", "b", "a"];
1333-
13341345
assert.deepEqual(df2.index, rslt);
13351346
});
1347+
13361348
});
13371349

13381350
describe("copy", function () {

0 commit comments

Comments
 (0)