python - para - recorrer data frame pandas
Asignar dtypes de columna de datos de pandas (6)
Desde 0.17, debe usar las conversiones explícitas:
pd.to_datetime, pd.to_timedelta and pd.to_numeric
(Como se menciona a continuación, no más "magic", convert_objects
ha quedado obsoleto en 0.17)
df = pd.DataFrame({''x'': {0: ''a'', 1: ''b''}, ''y'': {0: ''1'', 1: ''2''}, ''z'': {0: ''2018-05-01'', 1: ''2018-05-02''}})
df.dtypes
x object
y object
z object
dtype: object
df
x y z
0 a 1 2018-05-01
1 b 2 2018-05-02
Puede aplicarlos a cada columna que desee convertir:
df["y"] = pd.to_numeric(df["y"])
df["z"] = pd.to_datetime(df["z"])
df
x y z
0 a 1 2018-05-01
1 b 2 2018-05-02
df.dtypes
x object
y int64
z datetime64[ns]
dtype: object
y confirmar que el tipo está actualizado.
RESPUESTA ANTERIOR / DEPRECATED para pandas 0.12 - 0.16: puede usar convert_objects
para inferir mejores dtypes:
In [21]: df
Out[21]:
x y
0 a 1
1 b 2
In [22]: df.dtypes
Out[22]:
x object
y object
dtype: object
In [23]: df.convert_objects(convert_numeric=True)
Out[23]:
x y
0 a 1
1 b 2
In [24]: df.convert_objects(convert_numeric=True).dtypes
Out[24]:
x object
y int64
dtype: object
¡Magia! (Es triste ver que está en desuso).
Quiero establecer los dtype
de columnas múltiples en pd.Dataframe
(tengo un archivo que he tenido que analizar manualmente en una lista de listas, ya que el archivo no era pd.read_csv
para pd.read_csv
)
import pandas as pd
print pd.DataFrame([[''a'',''1''],[''b'',''2'']],
dtype={''x'':''object'',''y'':''int''},
columns=[''x'',''y''])
yo obtengo
ValueError: entry not a 2- or 3- tuple
La única forma en que puedo configurarlos es recorriendo cada variable de la columna y astype
con astype
.
dtypes = {''x'':''object'',''y'':''int''}
mydata = pd.DataFrame([[''a'',''1''],[''b'',''2'']],
columns=[''x'',''y''])
for c in mydata.columns:
mydata[c] = mydata[c].astype(dtypes[c])
print mydata[''y''].dtype #=> int64
¿Hay una mejor manera?
Es mejor que use np.arrays tipeados, y luego pase los nombres de datos y columnas como un diccionario.
import numpy as np
import pandas as pd
# Feature: np arrays are 1: efficient, 2: can be pre-sized
x = np.array([''a'', ''b''], dtype=object)
y = np.array([ 1 , 2 ], dtype=np.int32)
df = pd.DataFrame({
''x'' : x, # Feature: column name is near data array
''y'' : y,
}
)
Otra forma de establecer los tipos de columna es construir primero una matriz de registros numpy con los tipos que desee, llenarla y luego pasarla a un constructor de DataFrame.
import pandas as pd
import numpy as np
x = np.empty((10,), dtype=[(''x'', np.uint8), (''y'', np.float64)])
df = pd.DataFrame(x)
df.dtypes ->
x uint8
y float64
Para aquellos que vienen de Google (etc.) como yo:
convert_objects
ha quedado en desuso desde 0.17; si lo usas, recibes una advertencia como esta:
FutureWarning: convert_objects is deprecated. Use the data-type specific converters
pd.to_datetime, pd.to_timedelta and pd.to_numeric.
Deberías hacer algo como lo siguiente:
-
df =
df.astype(np.float)
-
df["A"] =
pd.to_numeric(df["A"])
enfrentando un problema similar para ti. En mi caso, tengo miles de archivos de registros de Cisco que necesito analizar manualmente.
Para ser flexible con campos y tipos, he probado con éxito utilizando StringIO + read_cvs, que de hecho acepta un dict para la especificación dtype.
Normalmente obtengo cada uno de los archivos (5k-20k líneas) en un búfer y creo los diccionarios de tipo de forma dinámica.
Eventualmente concateno (con categorías ... gracias a 0.19) estos dataframes en un marco de datos grande que vuelvo a hdf5.
Algo en esta línea
import pandas as pd
import io
output = io.StringIO()
output.write(''A,1,20,31/n'')
output.write(''B,2,21,32/n'')
output.write(''C,3,22,33/n'')
output.write(''D,4,23,34/n'')
output.seek(0)
df=pd.read_csv(output, header=None,
names=["A","B","C","D"],
dtype={"A":"category","B":"float32","C":"int32","D":"float64"},
sep=","
)
df.info()
<class ''pandas.core.frame.DataFrame''>
RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
A 5 non-null category
B 5 non-null float32
C 5 non-null int32
D 5 non-null float64
dtypes: category(1), float32(1), float64(1), int32(1)
memory usage: 205.0 bytes
None
No muy pitónico ... pero hace el trabajo
Espero eso ayude.
JC
puede establecer los tipos explícitamente con pandas DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)
y pasar en un diccionario con los dtypes que desee dtype
he aquí un ejemplo:
import pandas as pd
wheel_number = 5
car_name = ''jeep''
minutes_spent = 4.5
# set the columns
data_columns = [''wheel_number'', ''car_name'', ''minutes_spent'']
# create an empty dataframe
data_df = pd.DataFrame(columns = data_columns)
df_temp = pd.DataFrame([[wheel_number, car_name, minutes_spent]],columns = data_columns)
data_df = data_df.append(df_temp, ignore_index=True)
In [11]: data_df.dtypes
Out[11]:
wheel_number float64
car_name object
minutes_spent float64
dtype: object
data_df = data_df.astype(dtype= {"wheel_number":"int64",
"car_name":"object","minutes_spent":"float64"})
ahora puedes ver que ha cambiado
In [18]: data_df.dtypes
Out[18]:
wheel_number int64
car_name object
minutes_spent float64