2017-08-03 1 views
1

Ich habe einen DataFrame mit einem zweistufigen MultiIndex. Die erste Ebene date ist ein DatetimeIndex und die zweite Ebene name ist nur einige Zeichenfolgen. Die Daten haben 10-Minuten-Intervalle.Wie kann die Anzahl der Zeilen pro Tag in einem MultiIndex-Datenrahmen gezählt werden?

Wie kann ich nach Datum auf der ersten Ebene dieses MultiIndex gruppieren und die Anzahl der Zeilen pro Tag zählen?

Ich vermute, dass die DatetimeIndex gekoppelt in ein Multiindex gibt mir Probleme, da tun

data.groupby(pd.TimeGrouper(freq='D')).count() 

gibt mir

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'MultiIndex' 

Ich habe auch versucht

data.groupby(data.index.levels[0].date).count() 

schreiben was zu

01 führt
ValueError: Grouper and axis must be same length 

Wie könnte ich zum Beispiel den Grouper länger machen (d. H. Dupliziere Indexwerte, deren Auslassung nun kürzer als die Achse ist)?

Danke!

+0

Können Sie eine Probe Ihres Datenrahmen in der Frage zur Verfügung stellen? –

Antwort

1

Sie können das Schlüsselwort level in Grouper verwenden. (Beachten Sie auch, dass TimeGrouper veraltet ist). Dieser Parameter lautet

das Niveau für den Zielindex.

Beispiel Datenrahmen:

dates = pd.date_range('2017-01', freq='10MIN', periods=1000) 
strs = ['aa'] * 1000 
df = pd.DataFrame(np.random.rand(1000,2), index=pd.MultiIndex.from_arrays((dates, strs))) 

Lösung:

print(df.groupby(pd.Grouper(freq='D', level=0)).count()) 
       0 1 
2017-01-01 144 144 
2017-01-02 144 144 
2017-01-03 144 144 
2017-01-04 144 144 
2017-01-05 144 144 
2017-01-06 144 144 
2017-01-07 136 136 

Update: Sie bemerken in Ihren Kommentaren, die Ihre resultierenden Zählungen haben Nullen Sie möchten fallen zu lassen. Zum Beispiel, sagen Sie Ihre Datenrahmen ein paar Tage wirklich fehlt:

df = df.drop(df.index[140:400]) 
print(df.groupby(pd.Grouper(freq='D', level=0)).count()) 
       0 1 
2017-01-01 140 140 
2017-01-02 0 0 
2017-01-03 32 32 
2017-01-04 144 144 
2017-01-05 144 144 
2017-01-06 144 144 
2017-01-07 136 136 

Meines Wissens gibt es keine Möglichkeit, Null zählt innerhalb .count auszuschließen. Stattdessen können Sie Ihr Ergebnis von oben verwenden, um Nullen zu löschen.

Erste Lösung (kann weniger bevorzugt, weil es konvertiert und int Ergebnis float wenn np.nan eingeführt wird, würde

res = df.groupby(pd.Grouper(freq='D', level=0)).count() 
res = res.replace(0, np.nan).dropna() 

zweite und bessere Lösung sein, meiner Meinung nach, von here:

res = res[(res.T != 0).any()] 
print(res) # notice - excludes 2017-01-02 
       0 1 
2017-01-01 140 140 
2017-01-03 32 32 
2017-01-04 144 144 
2017-01-05 144 144 
2017-01-06 144 144 
2017-01-07 136 136 

.any stammt von NumPy, wird auf Pandas portiert und gibt True zurück, wenn ein Element über der angeforderten Achse True ist.

+0

Danke, Brad, du hast meine Frage perfekt beantwortet. Als Lerngelegenheit habe ich bemerkt, dass ich Zeilen mit null Zählungen bekomme und '.dropna()' an die '.groupby(). Count()' -Anweisung anhängt. Jeder Weg, den "Grouper" fallen zu lassen, zählt sofort in derselben Zeile? – basse

2

die Datenrahmen Unter der Annahme, sieht wie folgt aus

d=pd.DataFrame([['Mon','foo',3],['Tue','bar',6],['Wed','qux',9]], 
       columns=['date','name','amount'])\ 
       .set_index(['date','name']) 

Sie den Namen aus dem Index nur für diesen Gruppierungsoperation entfernen

d.reset_index('name', drop=True)\ 
.groupby('date')\ 
['amount'].count() 
Verwandte Themen