Skip to content

Commit

Permalink
'sort' and 'sortByColumns' to reorder DataFrames #5
Browse files Browse the repository at this point in the history
* allowing to specify sort direction
  • Loading branch information
andrus committed Mar 28, 2019
1 parent d69e58a commit 7c76565
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 20 deletions.
18 changes: 14 additions & 4 deletions dflib/src/main/java/com/nhl/dflib/ColumnDataFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,23 @@ public <V extends Comparable<? super V>> DataFrame sort(RowToValueMapper<V> sort
}

@Override
public <V extends Comparable<? super V>> DataFrame sortByColumns(String... columns) {
return sort(Sorters.sorter(getColumns(), columns));
public DataFrame sortByColumns(String[] columns, boolean[] ascending) {
return sort(Sorters.sorter(columnsIndex, columns, ascending));
}

@Override
public <V extends Comparable<? super V>> DataFrame sortByColumns(int... columns) {
return sort(Sorters.sorter(getColumns(), columns));
public DataFrame sortByColumns(int[] columns, boolean[] ascending) {
return sort(Sorters.sorter(columnsIndex, columns, ascending));
}

@Override
public DataFrame sortByColumn(int column, boolean ascending) {
return sort(Sorters.sorter(columnsIndex, column, ascending));
}

@Override
public DataFrame sortByColumn(String column, boolean ascending) {
return sort(Sorters.sorter(columnsIndex, column, ascending));
}

private DataFrame sort(Comparator<RowProxy> comparator) {
Expand Down
8 changes: 6 additions & 2 deletions dflib/src/main/java/com/nhl/dflib/DataFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,13 @@ default <V> DataFrame filterByColumn(String columnName, ValuePredicate<V> p) {

<V extends Comparable<? super V>> DataFrame sort(RowToValueMapper<V> sortKeyExtractor);

DataFrame sortByColumns(String... columns);
DataFrame sortByColumn(String column, boolean ascending);

DataFrame sortByColumns(int... columns);
DataFrame sortByColumn(int column, boolean ascending);

DataFrame sortByColumns(String[] columns, boolean[] ascending);

DataFrame sortByColumns(int[] columns, boolean[] ascending);

/**
* Horizontally concatenates a DataFrame with another DataFrame, producing a "wider" DataFrame. If the heights of
Expand Down
8 changes: 4 additions & 4 deletions dflib/src/main/java/com/nhl/dflib/GroupBy.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,29 @@ public <V extends Comparable<? super V>> GroupBy sort(RowToValueMapper<V> sortKe
return new GroupBy(ungroupedColumns, sorted);
}

public <V extends Comparable<? super V>> GroupBy sortByColumns(String... columns) {
public <V extends Comparable<? super V>> GroupBy sortByColumns(String[] columns, boolean[] ascending) {
if (columns.length == 0) {
return this;
}

Map<Object, DataFrame> sorted = new LinkedHashMap<>((int) (groups.size() / 0.75));

for (Map.Entry<Object, DataFrame> e : groups.entrySet()) {
sorted.put(e.getKey(), e.getValue().sortByColumns(columns));
sorted.put(e.getKey(), e.getValue().sortByColumns(columns, ascending));
}

return new GroupBy(ungroupedColumns, sorted);
}

public <V extends Comparable<? super V>> GroupBy sortByColumns(int... columns) {
public <V extends Comparable<? super V>> GroupBy sortByColumns(int[] columns, boolean[] ascending) {
if (columns.length == 0) {
return this;
}

Map<Object, DataFrame> sorted = new LinkedHashMap<>((int) (groups.size() / 0.75));

for (Map.Entry<Object, DataFrame> e : groups.entrySet()) {
sorted.put(e.getKey(), e.getValue().sortByColumns(columns));
sorted.put(e.getKey(), e.getValue().sortByColumns(columns, ascending));
}

return new GroupBy(ungroupedColumns, sorted);
Expand Down
22 changes: 16 additions & 6 deletions dflib/src/main/java/com/nhl/dflib/sort/Sorters.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,42 @@ static <V extends Comparable<? super V>> Comparator<RowProxy> sorter(RowToValueM
return Comparator.comparing(sortKeyExtractor::map);
}

static Comparator<RowProxy> sorter(Index columns, String... sortColumns) {
static Comparator<RowProxy> sorter(Index columns, String sortColumn, boolean ascending) {
IndexPosition pos = columns.position(sortColumn);
Comparator<RowProxy> ci = Comparator.comparing(o -> (Comparable) o.get(pos.ordinal()));
return ascending ? ci : ci.reversed();
}

static Comparator<RowProxy> sorter(Index columns, int sortColumn, boolean ascending) {
IndexPosition pos = columns.getPositions()[sortColumn];
Comparator<RowProxy> ci = Comparator.comparing(o -> (Comparable) o.get(pos.ordinal()));
return ascending ? ci : ci.reversed();
}

static Comparator<RowProxy> sorter(Index columns, String[] sortColumns, boolean[] ascending) {

if (sortColumns.length == 0) {
throw new IllegalArgumentException("No sort columns");
}

Comparator<RowProxy> c = null;
for (int i = 0; i < sortColumns.length; i++) {
IndexPosition pos = columns.position(sortColumns[i]);
Comparator<RowProxy> ci = Comparator.comparing(o -> (Comparable) o.get(pos.ordinal()));
Comparator<RowProxy> ci = sorter(columns, sortColumns[i], ascending[i]);
c = c == null ? ci : c.thenComparing(ci);
}

return c;
}

static Comparator<RowProxy> sorter(Index columns, int... sortColumns) {
static Comparator<RowProxy> sorter(Index columns, int[] sortColumns, boolean[] ascending) {

if (sortColumns.length == 0) {
throw new IllegalArgumentException("No sort columns");
}

Comparator<RowProxy> c = null;
for (int i = 0; i < sortColumns.length; i++) {
IndexPosition pos = columns.getPositions()[sortColumns[i]];
Comparator<RowProxy> ci = Comparator.comparing(o -> (Comparable) o.get(pos.ordinal()));
Comparator<RowProxy> ci = sorter(columns, sortColumns[i], ascending[i]);
c = c == null ? ci : c.thenComparing(ci);
}

Expand Down
35 changes: 31 additions & 4 deletions dflib/src/test/java/com/nhl/dflib/DataFrame_Sort_Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testSortByColumns_Names() {
2, 2,
0, 2);

DataFrame dfab = dfi.sortByColumns("a", "b");
DataFrame dfab = dfi.sortByColumns(new String[]{"a", "b"}, new boolean[]{true, true});
assertNotSame(dfi, dfab);

new DFAsserts(dfab, "a", "b")
Expand All @@ -48,7 +48,7 @@ public void testSortByColumns_Names() {
.expectRow(1, 0, 4)
.expectRow(2, 2, 2);

DataFrame dfba = dfi.sortByColumns("b", "a");
DataFrame dfba = dfi.sortByColumns(new String[]{"b", "a"}, new boolean[]{true, true});
assertNotSame(dfi, dfba);

new DFAsserts(dfba, "a", "b")
Expand All @@ -67,7 +67,7 @@ public void testSortByColumns_Positions() {
2, 2,
0, 2);

DataFrame dfab = dfi.sortByColumns(0, 1);
DataFrame dfab = dfi.sortByColumns(new int[]{0, 1}, new boolean[]{true, true});
assertNotSame(dfi, dfab);

new DFAsserts(dfab, "a", "b")
Expand All @@ -76,7 +76,7 @@ public void testSortByColumns_Positions() {
.expectRow(1, 0, 4)
.expectRow(2, 2, 2);

DataFrame dfba = dfi.sortByColumns(1, 0);
DataFrame dfba = dfi.sortByColumns(new int[]{1, 0}, new boolean[]{true, true});
assertNotSame(dfi, dfba);

new DFAsserts(dfba, "a", "b")
Expand All @@ -86,4 +86,31 @@ public void testSortByColumns_Positions() {
.expectRow(2, 0, 4);

}

@Test
public void testSortByColumn_Position_Direction() {
Index i = Index.withNames("a", "b");
DataFrame dfi = createDf(i,
0, 3,
2, 4,
0, 2);

DataFrame dfab = dfi.sortByColumn(1, false);
assertNotSame(dfi, dfab);

new DFAsserts(dfab, "a", "b")
.expectHeight(3)
.expectRow(0, 2, 4)
.expectRow(1, 0, 3)
.expectRow(2, 0, 2);

DataFrame dfba = dfi.sortByColumn(1, true);
assertNotSame(dfi, dfba);

new DFAsserts(dfba, "a", "b")
.expectHeight(3)
.expectRow(0, 0, 2)
.expectRow(1, 0, 3)
.expectRow(2, 2, 4);
}
}

0 comments on commit 7c76565

Please sign in to comment.