Verwerfen Sie Ihre Verwendung von values
und 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 Index
ist , undSeries,
DataFrame
array
, die nur für Index
und Series
Objekte 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_numpy
eingefü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 Index
und Series
Objekte 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_records
ist 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_numpy
leider 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.fromrecords
etwas 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:
[...] .values
dabei 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 ndarray
Perioden Objekte jedes Mal. [...]
to_numpy
Ziel ist es, die Konsistenz der API zu verbessern, was ein wichtiger Schritt in die richtige Richtung ist. .values
wird 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!