Anwenden einer benutzerdefinierten Gruppe durch aggregierte Funktion, um ein binäres Ergebnis in pandas python auszugeben

Ich habe einen Datensatz von Trader-Transaktionen, wo die Variable von Interesse ist Buy/Sell die binär ist und nimmt den Wert von 1 f die Transaktion war ein Kauf und 0, wenn es ein Verkauf ist. Ein Beispiel sieht wie folgt aus:

 Trader Buy/Sell A 1 A 0 B 1 B 1 B 0 C 1 C 0 C 0 

Ich möchte das Netto Buy/Sell für jeden Trader berechnen, so dass, wenn der Trader mehr als 50% der Trades als Kauf hatte, er einen Buy/Sell von 1 haben würde, wenn er weniger als 50% kaufen würde, dann würde er Habe einen Buy/Sell von 0 und wenn es genau 50% wäre er NA (und würde in zukünftigen Berechnungen nicht berücksichtigt werden).

  • Pandas gruppieren mit zwei schlüsseln
  • Wenden Sie mehrere Funktionen auf mehrere groupby-Spalten an
  • Also für Trader A ist der Kaufanteil (Anzahl der Käufe) / (Gesamtzahl des Traders) = 1/2 = 0,5, was NA ergibt.

    Für Trader B ist es 2/3 = 0,67, was eine 1

    Für Trader C ist es 1/3 = 0,33, was eine 0 gibt

    Der Tisch sollte so aussehen:

     Trader Buy/Sell A NA B 1 C 0 

    Letztlich möchte ich die gesamte aggregierte Anzahl von Käufen berechnen, die in diesem Fall 1 ist, und die aggregierte Gesamtzahl der Trades (ohne NAs), die in diesem Fall 2 ist. Ich interessiere mich nicht für die zweite Tabelle, ich bin nur interessiert In der aggregierten Anzahl von Käufen und der aggregierten Gesamtzahl (Anzahl) von Buy/Sell .

    Wie kann ich das in Pandas machen?

  • Regulärer Ausdruck, um zu bestätigen, ob ein String ein gültiger Bezeichner in Python ist
  • Unicode-Identifikatoren in Python?
  • Identifikationsnormierung: Warum wird das Mikroschild in den griechischen Buchstaben mu umgewandelt?
  • Was bedeutet ** (Doppelstern) und * (Stern) für Parameter?
  • Was bedeutet ** (Doppelstern) und * (Stern) für Parameter?
  • Ist es sicher, eine Funktion zu verwenden akzeptiert kwargs Keyword-Argumente, die keine Bezeichner sind?
  • One Solution collect form web for “Anwenden einer benutzerdefinierten Gruppe durch aggregierte Funktion, um ein binäres Ergebnis in pandas python auszugeben”

     import numpy as np import pandas as pd df = pd.DataFrame({'Buy/Sell': [1, 0, 1, 1, 0, 1, 0, 0], 'Trader': ['A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']}) grouped = df.groupby(['Trader']) result = grouped['Buy/Sell'].agg(['sum', 'count']) means = grouped['Buy/Sell'].mean() result['Buy/Sell'] = np.select(condlist=[means>0.5, means<0.5], choicelist=[1, 0], default=np.nan) print(result) 

    Erträge

      Buy/Sell sum count Trader A NaN 1 2 B 1 2 3 C 0 1 3 

    Meine ursprüngliche Antwort benutzte einen benutzerdefinierten Aggregator, categorize :

     def categorize(x): m = x.mean() return 1 if m > 0.5 else 0 if m < 0.5 else np.nan result = df.groupby(['Trader'])['Buy/Sell'].agg([categorize, 'sum', 'count']) result = result.rename(columns={'categorize' : 'Buy/Sell'}) 

    Während das Aufrufen einer benutzerdefinierten Funktion kann bequem sein, ist die Leistung oft deutlich langsamer, wenn Sie eine benutzerdefinierte Funktion im Vergleich zu den eingebauten Aggregatoren (wie groupby/agg/mean ) verwenden. Die eingebauten Aggregatoren sind zythonisiert, während die benutzerdefinierten Funktionen die Leistung auf einfache Python-Loop-Geschwindigkeiten reduzieren.

    Der Unterschied in der Geschwindigkeit ist besonders wichtig, wenn die Anzahl der Gruppen groß ist. Zum Beispiel mit einem 10000-reihigen DataFrame mit 1000 Gruppen,

     import numpy as np import pandas as pd np.random.seed(2017) N = 10000 df = pd.DataFrame({ 'Buy/Sell': np.random.randint(2, size=N), 'Trader': np.random.randint(1000, size=N)}) def using_select(df): grouped = df.groupby(['Trader']) result = grouped['Buy/Sell'].agg(['sum', 'count']) means = grouped['Buy/Sell'].mean() result['Buy/Sell'] = np.select(condlist=[means>0.5, means<0.5], choicelist=[1, 0], default=np.nan) return result def categorize(x): m = x.mean() return 1 if m > 0.5 else 0 if m < 0.5 else np.nan def using_custom_function(df): result = df.groupby(['Trader'])['Buy/Sell'].agg([categorize, 'sum', 'count']) result = result.rename(columns={'categorize' : 'Buy/Sell'}) return result 

    using_select ist über 50x schneller als using_custom_function :

     In [69]: %timeit using_custom_function(df) 10 loops, best of 3: 132 ms per loop In [70]: %timeit using_select(df) 100 loops, best of 3: 2.46 ms per loop In [71]: 132/2.46 Out[71]: 53.65853658536585 
    Python ist die beste Programmiersprache der Welt.