2017-08-18 3 views
3

ich habe die folgende Tabelleaufzählen Gruppen in einem Datenrahmen

date  ui mw maxw tC HL msurp 
01/03/2004 A 10 10  eC 0.25 0.1 
01/04/2004 A 10 10  eC 0.25 -0.1 
01/03/2004 B 20 20  bC 0.5 0.3 
01/03/2004 B 20 20  bC 0.25 0.3 

, was ich zu tun bin auf der Suche nach ist eine Spalte in dieser Tabelle hinzufügen, die im Grunde die einzigartigen Kombinationen von ui aufzählt, mw, maxw, tC und HL und aufzählt

so zum Beispiel in der obigen Tabelle

einzigartige Kombinationen von ui, mw, maxw, tC und HL

A,10, 10, eC, 0.25 
B,20, 20, bC, 0.5 
B,20, 20, bC, 0.5 
sind

Es gibt insgesamt 3 so die Ausgabe wie

etwas sein sollte
date  ui mw maxw tC HL msurp counter 
01/03/2004 A 10 10  eC 0.25 0.1 1 
01/04/2004 A 10 10  eC 0.25 -0.1 1 
01/03/2004 B 20 20  bC 0.5 0.3 2 
01/03/2004 B 20 20  bC 0.25 0.3 3 
+7

Ist die Reihenfolge wichtig? Wenn nicht, können Sie ngroup verwenden: 'df.groupby (['ui', 'mw', 'maxw', 'tC', 'HL']). Ngroup()' – ayhan

+0

Sind Sie nicht auch nach Datum aggregieren? Wie willst du 'msurp' zusammenfassen, wenn es mehr als einen Wert gibt? – Alexander

+0

Ich versuche nur, die einzigartigen Kombinationen zu identifizieren, sobald ich diesen "Zähler" habe. Ich kann dann aggregieren, anstatt die Gruppe mit [ui, mw, maxw etc – qfd

Antwort

8

Option 1
pd.Series.factorize

df.assign(
    counter=df[['ui', 'mw', 'maxw', 'tC', 'HL']].apply(tuple, 1).factorize()[0] + 1) 

     date ui mw maxw tC HL msurp counter 
0 01/03/2004 A 10 10 eC 0.25 0.1  1 
1 01/04/2004 A 10 10 eC 0.25 -0.1  1 
2 01/03/2004 B 20 20 bC 0.50 0.3  2 
3 01/03/2004 B 20 20 bC 0.25 0.3  3 

Option 1.5
Mehr widerwärtig Version von Option 1 sollte aber

df.assign(
    counter=pd.factorize(list(zip(
     *[df[c].values.tolist() for c in ['ui', 'mw', 'maxw', 'tC', 'HL']] 
    )))[0] + 1 
) 

     date ui mw maxw tC HL msurp counter 
0 01/03/2004 A 10 10 eC 0.25 0.1  1 
1 01/04/2004 A 10 10 eC 0.25 -0.1  1 
2 01/03/2004 B 20 20 bC 0.50 0.3  2 
3 01/03/2004 B 20 20 bC 0.25 0.3  3 

schneller

Option 2
@ ayhan Antwort (wird gelöscht werden, wenn er es posts)

df.assign(
    counter=df.groupby(['ui', 'mw', 'maxw', 'tC', 'HL']).ngroup() + 1) 

     date ui mw maxw tC HL msurp counter 
0 01/03/2004 A 10 10 eC 0.25 0.1  1 
1 01/04/2004 A 10 10 eC 0.25 -0.1  1 
2 01/03/2004 B 20 20 bC 0.50 0.3  3 
3 01/03/2004 B 20 20 bC 0.25 0.3  2 

Zeit
Code unten

(lambda r: r.div(r.min(1), 0).assign(best=lambda x: x.idxmin(1)))(results) 

      pir1  pir2  ayhan best 
100  17.260639 1.000000 3.438354 pir2 
300  30.550010 1.000000 2.598456 pir2 
1000 43.201163 1.000000 1.236190 pir2 
3000 61.593932 1.000000 1.025420 pir2 
10000 127.003138 2.177171 1.000000 ayhan 

enter image description here

pir1 = lambda d: d.assign(counter=d[['ui', 'mw', 'maxw', 'tC', 'HL']].apply(tuple, 1).factorize()[0] + 1) 
pir2 = lambda d: d.assign(counter=pd.factorize(list(zip(*[d[c].values.tolist() for c in ['ui', 'mw', 'maxw', 'tC', 'HL']])))[0] + 1) 
ayhan = lambda d: d.assign(counter=d.groupby(['ui', 'mw', 'maxw', 'tC', 'HL']).ngroup() + 1) 

results = pd.DataFrame(
    index=[100, 300, 1000, 3000, 10000], 
    columns='pir1 pir2 ayhan'.split(), 
    dtype=float 
) 

for i in results.index: 
    d = pd.concat([df] * i, ignore_index=True) 
    for j in results.columns: 
     stmt = '{}(d)'.format(j) 
     setp = 'from __main__ import d, {}'.format(j) 
     results.set_value(i, j, timeit(stmt, setp, number=10)) 

results.plot(loglog=True) 
2

Wie ayhan Antwort, übernehmen, um

df[['ui','mw','maxw','tC','HL']].T.apply(lambda x : ','.join(x.astype(str))).astype('category').cat.codes 


Out[1247]: 
0 0 
1 0 
2 2 
3 1 
dtype: int8 

nicht wichtig ist, wie Sie sagte ich kann dann Aggregat durch diese statt eines festen Gruppe von [ui, mw, maxw etc

tun nur das, und groupby('counter')

df['counter']=df[['ui','mw','maxw','tC','HL']].T.apply(lambda x : ','.join(x.astype(str))) 
Verwandte Themen