[PYTHON] pandas idxmax ist langsam

Hintergrund

Bei der Verarbeitung von Big Data bei der Arbeit Ich bemerkte, dass die Verarbeitung langsam war und ich nach dem Verbrecher suchte. Ich habe festgestellt, dass __idxmax () __ in der Pandas-Bibliothek langsam ist. </ font>

Natürlich gibt es im Vergleich zu max einen Prozess, um den Index des max-Werts zurückzugeben, daher ist es natürlich, dass er langsamer ist. Ich versuchte zu überprüfen, wie langsam es tatsächlich war.

Vorausgesetztes Wissen

Die Verarbeitung von __max () __ und __idxmax () __ von Pandas ist wie folgt.

import pandas as pd
import numpy as np

#Generieren Sie einen 10x5-Datenrahmen mit zufälligen Ganzzahlen zwischen 0 und 100
data = np.random.randint(0,100,[10,5])
df = pd.DataFrame(data,
                  index=['A','B','C','D','E','F','G','H','I','J'],
                  columns=['a','b','c','d','e'])

print(df)
print(df.max())
print(df.idxmax())

__max () __ gibt den Maximalwert für jede Spalte zurück. __idxmax () __ gibt den maximalen Index für jede Spalte zurück

Es ist eine Funktion namens.

Vergrößern wir nun den Datenrahmen und messen die Verarbeitungszeit.

Verarbeitungszeitmessung von max () und idxmax ()

import pandas as pd
import numpy as np
import time

arr = np.random.randint(0,100,[10**5,10**4],dtype='int8')
df = pd.DataFrame(arr, dtype='int8')
df.info()
#<class 'pandas.core.frame.DataFrame'>
#RangeIndex: 100000 entries, 0 to 99999
#Columns: 10000 entries, 0 to 9999
#dtypes: int8(10000)
#memory usage: 953.7 MB

ts = time.time()
df.max()
te =time.time()
print('max()_time:',te-ts)
#max()_time: 10.67

ts = time.time()
df.idxmax()
te =time.time()
print('idxmax()_time:',te-ts)
#idxmax()_time: 19.08

Das obige Experiment Für einen Datenrahmen von ca. 1 GB Dies ist das Ergebnis der Messung der Verarbeitungszeit von __max () __ und __idxmax () __.

__idxmax () __ 19.08 ÷ 10.67 = __1.78 mal __ </ font> Ich fand, dass der Prozess langsam war.

Die Maschinenspezifikationen sind übrigens MacBookPro 2018-Modell, Prozessor: 2,3 GHz Intel Core i5, Speicher: 8 GB 2133 MHz LPDDR3 ist (Auf dem Windows-PC meines Unternehmens gab es einen 6-fachen Zeitunterschied.)

Schauen wir uns den Inhalt der Funktion idxmax () an, um zu sehen, ob dies schneller möglich ist.

Quellcode für idxmax ()
import inspect
print(inspect.getsource(pd.DataFrame.idxmax))

Nachdem Sie dies ausgeführt haben, lautet der zurückgegebene Quellcode wie folgt.

def idxmax(self, axis=0, skipna=True):
    """
    Return index of first occurrence of maximum over requested axis.
    NA/null values are excluded.

    Parameters
    ----------
    axis : {0 or 'index', 1 or 'columns'}, default 0
        0 or 'index' for row-wise, 1 or 'columns' for column-wise
    skipna : boolean, default True
        Exclude NA/null values. If an entire row/column is NA, the result
        will be NA.

    Returns
    -------
    idxmax : Series

    Raises
    ------
    ValueError
        * If the row/column is empty

    See Also
    --------
    Series.idxmax

    Notes
    -----
    This method is the DataFrame version of ``ndarray.argmax``.
    """
    axis = self._get_axis_number(axis)
    indices = nanops.nanargmax(self.values, axis=axis, skipna=skipna)
    index = self._get_axis(axis)
    result = [index[i] if i >= 0 else np.nan for i in indices]
    return Series(result, index=self._get_agg_axis(axis))

Es ist als Datenrahmenversion der Funktion __argmax () __ von ndarray geschrieben. Natürlich war es wie erwartet, daher möchte ich die Verarbeitungszeit von __max () __ und __argmax () __ vergleichen.

Verarbeitungszeitmessung von max () und idxmax ()

ts = time.time()
_max = np.max(arr,axis=0)
te =time.time()
print('max()_time:',te-ts)
#max()_time: 0.85

ts = time.time()
_argmax = np.argmax(arr,axis=0)
te =time.time()
print('argmax()_time:',te-ts)
#argmax()_time: 13.70

Das Ergebnis ist __argmax () __ 13,70 ÷ 0,85 = __ 16,11 mal __ </ font> Ich fand, dass der Prozess langsam war.

Erwägung

-Beide sind schneller als der Datenrahmen. ・ Max ist bei Verwendung von ndarray überwiegend schneller als idxmax.

Ich verstehe.

Als Ursache, Da idxmax ein Prozess ist, der nur den Index der ersten Daten zurückgibt, wenn der gleiche Maximalwert vorhanden ist, Ich habe das Gefühl, dass die Bearbeitungszeit um diesen Betrag länger ist.

Wenn Sie den Bereich und die Größe der Zufallszahlen im Datenrahmen ändern, ändert sich diese Vergrößerung erheblich Quantitatives Sprechen ist schwierig, Eine Sache zu sagen ist, dass, wenn Sie keine datenrahmenspezifische Verarbeitung verwenden (wie groupby) Es ist besser, es nicht unnötig in einen Datenrahmen zu schaffen.