Finden Sie das Maximum von zwei oder mehr Spalten mit Pandas


92

Ich habe einen Datenrahmen mit Spalten A, B. Ich muss eine Spalte Cso erstellen, dass für jeden Datensatz / jede Zeile:

C = max(A, B).

Wie soll ich das machen?

Antworten:


182

Sie können das Maximum wie folgt erhalten:

>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
>>> df
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]]
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]].max(axis=1)
0    1
1    8
2    3

und so:

>>> df["C"] = df[["A", "B"]].max(axis=1)
>>> df
   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

Wenn Sie wissen, dass "A" und "B" die einzigen Spalten sind, könnten Sie sogar damit durchkommen

>>> df["C"] = df.max(axis=1)

Und du könntest es auch gebrauchen .apply(max, axis=1), denke ich.


1
.apply(max, axis=1)ist viel langsamer als.max(axis=1)
RajeshM

26

Die Antwort von @ DSM ist in fast jedem normalen Szenario vollkommen in Ordnung. Wenn Sie jedoch ein Programmierer sind, der etwas tiefer als bis zur Oberfläche gehen möchte, könnte es Sie interessieren, dass es etwas schneller ist, Numpy-Funktionen auf dem zugrunde liegenden Array .to_numpy()(oder .valuesfür <0,24) anstatt direkt aufzurufen Aufrufen der (cythonisierten) Funktionen, die für die DataFrame / Series-Objekte definiert sind.

Zum Beispiel können Sie ndarray.max()entlang der ersten Achse verwenden.

# Data borrowed from @DSM's post.
df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
df
   A  B
0  1 -2
1  2  8
2  3  1

df['C'] = df[['A', 'B']].values.max(1)
# Or, assuming "A" and "B" are the only columns, 
# df['C'] = df.values.max(1) 
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

Wenn Ihre Daten NaNs haben, benötigen Sie numpy.nanmax:

df['C'] = np.nanmax(df.values, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

Sie können auch verwenden numpy.maximum.reduce. numpy.maximumist ein Ufunc (Universal Function) und jeder Ufunc hat einreduce :

df['C'] = np.maximum.reduce(df['A', 'B']].values, axis=1)
# df['C'] = np.maximum.reduce(df[['A', 'B']], axis=1)
# df['C'] = np.maximum.reduce(df, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

Geben Sie hier die Bildbeschreibung ein

np.maximum.reduceund np.maxscheinen mehr oder weniger gleich zu sein (für die meisten normal großen DataFrames) - und zufällig einen Schatten schneller als DataFrame.max. Ich stelle mir vor, dass dieser Unterschied in etwa konstant bleibt und auf internen Overhead (Indexausrichtung, Umgang mit NaNs usw.) zurückzuführen ist.

Der Graph wurde unter Verwendung eines Perfplots erzeugt . Benchmarking-Code als Referenz:

import pandas as pd
import perfplot

np.random.seed(0)
df_ = pd.DataFrame(np.random.randn(5, 1000))

perfplot.show(
    setup=lambda n: pd.concat([df_] * n, ignore_index=True),
    kernels=[
        lambda df: df.assign(new=df.max(axis=1)),
        lambda df: df.assign(new=df.values.max(1)),
        lambda df: df.assign(new=np.nanmax(df.values, axis=1)),
        lambda df: df.assign(new=np.maximum.reduce(df.values, axis=1)),
    ],
    labels=['df.max', 'np.max', 'np.maximum.reduce', 'np.nanmax'],
    n_range=[2**k for k in range(0, 15)],
    xlabel='N (* len(df))',
    logx=True,
    logy=True)

Kleiner Tippfehler: "df ['C'] = np.maximum.reduce (df ['A', 'B']]. Werte, Achse = 1)" sollte "df ['C'] = np.maximum sein. reduzieren (df [['A', 'B']]. Werte, Achse = 1) "
Velizar VESSELINOV
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.