702 Stimmen

Unterschied zwischen den Methoden map, applymap und apply in Pandas

Können Sie mir sagen, wann man diese Vektorisierungsmethoden mit einfachen Beispielen verwenden sollte?

Ich sehe, dass map eine Methode für Series ist, während die anderen Methoden für DataFrame sind. Ich war jedoch verwirrt über die Methoden apply und applymap. Warum haben wir zwei Methoden, um eine Funktion auf ein DataFrame anzuwenden? Wieder würden einfache Beispiele, die die Verwendung veranschaulichen, hilfreich sein!

15voto

Kath Punkte 1834

Vielleicht die einfachste Erklärung für den Unterschied zwischen apply und applymap:

apply nimmt die gesamte Spalte als Parameter und weist dann das Ergebnis dieser Spalte zu

applymap nimmt den separaten Zellenwert als Parameter und weist das Ergebnis zurück zu dieser Zelle.

NB Wenn apply den einzelnen Wert zurückgibt, haben Sie diesen Wert anstelle der Spalte nach der Zuweisung und letztendlich haben Sie nur eine Zeile anstelle einer Matrix.

12voto

muon Punkte 10656

Wollte nur darauf hinweisen, dass ich damit ein wenig kämpfen musste

def f(x):
    if x < 0:
        x = 0
    elif x > 100000:
        x = 100000
    return x

df.applymap(f)
df.describe()

dies ändert das DataFrame selbst nicht, muss neu zugewiesen werden:

df = df.applymap(f)
df.describe()

7voto

Alpha Punkte 589

Basierend auf der Antwort von cs95

  • map wird NUR auf Series definiert
  • applymap wird NUR auf DataFrames definiert
  • apply wird auf BEIDEN definiert

Geben Sie einige Beispiele an

In [3]: frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [4]: frame
Out[4]:
            b         d         e
Utah    0.129885 -0.475957 -0.207679
Ohio   -2.978331 -1.015918  0.784675
Texas  -0.256689 -0.226366  2.262588
Oregon  2.605526  1.139105 -0.927518

In [5]: myformat=lambda x: f'{x:.2f}'

In [6]: frame.d.map(myformat)
Out[6]:
Utah      -0.48
Ohio      -1.02
Texas     -0.23
Oregon     1.14
Name: d, dtype: object

In [7]: frame.d.apply(myformat)
Out[7]:
Utah      -0.48
Ohio      -1.02
Texas     -0.23
Oregon     1.14
Name: d, dtype: object

In [8]: frame.applymap(myformat)
Out[8]:
            b      d      e
Utah     0.13  -0.48  -0.21
Ohio    -2.98  -1.02   0.78
Texas   -0.26  -0.23   2.26
Oregon   2.61   1.14  -0.93

In [9]: frame.apply(lambda x: x.apply(myformat))
Out[9]:
            b      d      e
Utah     0.13  -0.48  -0.21
Ohio    -2.98  -1.02   0.78
Texas   -0.26  -0.23   2.26
Oregon   2.61   1.14  -0.93

In [10]: myfunc=lambda x: x**2

In [11]: frame.applymap(myfunc)
Out[11]:
            b         d         e
Utah    0.016870  0.226535  0.043131
Ohio    8.870453  1.032089  0.615714
Texas   0.065889  0.051242  5.119305
Oregon  6.788766  1.297560  0.860289

In [12]: frame.apply(myfunc)
Out[12]:
            b         d         e
Utah    0.016870  0.226535  0.043131
Ohio    8.870453  1.032089  0.615714
Texas   0.065889  0.051242  5.119305
Oregon  6.788766  1.297560  0.860289

5voto

mikelowry Punkte 1357

Nur für zusätzlichen Kontext und Intuition, hier ist ein explizites und konkretes Beispiel für die Unterschiede.

Annehmen, dass Sie die folgende Funktion haben. ( Diese Label-Funktion teilt willkürlich die Werte in 'Hoch' und 'Niedrig' auf, basierend auf dem Schwellenwert, den Sie als Parameter (x) bereitstellen.)

def label(element, x):
    if element > x:
        return 'Hoch'
    else:
        return 'Niedrig'

In diesem Beispiel nehmen wir an, dass unser DataFrame eine Spalte mit Zufallszahlen hat.

DataFrame mit einer Spalte, die Zufallszahlen enthält

Wenn Sie versucht haben, die Label-Funktion mit map zu verwenden:

df['Spaltenname'].map(label, x = 0.8)

Werden Sie den folgenden Fehler erhalten:

TypeError: map() hat ein unerwartetes Schlüsselwortargument 'x'

Nehmen Sie nun dieselbe Funktion und verwenden Sie apply, dann werden Sie sehen, dass es funktioniert:

df['Spaltenname'].apply(label, x=0.8)

Series.apply() kann zusätzliche Argumente elementweise entgegennehmen, während die Methode Series.map() einen Fehler zurückgibt.

Wenn Sie nun versuchen, dieselbe Funktion gleichzeitig auf mehrere Spalten in Ihrem DataFrame anzuwenden, wird DataFrame.applymap() verwendet.

df[['Spaltenname','Spaltenname2','Spaltenname3','Spaltenname4']].applymap(label)

Zuletzt können Sie auch die apply() Methode auf einem DataFrame verwenden, aber die DataFrame.apply() Methode hat unterschiedliche Funktionen. Anstatt Funktionen elementweise anzuwenden, wendet die df.apply() Methode Funktionen entlang einer Achse an, entweder spaltenweise oder zeilenweise. Wenn wir eine Funktion erstellen, die mit df.apply() verwendet werden soll, richten wir sie so ein, dass sie eine Serie akzeptiert, am häufigsten eine Spalte.

Hier ist ein Beispiel:

df.apply(pd.value_counts)

Als wir die Funktion pd.value_counts auf das DataFrame angewendet haben, hat es die Wertezählungen für alle Spalten berechnet.

Beachten Sie, und das ist sehr wichtig, wenn wir die df.apply() Methode verwendet haben, um mehrere Spalten zu transformieren. Dies ist nur möglich, weil die Funktion pd.value_counts auf einer Serie arbeitet. Wenn wir versuchen würden, die df.apply() Methode zu verwenden, um eine Funktion anzuwenden, die elementweise an mehreren Spalten arbeitet, würden wir einen Fehler erhalten:

Zum Beispiel:

def label(element):
    if element > 1:
        return 'Hoch'
    else:
        return 'Niedrig'

df[['Spaltenname','Spaltenname2','Spaltenname3','Spaltenname4']].apply(label)

Dies wird den folgenden Fehler verursachen:

ValueError: ('Der Wahrheitswert einer Serie ist mehrdeutig. Verwenden Sie a.empty, a.bool(), a.item(), a.any() oder a.all().', u'bereits aufgetreten bei Index Economy')

Allgemein sollten wir die apply() Methode nur verwenden, wenn keine vektorisierte Funktion existiert. Denken Sie daran, dass Pandas die Vektorisierung verwendet, den Prozess, Operationen auf ganze Serien auf einmal anzuwenden, um die Leistung zu optimieren. Wenn wir die apply() Methode verwenden, durchlaufen wir eigentlich die Zeilen, daher kann eine vektorisierte Methode die Aufgabe schneller als die apply()-Methode erledigen.

apply, applymap, map Zusammenfassung

Hier sind einige Beispiele für vektorisierte Funktionen, die bereits existieren, die Sie NICHT mit irgendwelchen Arten von apply/map Methoden neu erstellen möchten:

  1. Series.str.split() Teilt jedes Element in der Serie
  2. Series.str.strip() Entfernt Leerzeichen von jedem String in der Serie.
  3. Series.str.lower() Konvertiert Zeichenfolgen in der Serie in Kleinbuchstaben.
  4. Series.str.upper() Konvertiert Zeichenfolgen in der Serie in Großbuchstaben.
  5. Series.str.get() Ruft das ith Element jedes Elements in der Serie ab.
  6. Series.str.replace() Ersetzt ein Regex oder eine Zeichenkette in der Serie durch eine andere Zeichenfolge
  7. Series.str.cat() Verkettet Zeichenfolgen in einer Serie.
  8. Series.str.extract() Extrahiert Teilzeichenfolgen aus der Serie, die auf einem Regex-Muster basieren.

3voto

Vicky Miao Punkte 61

Mein Verständnis:

Vom Funktionsstandpunkt aus:

Wenn die Funktion Variablen hat, die innerhalb einer Spalte/Zeile verglichen werden müssen, verwenden Sie apply.

z.B.: lambda x: x.max()-x.mean().

Wenn die Funktion auf jedes Element angewendet werden soll:

1> Wenn eine Spalte/Zeile gefunden wird, verwenden Sie apply

2> Wenn auf das gesamte DataFrame angewendet werden soll, verwenden Sie applymap

majority = lambda x : x > 17
df2['legal_drinker'] = df2['age'].apply(majority)

def times10(x):
  if type(x) is int:
    x *= 10 
  return x
df2.applymap(times10)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X