Skip to content

Convertire pandas.DataFrame, Series e numpy.ndarray tra di loro

Python

pandas.DataFrame, pandas.Series e l’array NumPy numpy.ndarray possono essere convertiti l’uno nell’altro.

  • Converti DataFrame, serie in ndarray:values
  • Converti ndarray in DataFrame, Series
  • Nota sulla condivisione della memoria (visualizza e copia)
  • panda 0.24.0 o successivo:to_numpy()

Nota che panda.DataFrame e pandas.Series hanno as_matrix() che rilascia anche numpy.ndarray, ma è stato deprecato dalla versione 0.23.0.

Vedere l’articolo seguente per eseguire la conversione tra pandas.DataFrame, pandas.Series e l’elenco dei tipi predefiniti di Python.

Converti DataFrame, serie in ndarray:values

Sia pandas.DataFrame che pandas.Series un attributo values ​​​​che hanno trasferito l’array NumPy numpy.ndarray. Dopo panda 0.24.0, si consiglia di utilizzare il metodo to_numpy() introdotto alla fine di questo articolo.

panda.DataFrame:

import numpy as np
import pandas as pd

df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c'])
print(df)
#    a  b  c
# 0  1  2  3
# 1  4  5  6

a_df = df.values
print(a_df)
# [[1 2 3]
#  [4 5 6]]

print(type(a_df))
# <class 'numpy.ndarray'>

print(a_df.dtype)
# int64

panda.Serie:

s = df['a']
print(s)
# 0    1
# 1    4
# Name: a, dtype: int64

a_s = s.values
print(a_s)
# [1 4]

print(type(a_s))
# <class 'numpy.ndarray'>

print(a_s.dtype)
# int64

Il tipo di dati dtype di numpy.ndarray è lo stesso di dtype dei pandas.DataFrame e pandas.Series originali.

df_f = pd.DataFrame([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])
print(df_f)
#      0    1    2
# 0  0.1  0.2  0.3
# 1  0.4  0.5  0.6

a_df_f = df_f.values
print(a_df_f)
# [[0.1 0.2 0.3]
#  [0.4 0.5 0.6]]

print(type(a_df_f))
# <class 'numpy.ndarray'>

print(a_df_f.dtype)
# float64

Pandas.DataFrame con una combinazione di numeri e stringhe inviandarray il cui dtype è oggetto.

df_multi = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df_multi)
#       name  age state  point
# 0    Alice   24    NY     64
# 1      Bob   42    CA     92
# 2  Charlie   18    CA     70
# 3     Dave   68    TX     70
# 4    Ellen   24    CA     88
# 5    Frank   30    NY     57

a_df_multi = df_multi.values
print(a_df_multi)
# [['Alice' 24 'NY' 64]
#  ['Bob' 42 'CA' 92]
#  ['Charlie' 18 'CA' 70]
#  ['Dave' 68 'TX' 70]
#  ['Ellen' 24 'CA' 88]
#  ['Frank' 30 'NY' 57]]

print(type(a_df_multi))
# <class 'numpy.ndarray'>

print(a_df_multi.dtype)
# object

Vedere l’articolo seguente per ulteriori informazioni sul tipo di oggetto di ndarray.

Se estra colonne e ottieni valori, puoi ottenere solo alcune colonne in ndarray. Vedere l’articolo seguente su come estrarre le colonne.

Se selezioni solo colonne numeriche, il tipo di ndarray sarà quel tipo invece di oggetto.

a_df_int = df_multi[['age', 'point']].values
print(a_df_int)
# [[24 64]
#  [42 92]
#  [18 70]
#  [68 70]
#  [24 88]
#  [30 57]]

print(type(a_df_int))
# <class 'numpy.ndarray'>

print(a_df_int.dtype)
# int64

Se vuoi trasporre, usa T.

print(a_df_int.T)
# [[24 42 18 68 24 30]
#  [64 92 70 70 88 57]]

Puoi anche estrarre solo determinati tipi di colonne. Ad esempio, se vuoi estrarre solo colonne int64, puoi scrivere:

a_df_int = df_multi.select_dtypes(include=int).values
print(a_df_int)
# [[24 64]
#  [42 92]
#  [18 70]
#  [68 70]
#  [24 88]
#  [30 57]]

print(type(a_df_int))
# <class 'numpy.ndarray'>

print(a_df_int.dtype)
# int64

Vedere l’articolo seguente per ulteriori informazioni sull’estrazione di colonne per dtype utilizzando select_dtypes().

Puoi anche estrarre righe/colonne in base alle loro etichette. Vedi il seguente articolo.

Nota che il pandas.DataFrame originale e il convertitonumpy.ndarray possono condividere la memoria e la modifica di uno può cambiare l’altro. Sarà più avanti.

Converti ndarray in DataFrame, Series

L’array NumPy numpy.ndarray può essere specificato come primo argomento dei costruttori pandas.DataFrame e pandas.Series. Come segui in seguito, numpy.ndarray e pandas.DataFrame generati, pandas.Series condividono la memoria.

panda.Serie()

Se non vengono specificati altri argomenti nel costruttore, sarà una serie del tipo ndarray originale.

import numpy as np
import pandas as pd

a = np.arange(4)
print(a)
# [0 1 2 3]

s = pd.Series(a)
print(s)
# 0    0
# 1    1
# 2    2
# 3    3
# dtype: int64

È possibile specificare indice, nome, dtype, ecc.

index = ['A', 'B', 'C', 'D']
name = 'sample'
s = pd.Series(data=a, index=index, name=name, dtype='float')
print(s)
# A    0.0
# B    1.0
# C    2.0
# D    3.0
# Name: sample, dtype: float64

Per ulteriori informazioni su tipo nei panda, vedere l’articolo seguente.

La specifica di un ndarray multidimensionale come dati nel costruttore Series genera un errore.

a = np.arange(12).reshape((4, 3))
print(a)
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

# s = pd.Series(a)
# print(s)
# Exception: Data must be 1-dimensional

È possibile selezionare righe o colonne di ndarray bidimensionali e convertirle in serie.

s = pd.Series(a[2])
print(s)
# 0    6
# 1    7
# 2    8
# dtype: int64

s = pd.Series(a.T[2])
print(s)
# 0     2
# 1     5
# 2     8
# 3    11
# dtype: int64

panda.DataFrame()

Come con Series, se non specifichi altri argomenti nel costruttore, ottieni un DataFrame del tipo ndarray originale.

a = np.arange(12).reshape((4, 3))
print(a)
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

df = pd.DataFrame(a)
print(df)
#    0   1   2
# 0  0   1   2
# 1  3   4   5
# 2  6   7   8
# 3  9  10  11

È possibile specificare indice, colonne, dtype, ecc.

index = ['A', 'B', 'C', 'D']
columns = ['a', 'b', 'c']
df = pd.DataFrame(data=a, index=index, columns=columns, dtype='float')
print(df)
#      a     b     c
# A  0.0   1.0   2.0
# B  3.0   4.0   5.0
# C  6.0   7.0   8.0
# D  9.0  10.0  11.0

Nota sulla condivisione della memoria (visualizza e copia)

pandas.DataFrame o pandas.Series e numpy.ndarray convertiti l’uno all’altro tramite l’attributo dei valori o il costruttore possono condividere la memoria. Se la memoria è condivisa, cambiandone una cambia l’altra. Fai attenzione se vuoi usarli separatamente.

Il codice di esempio ei seguenti risultati sono per Panda 0.25.1.

attributo valori

Innanzitutto, considera il caso seguente.

df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c'])
print(df)
#    a  b  c
# 0  1  2  3
# 1  4  5  6

a_values = df.values
print(a_values)
# [[1 2 3]
#  [4 5 6]]

valorizza una vista; uno cambia l’altro. Questo può essere verificato con np.shares_memory().

print(np.shares_memory(a_values, df))
# True

a_values[0, 0] = 100
print(a_values)
# [[100   2   3]
#  [  4   5   6]]

print(df)
#      a  b  c
# 0  100  2  3
# 1    4  5  6

Non sempre richiama una vista; ad esempio, se ogni colonna ha un tipo di dati diverso dtype, viene restituita una copia.

df_if = pd.DataFrame(data=[[1, 0.1], [2, 0.2]], columns=['int', 'float'])
print(df_if)
#    int  float
# 0    1    0.1
# 1    2    0.2

print(df_if.dtypes)
# int        int64
# float    float64
# dtype: object

a_values_if = df_if.values
print(a_values_if)
# [[1.  0.1]
#  [2.  0.2]]

print(np.shares_memory(a_values_if, df_if))
# False

a_values_if[0, 0] = 100
print(a_values_if)
# [[100.    0.1]
#  [  2.    0.2]]

print(df_if)
#    int  float
# 0    1    0.1
# 1    2    0.2

Inoltre, quando si seleziona un intervallo, la restituzione della vista o della copia dipende dal metodo di specifica.

print(df[['a', 'c']].values)
# [[100   3]
#  [  4   6]]

print(np.shares_memory(df[['a', 'c']].values, df))
# False

print(df.iloc[:, ::2].values)
# [[100   3]
#  [  4   6]]

print(np.shares_memory(df.iloc[:, ::2].values, df))
# True

Puoi creare manualmente una copia con copy() di valori.

a_values_copy = df.values.copy()
print(a_values_copy)
# [[100   2   3]
#  [  4   5   6]]

print(np.shares_memory(a_values_copy, df))
# False

a_values_copy[0, 0] = 10
print(a_values_copy)
# [[10  2  3]
#  [ 4  5  6]]

print(df)
#      a  b  c
# 0  100  2  3
# 1    4  5  6

pandas.DataFrame(), pandas.Series()

Passando numpy.ndarray al costruttore pandas.DataFrame() o pandas.Series(), due oggetti condivideranno la memoria. La modifica di un valore cambia l’altro.

a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
# [[1 2 3]
#  [4 5 6]]

df_a = pd.DataFrame(a, columns=['a', 'b', 'c'])
print(df_a)
#    a  b  c
# 0  1  2  3
# 1  4  5  6

print(np.shares_memory(a, df_a))
# True

a[0, 0] = 100
print(a)
# [[100   2   3]
#  [  4   5   6]]

print(df_a)
#      a  b  c
# 0  100  2  3
# 1    4  5  6

df_a.iat[1, 0] = 10
print(df_a)
#      a  b  c
# 0  100  2  3
# 1   10  5  6

print(a)
# [[100   2   3]
#  [ 10   5   6]]

Se non vuoi condividere la memoria, usa copy() di numpy.ndarray.

df_a_copy = pd.DataFrame(a.copy(), columns=['a', 'b', 'c'])
print(df_a_copy)
#      a  b  c
# 0  100  2  3
# 1   10  5  6

a[0, 0] = 1
print(a)
# [[ 1  2  3]
#  [10  5  6]]

print(df_a_copy)
#      a  b  c
# 0  100  2  3
# 1   10  5  6

panda 0.24.0 o successivo:to_numpy()

Il metodo to_numpy() è stato aggiunto a pandas.DataFrame e pandas.Series in pandas 0.24.0. Questo metodo produce numpy.ndarray, similitudine all’attributo valori di cui sopra.

La documentazione consiglia ufficiale di utilizzare il metodo to_numpy() invece dell’attributo values, ma a partire dalla versione 0.25.1, l’utilizzo dell’attributo values ​​​​non genera alcun avviso.

df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c'])
print(df)
#    a  b  c
# 0  1  2  3
# 1  4  5  6

a = df.to_numpy()
print(a)
# [[1 2 3]
#  [4 5 6]]

print(type(a))
# <class 'numpy.ndarray'>

Per impostazione predefinita, come l’attributo values, può restituire una vista (numpy.ndar che condivide la memoria).

print(np.shares_memory(df, a))
# True

a[0, 0] = 100
print(a)
# [[100   2   3]
#  [  4   5   6]]

print(df)
#      a  b  c
# 0  100  2  3
# 1    4  5  6

L’impostazione della copia su True riporta una copia. L’impostazione predefinita è copia=Falso.

a_copy = df.to_numpy(copy=True)
print(a_copy)
# [[100   2   3]
#  [  4   5   6]]

print(np.shares_memory(df, a_copy))
# False

a_copy[0, 0] = 10
print(a_copy)
# [[10  2  3]
#  [ 4  5  6]]

print(df)
#      a  b  c
# 0  100  2  3
# 1    4  5  6

L’impostazione predefinita (piuttosto che copy=False) può restituire una copia una vista. copy=Vero richiede sempre una copia, ma copy=Falso non richiede sempre una vista.

Se l’attributo valori restituisce una copia, anche to_numpy(copy=False) restituisce una copia.

a_cols = df[['a', 'c']].to_numpy()
print(a_cols)
# [[100   3]
#  [  4   6]]

print(np.shares_memory(df, a_cols))
# False

Il tipo di dati può essere specificato con il parametro dtype. Una copia viene restituita anche se il tipo di dati è cambiato.

a_f = df.to_numpy(dtype=float)
print(a_f)
# [[100.   2.   3.]
#  [  4.   5.   6.]]

print(np.shares_memory(df, a_f))
# False