Pandas groupby-transform()-Funktion

Pandas 常用函数Pandas Häufige Funktionen


groupby.transform()Es ist eine Funktion in Pandas zum Transformieren von Daten nach der Gruppierung. Im Gegensatz zu Aggregatfunktionengibt die Aggregation ein Zusammenfassungsergebnis für jede Gruppe zurück, während die Transformation ein Ergebnis derselben Länge wie die Originaldaten zurückgibt.。

Einfach ausgedrückt,transform()es überträgt das gruppierte Berechnungsergebnis zurück auf jede Zeile der Originaldaten. Dies ist sehr nützlich in Szenarien wie der Berechnung der relativen Position jedes Mitglieds innerhalb einer Gruppe, der gruppeninternen Standardisierung und der Abweichungen vom Gruppenmittelwert.


Grundlegende Syntax und Parameter

transform()Es ist eine Memberfunktion des GroupBy-Objekts. Sie müssen zuerstgroupby()gruppieren, bevor Sie es aufrufen.

Syntaxformat

GroupBy.transform(func, axis=0, *args, engine=None, engine_kwargs=None, **kwargs)

Parameterbeschreibung

Parameter Type Beschreibung Standardwert
func str, list, dict oder callable Die Transformationsfunktion. Sie kann ein integrierter Funktionsname (wie 'mean', 'sum', 'std'), eine Liste von Funktionen, ein Dictionary, das unterschiedliche Funktionen für jede Spalte angibt, oder eine benutzerdefinierte Funktion sein. Keine
axis int Die Achsenrichtung für die Anwendung der Transformation. 0 bedeutet zeilenweise (Gruppierungsdimension), 1 bedeutet spaltenweise. 0
args tuple Zusätzliche Positionsargumente, die an die Transformationsfunktion übergeben werden. ()
engine str Gibt die Berechnungs-Engine an, die 'cython' oder 'numba' sein kann. None bedeutet, dass Pandas sie automatisch auswählt. Keine
engine_kwargs dict Ein Wörterbuch mit zusätzlichen Parametern, die an die zugrunde liegende Engine übergeben werden. Keine

Rückgabewert

  • Rückgabetyp:SeriesoderDataFrame
  • Beschreibung: Gibt ein Ergebnis mit derselben Anzahl an Zeilen wie die Originaldaten zurück. Jede Zeile der Originaldaten erhält das Berechnungsergebnis ihrer entsprechenden Gruppe.

Beispiele

Lass uns durch eine Reihe von Beispielen von einfach bis komplex gründlich meistern,groupby.transform()die Verwendung beherrschen.

Beispiel 1: Grundlegende Verwendung - Gruppenmittelwert berechnen

transform()Die grundlegendste Verwendung besteht darin, den Mittelwert jeder Gruppe zu berechnen und das Ergebnis dann auf jede Zeile zu übertragen.

Beispiel

import pandas as pd

# Daten mit Schülerergebnissen erstellen
data = {
    'Name': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu', Sun Qi, Zhou Ba, Wu Jiu, Zheng Shi],
    Klasse: ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'A'],
    Chinesisch: [85, 92, 78, 88, 95, 82, 90, 87],
    Mathematik: [90, 85, 92, 78, 88, 91, 85, 89]
}

# DataFrame erstellen
df = pd.DataFrame(data)

print("Schülernotendaten:")
print(df)
print()

# Den Mathe-Durchschnitt für jede Klasse berechnen und dann auf jede Zeile übertragen
df['Class Math Average'] = df.groupby(Class)[Mathematics].transform('mean')

# Berechne die Differenz zwischen der Punktzahl jedes Schülers und dem Klassendurchschnitt
df['Difference from average score'] = df[Mathematics] - df['Class Math Average']

print("Daten nach dem Hinzufügen von Klassendurchschnitt und Differenz:")
print(df)
print()

# Den Klassendurchschnitt für mehrere Spalten gleichzeitig berechnen
df[['Class Chinese Average', 'Class Math Average 2']] = df.groupby(Class)[[Chinese, Mathematics]].transform('mean')

print(Daten nach dem Hinzufügen der Durchschnitte mehrerer Spalten:)
print(df)

Run result:

学生成绩数据:
   姓名  班级  语文  数学
0  张三   A   85   90
1  李四   A   92   85
2  王五   A   78   92
3  赵六   B   88   78
4  孙七   B   95   88
5  周八   B   82   91
6  吴九   B   90   85
7  郑十   A   87   89

添加班级平均分和差值后的数据:
   姓名  班级   语文   数学   班级数学平均分   与平均分差值
0  张三   A   85   90  89.000000   1.000000
1  李四   A   92   85  89.000000  -4.000000
2  王五   A   78   92  89.000000   3.000000
3  赵六   B   88   78  85.666667   -7.666667
4  孙七   B   95   88  85.666667   2.333333
5  周八   B   82   91  85.666667   5.333333
6  吴九   B   90   85  85.666667   -0.666667
7  郑十   A   87   89  89.000000   0.000000

添加多列平均值后的数据:
   姓名  班级   语文   数学  班级语文平均分  班级数学平均分2
0  张三   A   85   90  85.500000         89.0
1  李四   A   92   85  85.500000         89.0
2  王五   A   78   92  85.500000         89.0
3  赵六   B   88   78  88.750000         85.5
4  孙七   B   95   88  88.750000         85.5
5  周八   B   82   91  88.750000         85.5
6  吴九   B   90   85  88.750000         85.5
7  郑十   A   87   89  85.500000         89.0

Code-Erklärung:

  1. transform('mean')Berechne den Mathe-Mittelwert für jede Klasse.
  2. Da Zhang San, Li Si, Wang Wu und Zheng Shi alle in Klasse A sind, ist der "Klassen-Mathe-Durchschnitt", den sie erhalten, der Mittelwert der Mathenoten von Klasse A.
  3. Die Länge des Rückgabewerts entspricht der Anzahl der Zeilen in den Originaldaten; das ist der entscheidende Unterschied zwischen transform und agg.

Beispiel 2: Gruppeninterne Standardisierung (Z-Score)

transform()Es wird oft verwendet, um gruppeninterne standardisierte Werte zu berechnen, was sehr nützlich ist, wenn die relative Position von Individuen innerhalb einer Gruppe verglichen werden soll.

Beispiel

import pandas as pd

# Mitarbeitergehaltsdaten erstellen
data = {
    'Name': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu', Sun Qi, Zhou Ba, Wu Jiu, Zheng Shi],
    'Department': [Sales, Sales, Sales, 'Technology', 'Technology', 'Technology', Administration, Administration],
    'salary': [5000, 8000, 6000, 9000, 12000, 10000, 4500, 7000]
}
df = pd.DataFrame(data)

print("Gehaltsdaten der Mitarbeiter:")
print(df)
print()

# Berechne den Z-Score (standardisierten Wert) des Gehalts jedes Mitarbeiters innerhalb der Abteilung
# Z-Score = (Originalwert - Gruppenmittelwert) / Gruppenstandardabweichung
df['Department average salary'] = df.groupby('Department')['salary'].transform('mean')
df['Department Salary Standard Deviation'] = df.groupby('Department')['salary'].transform('std')
df['Z-Score'] = (df['salary'] - df['Department average salary']) / df['Department Salary Standard Deviation']

print(Daten nach dem Hinzufügen von Abteilungsstatistiken und Z-Score:)
print(df)
print()

# Berechne den Z-Score auf einmal mit einer benutzerdefinierten Funktion
def z_score(x):
    """Z-Score berechnen"""
    return (x - x.mean()) / x.std()

df['Z-Score2'] = df.groupby('Department')['salary'].transform(z_score)

print(Z-Score berechnet mit einer benutzerdefinierten Funktion:)
print(df[['Name', 'Department', 'salary', 'Z-Score2']])

Run result:

员工工资数据:
  姓名  部门    工资
0  张三   销售   5000
1  李四   销售   8000
2  王五   销售   6000
3  赵六   技术   9000
4  孙七   技术  12000
5  周八   技术  10000
6  吴九   行政   4500
7  郑十   行政   7000

添加部门统计和Z-Score后的数据:
   姓名   部门    工资    部门平均工资   部门工资标准差    Z-Score
0  张三   销售  5000  6333.333333  1525.755   -0.872871
1  李四   销售  8000  6333.333333  1525.755    1.092091
2  王五   销售  6000  6333.333333  1525.755   -0.218218
3  赵六   技术  9000 10333.333333  1525.755   -0.872871
4  孙七   技术 12000 10333.333333  1525.755    1.092091
5  周八   技术 10000 10333.333333  1525.755   -0.218218
6  吴九   行政   4500  5750.000000  1767.767   -0.707107
7  郑十   行政   7000  5750.000000  1767.767    0.707107

使用自定义函数计算的 Z-Score:
   姓名  部门    工资   Z-Score2
0  张三   销售  5000  -0.872871
1  李四   销售  8000   1.092091
2  王五   销售  6000  -0.218218
3  赵六   技术  9000  -0.872871
4  孙七   技术 12000   1.092091
5  周八   技术 10000  -0.218218
6  吴九   行政  4500  -0.707107
7  郑十   行政  7000   0.707107

Code-Erklärung:

  • Der Z-Score gibt die Anzahl der Standardabweichungen an, um die der ursprüngliche Wert vom Mittelwert abweicht. Ein positiver Wert bedeutet über dem Mittelwert, ein negativer Wert bedeutet unter dem Mittelwert.
  • Durch den Z-Score kann der Einfluss von Gehaltsniveauunterschieden zwischen Abteilungen eliminiert werden, wodurch die relativen Positionen der Mitarbeiter innerhalb ihrer Abteilungen verglichen werden können.
  • Der Z-Score von Zhang San beträgt -0.87, was darauf hinweist, dass sein Gehalt etwa 0.87 Standardabweichungen unter dem Durchschnittsniveau der Vertriebsabteilung liegt.

Beispiel 3: Rangfolge innerhalb der Gruppe und Perzentil

transform()Es kann auch verwendet werden, um gruppeninterne Rangfolgen zu berechnen, was bei der Sortierung und Wettbewerbsanalyse sehr nützlich ist.

Beispiel

import pandas as pd
import numpy as np

# Daten mit Schülerergebnissen erstellen
data = {
    'Name': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu', Sun Qi, Zhou Ba, Wu Jiu, Zheng Shi],
    Klasse: ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'A'],
    Mathematik: [90, 85, 92, 78, 88, 91, 85, 89]
}
df = pd.DataFrame(data)

print("Schülernotendaten:")
print(df)
print()

# Berechne die Klassenrangfolge jedes Schülers (von der höchsten zur niedrigsten)
df['班levelinside排name'] = df.groupby(Class)[Mathematics].transform(lambda x: x.rank(ascending=False))

# Berechne das Perzentil jedes Schülers (prozentuale Rangfolge) innerhalb der Klasse
df['Percentile within class'] = df.groupby(Class)[Mathematics].transform(lambda x: x.rank(pct=True))

print("Daten nach dem Hinzufügen von Klassenrangfolge und Perzentil:")
print(df)
print()

# Eine weitere Möglichkeit, fehlende Werte zu füllen: Füllen mit dem Gruppenmittelwert
data_with_na = {
    'Name': ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu', Sun Qi, Zhou Ba],
    Klasse: ['A', 'A', 'A', 'B', 'B', 'B'],
    'Score': [85, np.nan, 78, 88, np.nan, 82]
}
df_na = pd.DataFrame(data_with_na)

print(Daten mit fehlenden Werten:)
print(df_na)
print()

# Fehlende Werte mit dem Gruppenmittelwert füllen
df_na['Filled score'] = df_na.groupby(Class)['Score'].transform(lambda x: x.fillna(x.mean()))

print(Ergebnis nach dem Füllen mit dem Gruppenmittelwert:)
print(df_na)

Run result:

学生成绩数据:
   姓名  班级  数学
0  张三   A   90
1  李四   A   85
2  王五   A   92
3  赵六   B   78
4  孙七   B   88
5  周八   B   91
6  吴九   B   85
7  郑十   A   89

添加班级内排名和百分位后的数据:
   姓名   班级   数学   班级内排名   班级内百分位
0  张三   A   90   2.0   0.666667
1  李四   A   85   3.0   1.000000
2  王五   A   92   1.0   1.000000
3  赵六   B   78   4.0   0.250000
4  孙七   B   88   2.0   0.500000
5  周八   B   91   1.0   0.750000
6  吴九   B   85   3.0   0.500000
7  郑十   A   89   4.0   0.333333

包含缺失值的数据:
   姓名  班级   成绩
0  张三   A   85.0
1  李四   A    NaN
2  王五   A   78.0
3  赵六   B   88.0
4  孙七   B    NaN
5  周八   B   82.0

使用组内均值填充后的结果:
   姓名  班级   成绩  填充后的成绩
0  张三   A   85.0         85.0
1  李四   A    NaN         81.5
2  王五   A   78.0         78.0
3  赵六   B   88.0         88.0
4  孙七   B    NaN         85.0
5  周八   B   82.0         82.0

Code-Erklärung:

  • rank(ascending=False)Berechne die Rangfolge, wobei höhere Werte zuerst eingestuft werden.
  • rank(pct=True)Berechne die Perzentil-Rangfolge, wobei die Ergebnisse zwischen 0 und 1 liegen.
  • transform(lambda x: x.fillna(x.mean()))Es ist ein übliches Muster für den Umgang mit fehlenden Werten, wobei der Mittelwert jeder Gruppe verwendet wird, um die fehlenden Werte innerhalb dieser Gruppe zu füllen.

Beispiel 4: Verwendung einer benutzerdefinierten Transformationsfunktion

transform()Benutzerdefinierte Funktionen werden unterstützt, wodurch komplexere gruppeninterne Datentransformationslogik ermöglicht wird.

Beispiel

import pandas as pd
import numpy as np

# Aktienkursdaten erstellen
data = {
    'Stock Code': ['AAPL', 'AAPL', 'AAPL', 'AAPL', 'GOOG', 'GOOG', 'GOOG', 'GOOG'],
    'Datum': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'] * 2,
    'Close Price': [100, 105, 102, 110, 80, 85, 82, 90]
}
df = pd.DataFrame(data)

print("Aktienkursdaten:")
print(df)
print()

# Benutzerdefinierte Funktion: Tägliche Rendite für jede Aktie berechnen
def calc_daily_return(prices):
    """Berechne die tägliche Rendite: (heutiger Preis - gestriger Preis) / gestriger Preis"""
    return prices.pct_change()

# Berechne die Tagesrendite für jede Aktie
df['Daily Return'] = df.groupby('Stock Code')['Close Price'].transform(calc_daily_return)

print("Daten nach Hinzufügen der Tagesrendite:")
print(df)
print()

# Benutzerdefinierte Funktion: Berechne den normalisierten Wert auf Basis des Maximums und Minimums innerhalb der Gruppe
def normalize(x):
    """Normalisierung: (x - min) / (max - min)"""
    return (x - x.min()) / (x.max() - x.min())

# Berechne den normalisierten Preis für jede Aktie
df['Normalized Price'] = df.groupby('Stock Code')['Close Price'].transform(normalize)

print("Daten nach Hinzufügen des normalisierten Preises:")
print(df)

Ausführungsergebnis:

股票价格数据:
  股票代码         日期   收盘价
0  AAPL  2024-01-01   100
1  AAPL  2024-01-02   105
2  AAPL  2024-01-03   102
3  AAPL  2024-01-04   110
4  GOOG  2024-01-01    80
5  GOOG  2024-01-02    85
6  GOOG  2024-01-03    82
7  GOOG  2024-01-04    90

添加日收益率后的数据:
   股票代码         日期  收盘价     日收益率
0  AAPL  2024-01-01   100         NaN
1  AAPL  2024-01-02   105    0.050000
2  AAPL  2024-01-03   102   -0.028571
3  AAPL  2024-01-04   110    0.078431
4  GOOG  2024-01-01    80         NaN
5  GOOG  2024-01-02    85    0.062500
6  GOOG  2024-01-03    82   -0.035294
7  GOOG  2024-01-04    90    0.097561

添加归一化价格后的数据:
   股票代码         日期  收盘价     日收益率   归一化价格
0  AAPL  2024-01-01   100         NaN    0.000000
1  AAPL  2024-01-02   105    0.050000    0.500000
2  AAPL  2024-01-03   102   -0.028571    0.200000
3  AAPL  2024-01-04   110    0.078431    1.000000
4  GOOG  2024-01-01    80         NaN    0.000000
5  GOOG  2024-01-02    85    0.062500    0.500000
6  GOOG  2024-01-03    82   -0.035294    0.200000
7  GOOG  2024-01-04    90    0.097561    1.000000

Code-Erklärung:

  • Die Transformationsfunktion erhält eine Series (die Daten innerhalb jeder Gruppe).
  • Die Länge der zurückgegebenen Series muss mit der Länge der eingegebenen Series übereinstimmen.
  • Der erste Wert ist NaN, weilpct_change()er eine relative Änderung berechnet und der erste Tag keine Daten des vorherigen Tages hat.

Wesentlicher Unterschied:agg()undtransform()Der Unterschied ist:agg()gibt das aggregierte Ergebnis für jede Gruppe zurück (die Anzahl der Zeilen entspricht der Anzahl der Gruppen), währendtransform()ein Ergebnis mit der gleichen Länge wie die Originaldaten zurückgibt. Einfach gemerkt: agg komprimiert Daten, transform behält die Datenform bei.


Pandas 常用函数Pandas gängige Funktionen

Weitere Erweiterungen