Verwerfen Sie Ihre Verwendung von valuesund as_matrix()!
In pandas v0.24.0 wurden zwei neue Methoden zum Abrufen von NumPy-Arrays aus Pandas-Objekten eingeführt:
to_numpy(), die auf und Objekte definiert Indexist , undSeries,DataFrame
array, die nur für Indexund SeriesObjekte definiert ist .
Wenn Sie die v0.24-Dokumente für besuchen .values, wird eine große rote Warnung angezeigt , die besagt:
Warnung: Wir empfehlen DataFrame.to_numpy()stattdessen die Verwendung .
Weitere Informationen finden Sie in diesem Abschnitt der Versionshinweise zu Version 0.24.0 und in dieser Antwort .
Auf dem Weg zu einer besseren Konsistenz: to_numpy()
Im Sinne einer besseren Konsistenz in der gesamten API wurde eine neue Methode to_numpyeingeführt, um das zugrunde liegende NumPy-Array aus DataFrames zu extrahieren.
# Setup.
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])
df.to_numpy()
array([[1, 4],
[2, 5],
[3, 6]])
Wie oben erwähnt, ist diese Methode auch für Indexund SeriesObjekte definiert (siehe hier ).
df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)
df['A'].to_numpy()
# array([1, 2, 3])
Standardmäßig wird eine Ansicht zurückgegeben, sodass alle vorgenommenen Änderungen das Original beeinflussen.
v = df.to_numpy()
v[0, 0] = -1
df
A B
a -1 4
b 2 5
c 3 6
Wenn Sie stattdessen eine Kopie benötigen, verwenden Sie to_numpy(copy=True).
pandas> = 1.0 Update für ExtensionTypes
Wenn Sie pandas 1.x verwenden, werden Sie wahrscheinlich viel mehr mit Erweiterungstypen zu tun haben. Sie müssen etwas vorsichtiger sein, dass diese Erweiterungstypen korrekt konvertiert werden.
a = pd.array([1, 2, None], dtype="Int64")
a
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64
# Wrong
a.to_numpy()
# array([1, 2, <NA>], dtype=object) # yuck, objects
# Right
a.to_numpy(dtype='float', na_value=np.nan)
# array([ 1., 2., nan])
Dies wird in den Dokumenten erwähnt .
Wenn Sie die dtypes...
Wie in einer anderen Antwort gezeigt, DataFrame.to_recordsist dies ein guter Weg, dies zu tun.
df.to_records()
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])
Dies ist to_numpyleider nicht möglich. Alternativ können Sie jedoch Folgendes verwenden np.rec.fromrecords:
v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8')])
In Bezug auf die Leistung ist es fast das gleiche (tatsächlich ist die Verwendung rec.fromrecordsetwas schneller).
df2 = pd.concat([df] * 10000)
%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Begründung für das Hinzufügen einer neuen Methode
to_numpy()(zusätzlich zu array) wurde als Ergebnis von Diskussionen unter zwei GitHub-Ausgaben GH19954 und GH23623 hinzugefügt .
In den Dokumenten wird insbesondere die Begründung erwähnt:
[...] .valuesdabei war unklar, ob der zurückgegebene Wert das tatsächliche Array, eine Transformation davon oder eines der benutzerdefinierten Pandas-Arrays (wie Categorical) sein würde. Zum Beispiel mit PeriodIndex, .values
erzeugt eine neue ndarrayPerioden Objekte jedes Mal. [...]
to_numpyZiel ist es, die Konsistenz der API zu verbessern, was ein wichtiger Schritt in die richtige Richtung ist. .valueswird in der aktuellen Version nicht veraltet sein, aber ich gehe davon aus, dass dies irgendwann in der Zukunft passieren wird. Daher möchte ich die Benutzer dringend bitten, so bald wie möglich auf die neuere API zu migrieren.
Kritik anderer Lösungen
DataFrame.values hat inkonsistentes Verhalten, wie bereits erwähnt.
DataFrame.get_values()ist einfach ein Wrapper herum DataFrame.values, also gilt alles, was oben gesagt wurde.
DataFrame.as_matrix()ist jetzt veraltet, NICHT verwenden!