2016-05-12 10 views
0

Ich habe einen Datenrahmen wie diese, die den Wert bestimmter Gegenstände (ids) über die Zeit verfolgt:Python: Maximal von einer anderen Spalte ausgeführt?

mytime=np.tile(np.arange(0,10) , 2) 
myids=np.repeat([123,456], [10,10]) 
myvalues=np.random.random_integers(20,30,10*2) 

df=pd.DataFrame() 
df['myids']=myids 
df['mytime']=mytime 
df['myvalues']=myvalues 



+-------+--------+----------+--+--+ 
| myids | mytime | myvalues | | | 
+-------+--------+----------+--+--+ 
| 123 | 0  | 29  | | | 
+-------+--------+----------+--+--+ 
| 123 | 1  | 23  | | | 
+-------+--------+----------+--+--+ 
| 123 | 2  | 26  | | | 
+-------+--------+----------+--+--+ 
| 123 | 3  | 24  | | | 
+-------+--------+----------+--+--+ 
| 123 | 4  | 25  | | | 
+-------+--------+----------+--+--+ 
| 123 | 5  | 29  | | | 
+-------+--------+----------+--+--+ 
| 123 | 6  | 28  | | | 
+-------+--------+----------+--+--+ 
| 123 | 7  | 21  | | | 
+-------+--------+----------+--+--+ 
| 123 | 8  | 20  | | | 
+-------+--------+----------+--+--+ 
| 123 | 9  | 26  | | | 
+-------+--------+----------+--+--+ 
| 456 | 0  | 26  | | | 
+-------+--------+----------+--+--+ 
| 456 | 1  | 24  | | | 
+-------+--------+----------+--+--+ 
| 456 | 2  | 20  | | | 
+-------+--------+----------+--+--+ 
| 456 | 3  | 26  | | | 
+-------+--------+----------+--+--+ 
| 456 | 4  | 29  | | | 
+-------+--------+----------+--+--+ 
| 456 | 5  | 29  | | | 
+-------+--------+----------+--+--+ 
| 456 | 6  | 24  | | | 
+-------+--------+----------+--+--+ 
| 456 | 7  | 21  | | | 
+-------+--------+----------+--+--+ 
| 456 | 8  | 27  | | | 
+-------+--------+----------+--+--+ 
| 456 | 9  | 29  | | | 
+-------+--------+----------+--+--+ 

ich bräuchten den Lauf Maximum für jede ID zu berechnen.

np.maximum.accumulate() 

würde die Lauf maximal unabhängig von id berechnen, während ich eine ähnliche Berechnung benötigen, die jedesmal, wenn die ID ändert jedoch zurückgesetzt. Ich kann mir ein einfaches Skript vorstellen, um es in numba zu tun (ich habe sehr große Arrays und nicht-vektorisierter Non-Numba-Code wäre langsam), aber gibt es einen einfacheren Weg, es zu tun?

Mit nur zwei Werten, die ich laufen kann:

df['running max']= np.hstack(( np.maximum.accumulate(df[ df['myids']==123 ]['myvalues']) , np.maximum.accumulate(df[ df['myids']==456 ]['myvalues'])) ) 

aber dies ist nicht möglich mit viel, viel Wert.

Danke!

+0

[Pandas groupby] (http://pandas.pydata.org/pandas-docs/stable/groupby.html) - Sie schreiben Sie Ihre eigenen und akzeptieren antwort ... – gboffi

+0

ich gruppiere von myids, was genau? Ich bin sicher, dass es nur ich dick zu sein, aber ich komme aus einem SQL-Hintergrund und ich kämpfe wirklich meinen Kopf um Pandas zu bekommen (auch die grausamsten Dokumentation nicht hilft) ... –

+0

'df.groupby (‚myid‘) [ 'MyValues']. cummax() 'ist ziemlich nah dran, aber ich weiß nicht, wie weiter verfahren ist ...' .cummax() '' nimmt eine Achse = 'Argument aber, als Pandas Ignorant. Ich weiß nicht, wie man es benutzt (jedenfalls ist es nicht genau eine numpy 'Achse =') – gboffi

Antwort

2

Hier gehen Sie. Annahme ist meine Zeit ist sortiert.

mytime=np.tile(np.arange(0,10) , 2) 
myids=np.repeat([123,456], [10,10]) 
myvalues=np.random.random_integers(20,30,10*2) 

df=pd.DataFrame() 
df['myids']=myids 
df['mytime']=mytime 
df['myvalues']=myvalues 

groups = df.groupby('myids') 
df['run_max_group'] = groups['myvalues'].transform(np.maximum.accumulate) 

Ausgang ...

myids mytime myvalues run_max_group 
0  123  0  27    27 
1  123  1  21    27 
2  123  2  24    27 
3  123  3  25    27 
4  123  4  22    27 
5  123  5  20    27 
6  123  6  20    27 
7  123  7  30    30 
8  123  8  24    30 
9  123  9  22    30 
10 456  0  29    29 
11 456  1  23    29 
12 456  2  30    30 
13 456  3  28    30 
14 456  4  26    30 
15 456  5  25    30 
16 456  6  28    30 
17 456  7  27    30 
18 456  8  20    30 
19 456  9  24    30 
+0

Ist transform() irgendwo dokumentiert? Dieser Link: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.GroupBy.transform.html?highlight=transform#pandas.core.groupby.GroupBy.transform zeigt buchstäblich nichts. Dieser andere Link: http://pandas.pydata.org/pandas-docs/stable/groupby.html?highlight=transform#transformation sagt etwas, aber nicht viel –

+1

Ich bin nicht vertraut mit Dokumentation. Ich kann versuchen, es zu erklären ... Wenn Sie wissen, wie die Aggregatfunktion funktioniert, wissen Sie, wie Transformation funktioniert. Es erweitert einfach den resultierenden Wert von Aggregat, um der Größe der Gruppe zu entsprechen. Nehmen wir an, ich habe Gruppe a mit Werten [1, 2, 3] und Gruppe b mit Werten [3, 4, 5]. Wenn ich groups.aggregate (max) mache, bekomme ich a = 3 und b = 5 zurück. groups.transform wird mir a = [3,3,3] und b = [5,5,5] geben. Dies macht das Ändern oder Hinzufügen zu einem vorhandenen DataFrame erheblich einfacher. –

1

Es scheint, dass es in der Tat

nicht allzu schwierig ist
byid = df.groupby('myid') 
rmax = byid['myvalues].cummax() 
for k, indices in byid.indices.items(): 
    print 'myid = %s' % k 
    print 'running max = %s' % rmax[indices] 

Ich habe (fast) keine früheren Pandas, aber ipython als Sondierungs Instrument ich eine Lösung finden konnte. Ich empfehle die Verwendung von ipython, um große und komplexe Bibliotheken zu erkunden.

p.s. re meinem vorherigen Kommentar: keine Notwendigkeit für axis=

Verwandte Themen