Mehrspaltige Datentransformation

8

Ich erhalte Daten von einer Datenquelle, die ich drehen muss, bevor ich die Informationen zur Anzeige an die Benutzeroberfläche senden kann. I am new to concept of pivoting & I am not sure how to go about it.

Das Problem besteht aus zwei Teilen:

  1. bildet den Header
  2. Schwenken der Daten zur Übereinstimmung mit der Kopfzeile

Zu beachtende Punkte:

  1. Ich habe bestimmte Spalten, die ich nicht pivotieren möchte. Ich nenne sie static columns.

  2. Ich muss bestimmte Spalten drehen, um mehrstufige Header-Informationen zu bilden. Ich nenne sie dynamic columns

  3. Einige Spalten müssen gedreht werden, die tatsächliche Werte enthalten. Ich nannte sie value columns .

  4. Es gibt NO limit für die Anzahl von dynamic, static and value columns , die Sie haben können.

  5. Es wird angenommen, dass wenn Daten kommen, wir zuerst Daten für statische Spalten und dann dynamische Spalten & amp; dann für Wertspalten.

    Weitere Informationen finden Sie im angehängten Bild.

Dummy-Daten:

%Vor%     
OpenStack 16.05.2017, 02:50
quelle

5 Antworten

7

Was Sie static columns nennen, heißt normalerweise Zeilengruppen , dynamic columns - Spaltengruppen und value columns - Wertaggregate oder einfache Werte .

Um das Ziel zu erreichen, würde ich die folgende einfache Datenstruktur vorschlagen:

%Vor%

Das Columns Mitglied von PivotData repräsentiert das, was Sie header nennen, während das Row Mitglied - eine Liste von PivotDataRow Objekten mit Data Mitglied das enthält row group Werte und Values - die Werte für den entsprechenden Columns Index ( PivotDataRow.Values hat immer den gleichen Count wie PivotData.Columns.Count ).

Die obige Datenstruktur ist zu JSON serialisierbar / deserialisierbar (getestet mit Newtosoft.Json) und kann verwendet werden, um die Benutzeroberfläche mit dem gewünschten Format zu füllen.

Die Kerndatenstruktur, die für die Darstellung von Zeilengruppenwerten, Spaltengruppenwerten und Aggregatwerten verwendet wird, lautet wie folgt:

%Vor%

Grundsätzlich repräsentiert es einen Bereich (Slice) einer string -Liste mit Gleichheits- und Ordnungsvergleichssemantik. Ersteres ermöglicht die Verwendung der effizienten Hash-basierten LINQ-Operatoren während der Pivot-Transformation, während das spätere optionale Sortieren ermöglicht. Auch diese Datenstruktur ermöglicht eine effiziente Transformation, ohne neue Listen zuzuweisen und gleichzeitig die tatsächlichen Listen zu halten, wenn sie aus JSON deserialisiert werden.

(Der Gleichheitsvergleich wird durch die Implementierung der Methoden IEquatable<PivotValues> interface - GetHashCode und Equals bereitgestellt. Dadurch können zwei PivotValues -Klasseninstanzen auf der Grundlage der Werte im angegebenen Bereich als gleich behandelt werden die Elemente List<string> der Eingabe List<List<string>> . Ähnlich wird die Reihenfolge bereitgestellt, indem die Methode IComparable<PivotValues> interface - CompareTo ) implementiert wird)

Die Transformation selbst ist ziemlich einfach:

%Vor%

Zuerst werden die Spalten (Header) mit dem einfachen LINQ Distinct Operator bestimmt. Dann werden die Zeilen durch Gruppieren der Quellenmenge durch die Zeilenspalten bestimmt. Die Werte innerhalb jeder Zeilengruppierung werden durch das äußere Verknüpfen von Columns mit dem Gruppierungsinhalt bestimmt.

Aufgrund unserer Datenstrukturimplementierung ist die LINQ-Transformation ziemlich effizient (sowohl für den Raum als auch für die Zeit). Die Reihenfolge der Spalten und Zeilen ist optional, entfernen Sie sie einfach, wenn Sie sie nicht benötigen.

Beispieltest mit Ihren Dummy-Daten:

%Vor%     
Ivan Stoev 23.05.2017, 11:56
quelle
3

Hier ist der LINQ-Weg, dies zu tun:

%Vor%

Das gibt:

Beachten Sie, dass LINQ bestimmte Feldnamen für die Ausgabespalten benötigt.

Wenn die Anzahl der Spalten nicht bekannt ist, aber Sie ein handliches headerInfo List<List<string>> haben, dann können Sie das tun:

%Vor%

Das gibt:

    
Enigmativity 21.05.2017 01:52
quelle
1

Sie können die NReco PivotData -Bibliothek verwenden, um Pivot-Tabellen mit einer beliebigen Anzahl von Spalten auf folgende Weise zu erstellen (do not Vergessen Sie nicht, das Paket "NReco.PivotData" zu installieren:

%Vor%

Standardmäßig sind Pivot-Tabellenzeilen / -spalten nach Kopfzeilen (A-Z) geordnet. Sie können die Reihenfolge nach Bedarf ändern .

PivotData OLAP-Bibliothek (PivotData, PivotTable-Klassen) kann in Projekten mit einzelnem Einsatz kostenlos verwendet werden. Für erweiterte Komponenten (wie PivotTableHtmlWriter) ist ein kommerzieller Lizenzschlüssel erforderlich.

    
Vitaliy Fedorchenko 17.05.2017 05:25
quelle
0

Ein bisschen "vereinfachte" Version:

%Vor%
%Vor%

ergibt:

%Vor%

Das obige ist aufgrund der vielen String-Verkettungen bei weitem nicht das effizienteste, so dass es mit einem benutzerdefinierten Vergleicher ungefähr fünfmal schneller sein kann:

%Vor%

und dann:

%Vor%     
Slai 27.05.2017 23:03
quelle
0

Da wir die Größe des Ergebnisses vorbestimmen können, können wir es als mehrdimensionales Array definieren.

Lassen Sie uns einen funktionalen Ansatz verfolgen und das Ergebnis als Akkumulator behandeln, also schreiben wir einfach einen Reducer (für den Linq Aggregate Methode).

Es wird auf einem Wörterbuch basieren, um die Transformation von der horizontalen auf die vertikale Linie abzubilden, und in einem anderen Statuswörterbuch, um seine Zeilen zu erstellen (natürlich benötigen die Wörterbücher einen Standardvergleich).

Dieses setzt voraus, dass Sie eine validierte header_info haben, also - zuerst - musste ich den ersten Eintrag korrigieren eine Vervielfältigung des letzten.

Im Vergleich zu den anderen ist die folgende Lösung sehr effizient (es dauert nur 1 Millisekunde auf meinem Laptop, mehr als 4 Mal schneller als die angenommene Antwort).

%Vor%     
user6996876 28.05.2017 07:38
quelle

Tags und Links