Deprecare l'utilizzo di valuese as_matrix()!
pandas v0.24.0 ha introdotto due nuovi metodi per ottenere matrici NumPy dagli oggetti pandas:
to_numpy(), che è definito su Index, Series,e DataFrameoggetti e
array, che è definito su Indexe Seriessolo oggetti.
Se visiti i documenti v0.24 per .values, vedrai un grande avviso rosso che dice:
Avvertenza: si consiglia DataFrame.to_numpy()invece di utilizzare .
Vedere questa sezione delle note sulla versione v0.24.0 e questa risposta per ulteriori informazioni.
Verso una migliore coerenza: to_numpy()
Nello spirito di una migliore coerenza in tutta l'API, to_numpyè stato introdotto un nuovo metodo per estrarre l'array NumPy sottostante da DataFrames.
# 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]])
Come accennato in precedenza, questo metodo è anche definito su Indexe Seriesoggetti (vedi qui ).
df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)
df['A'].to_numpy()
# array([1, 2, 3])
Per impostazione predefinita, viene restituita una vista, quindi eventuali modifiche apportate influiranno sull'originale.
v = df.to_numpy()
v[0, 0] = -1
df
A B
a -1 4
b 2 5
c 3 6
Se invece hai bisogno di una copia, usa to_numpy(copy=True).
panda> = 1.0 aggiornamento per ExtensionTypes
Se stai usando Panda 1.x, è probabile che avrai a che fare con tipi di estensione molto di più. Dovrai stare un po 'più attento che questi tipi di estensione vengano convertiti correttamente.
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])
Questo è richiamato nei documenti .
Se hai bisogno del dtypes...
Come mostrato in un'altra risposta, DataFrame.to_recordsè un buon modo per farlo.
df.to_records()
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])
to_numpyPurtroppo non è possibile farlo . Tuttavia, in alternativa, è possibile utilizzare 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')])
Per quanto riguarda le prestazioni, è quasi lo stesso (in realtà, l'utilizzo rec.fromrecordsè un po 'più veloce).
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)
Razionale per l'aggiunta di un nuovo metodo
to_numpy()(oltre a array) è stato aggiunto a seguito di discussioni nell'ambito di due numeri GitHub GH19954 e GH23623 .
In particolare, i documenti menzionano la logica:
[...] con .valuesesso non era chiaro se il valore restituito sarebbe l'array effettivo, una sua trasformazione o uno degli array personalizzati di panda (come Categorical). Ad esempio, con PeriodIndex, .values
genera ndarrayogni volta un nuovo oggetto periodico. [...]
to_numpymirare a migliorare la coerenza dell'API, che rappresenta un passo importante nella giusta direzione. .valuesnon sarà deprecato nella versione corrente, ma mi aspetto che ciò possa accadere ad un certo punto in futuro, quindi esorto gli utenti a migrare verso l'API più recente, appena possibile.
Critica di altre soluzioni
DataFrame.values ha un comportamento incoerente, come già notato.
DataFrame.get_values()è semplicemente un involucro in giro DataFrame.values, quindi si applica tutto quanto detto sopra.
DataFrame.as_matrix()è obsoleto ora, NON utilizzare!