2016-04-07 5 views
0

Ich versuche, eine wachsende Anzahl von Tupel von Strings nach Gruppe zu erstellen.Pandas erweitern Anzahl der Zeichenfolge Auftreten von Gruppe

index category   group 
2000-01-01 ('foo',)    a 
2000-01-02 ('tito', 'puente') a 
2000-01-03 ('bar',)    a 
2000-01-04 ('zip',)    b 
2000-01-05 ('zorp',)   b 
2000-01-03 ('feep',)   c 

würde.

index category   group tuple_count 
2000-01-01 ('foo',)    a  0 
2000-01-02 ('tito', 'puente') a  1 
2000-01-03 ('bar',)    a  2 
2000-01-04 ('zip',)    b  0 
2000-01-05 ('zorp',)   b  0 
2000-01-03 ('feep',)   c  1 

Die Idee ist, dass ich ein expandierendes Fenster, durch Gruppe der Zählungen des Auftretens von Kategorien erstellen möchten, die ich in In diesem Fall interessiert bin, Die interessanten Kategorien sind [('tito', 'puente'), ('bar',), ('feep',)]. Wenn eine neue Kategorie angezeigt wird, möchte ich die Anzahl erhöhen.

Ich bin mit dem folgenden Code und kann nicht herausfinden, warum es nicht

from operator import or_ 

def count_categories(ser): 

    categories_to_count = [('tito', 'puente'), 
          ('bar',), 
          ('feep',)] 

    conditions = [ser == val for val in categories_to_count] 
    mask = reduce(or_, conditions) 
    return mask.sum() 


def expanding_count_categories(s): 
    return s.expanding().apply(count_categories) 

df.groupby('group')['category'].apply(expanding_count_categories) 

Für die tuple_count Spalte arbeitet, bekomme ich nur die Kategorie Spalt zurück:

index    tuple_count 
2000-01-01   ('foo',) 
2000-01-02   ('tito', 'puente') 
2000-01-03   ('bar',) 
2000-01-04   ('zip',) 
2000-01-05   ('zorp',) 
2000-01-03   ('feep',) 

edit:

Problem scheint zu sein, dass nicht-numerische Werte sind zur Zeit not handled by expanding/window

+0

Ich kann die Logik dieses Tuple_count nicht verstehen. Warum sind die b's null und erste c eins? – Parfait

+0

'count_categories' zählt nur das Aussehen der Tupel in' categories_to_count'. 'b' Kategorien sind nicht in dieser Liste. – Luke

Antwort

0

Da nicht-numerische Werte sind derzeit nicht durch Fenster behandelt, es ist wie der beste Weg scheint dies zu tun, ist ein Dummy ersten zu schaffen und dann mach eine laufende Summe dazu. Dies hat den Vorteil, dass auch an Rollfenstern gearbeitet wird.

categories_to_count = [('tito', 'puente'), 
         ('bar',), 
         ('feep',)] 

df['has_category'] = np.where(X['category'].isin(categories_to_count), 1, 0) 

df.groupby('group')['has_category'].apply(lambda x: x.expanding().sum()) 
1

Sie sind sich nicht sicher, ob Sie expandieren möchten, aber denken Sie daran, rank() in einer groupby -App-Funktion zu verwenden, nach Daten innerhalb der Gruppe zu sortieren und Kategorien mit isin() zu überprüfen. Der einzige Nachteil ist nicht eine Spalte mit dem Namen Index, die mit Index in groupby Serie, die kein Rang-Attribut hat. Sollten Sie müssen, sollten Sie Einstellung und die Umbenennung Index nach dem Tupel Zähloperation:

df = pd.DataFrame({'datesix':['2000-01-01', '2000-01-02', '2000-01-03', 
          '2000-01-04', '2000-01-05', '2000-01-06'], 
        'category':[('foo',), ('tito', 'puente'), ('bar',), 
           ('zip',), ('zorp',), ('feep',)],     
        'group': ['a', 'a', 'a', 'b', 'b', 'c']}) 

df['datesix'] = pd.to_datetime(df['datesix']) 

def count_categories(ser): 
    categories_to_count = [('tito', 'puente'), 
          ('bar',), 
          ('feep',)] 

    ser['tuple_count'] = ser.datesix[(ser.category.isin(categories_to_count))].rank() 
    ser['tuple_count'] = ser['tuple_count'].fillna(0).astype(int) 
    return ser 

df = df.groupby('group').apply(count_categories) 

#   category  datesix group tuple_count 
# 0   (foo,) 2000-01-01  a   0 
# 1 (tito, puente) 2000-01-02  a   1 
# 2   (bar,) 2000-01-03  a   2 
# 3   (zip,) 2000-01-04  b   0 
# 4   (zorp,) 2000-01-05  b   0 
# 5   (feep,) 2000-01-06  c   1 
+0

Wow. nett! Ich versuche immer noch, meinen Kopf dazu zu bringen. Warum verwenden Sie 'datesix' für die' rank' Methode. Könnten Sie irgendeine Spalte in 'datasix' verwenden, solange der Dataframe bereits geordnet ist? – Luke

+0

Leider nicht, 'rank()' rankt auf spezifische Variable. Sehen Sie es mit Kategorie und Element mit den meisten Elementen haben größere Ergebnis: 0, 2, 1, 0, 0, 1 für tuple_count. – Parfait

+0

Guckte etwas mehr und es wird nicht die Zählung von einer vorherigen Zeile beibehalten, wenn die aktuelle Zeile keine Kategorie von Interesse hat. – Luke