2017-02-27 8 views
3

Ich versuche einen Pandas Datenrahmen mit drei Spalten (Datum, Start, Ende) in eine Frequenzmatrix zu transformieren. Meine Eingangsdatenrahmen wie folgt aussehen:Pandas Datenframe in Frequenzmatrix transformieren

Date,    Start, End 
2016-09-02 09:16:00 18  16 
2016-09-02 16:14:10 16  1 
2016-09-02 06:17:21 18  17 
2016-09-02 05:51:07 23  17 
2016-09-02 18:34:44 18  17 
2016-09-02 05:44:44 20  4 
2016-09-02 09:25:22 18  17 
2016-09-02 22:27:44 18  17 
2016-09-02 16:02:46 0  18 
2016-09-02 15:35:07 17  17 
2016-09-02 16:06:42 8  17 
2016-09-02 14:47:04 16  23 
2016-09-02 07:47:24 20  1 
... 

Die Werte von ‚Start‘ und ‚Ende‘ sind ganze Zahlen zwischen 0 und 23 inklusive. Das "Datum" ist eine Datetime. Die Frequenzmatrix, die ich erstellen möchte, ist eine 24 mal 24 csv, wobei Zeile i und Spalte j die Anzahl der Male 'End' = i und 'Start' = j in der Eingabe auftritt. Zum Beispiel würde schaffen die obigen Daten:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 
17, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 1 
18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 

Für zusätzliche Hilfe, dies in einer Art und Weise getan werden könnte, die eine separate Matrix für alle 15 Minuten schafft? Das wären 672 Matrizen, da dieser Datumsbereich eine Woche ist. Ich bin ein autodidaktischer Anfänger, und ich kann wirklich nicht darüber nachdenken, wie man das auf eine pythonische Weise lösen kann, jede Lösung oder jeder Rat würde sehr geschätzt werden.

Antwort

5

Erstellen Sie Ihre Matrix mit einer einfachen Zählung und unstack einen von einer Spalte:

mat = df.groupby(['Start', 'End']).count().unstack(level=0) 

Abgleich der Datums-Ebene:

mat.columns = mat.columns.droplevel(0) 

Jetzt reindex Zeilen und Spalten und warf in ganzen Zahlen:


Detaillierte Erklärungen

Zuerst zählen Sie die Anzahl der Vorkommen eines gegebenen (Start, Ende) Paares. Das Ergebnis von groupby gegen diese beiden Spalten bringt tatsächlich einen Multiindex zurück.

df.groupby(['Start', 'End']).count() 
Out[134]: 
      Date 
Start End  
0  18  1 
8  17  1 
16 1  1 
     23  1 
17 17  1 
18 16  1 
     17  4 
20 1  1 
     4  1 
23 17  1 

Was wir von diesem Ergebnis wollen, ist, den Start-Index in Spalten zu bekommen. Entstapelungsunterdrückung tut dies:

df.groupby(['Start', 'End']).count().unstack(level=0) 
Out[135]: 
     Date        
Start 0 8 16 17 18 20 23 
End          
1  NaN NaN 1.0 NaN NaN 1.0 NaN 
4  NaN NaN NaN NaN NaN 1.0 NaN 
16  NaN NaN NaN NaN 1.0 NaN NaN 
17  NaN 1.0 NaN 1.0 4.0 NaN 1.0 
18  1.0 NaN NaN NaN NaN NaN NaN 
23  NaN NaN 1.0 NaN NaN NaN NaN 

Das Ergebnis Entstapelungsunterdrückung ist die Spalte Start als zusätzliche Spalte Indexebene auf dem aktuellen Datum Spaltenindex bewegt wird (siehe unten). Deshalb lassen wir danach das Level 0 fallen. Eine andere Möglichkeit - abhängig von Ihrem aktuellen Quellcode - könnte sein, die Datumsspalte im Voraus herauszufiltern, dann würde das Entstapeln eine Ebene bringen.

_.columns 
Out[136]: 
MultiIndex(levels=[['Date'], [0, 8, 16, 17, 18, 20, 23]], 
      labels=[[0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6]], 
      names=[None, 'Start']) 
+0

Schöne Lösung mit 'Reindex'! – pansen

+0

Danke! Es funktioniert, aber ich bin ein wenig verloren, wie. Kannst du erklären, was das Entstapeln ist? –

+1

Unstack versetzt die Tabelle und macht die Spalte zu einer Zeile. – postoronnim

Verwandte Themen