Назначить панды DataFrame столбец dtypes
Я хочу, чтобы dtype
s из нескольких столбцов в pd.Dataframe
(у меня есть файл, который мне пришлось вручную разобрать в список списков, так как файл не поддается pd.read_csv
)
import pandas as pd
print pd.DataFrame([['a','1'],['b','2']],
dtype={'x':'object','y':'int'},
columns=['x','y'])
Я
ValueError: entry not a 2- or 3- tuple
единственный способ, которым я могу установить их, - это перебирать каждую переменную столбца и переделывать с помощью 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
есть ли лучший способ?
6 ответов:
начиная с 0.17, вы должны использовать явные преобразования:
pd.to_datetime, pd.to_timedelta and pd.to_numeric
(как уже упоминалось ниже, больше никакой "магии",
convert_objects
был осужден в 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
вы можете применить их к каждому столбцу, который вы хотите преобразовать:
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
и подтвердите обновление dtype.
старый / устаревший ответ для панд 0.12-0.16: вы можете использовать
convert_objects
чтобы сделать вывод лучше 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
магия! (Грустно видеть, что он устарел.)
для тех, кто прибывает из Google (и др.) таких как я:
convert_objects
был осужден с 0.17 - если вы используете его, вы получите предупреждение, как этот:FutureWarning: convert_objects is deprecated. Use the data-type specific converters pd.to_datetime, pd.to_timedelta and pd.to_numeric.
вы должны сделать что-то вроде следующего:
df =
df.astype(np.float)
df["A"] =
pd.to_numeric(df["A"])
вы можете установить типы явно с пандами
DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)
и передать в словарь с dtypes вы хотитеdtype
вот пример:
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"})
теперь вы можете видеть, что он изменился
In [18]: data_df.dtypes Out[18]: wheel_number int64 car_name object minutes_spent float64
другой способ установить типы столбцов-это сначала построить массив записей numpy с нужными типами, заполнить его и затем передать его конструктору 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
столкнувшись с подобной проблемой для вас. В моем случае у меня есть 1000 файлов из журналов cisco, которые мне нужно разобрать вручную.
чтобы быть гибким с полями и типами, я успешно протестировал с помощью StringIO + read_cvs, который действительно принимает dict для спецификации dtype.
Я обычно получаю каждый из файлов (5K-20k строк) в буфер и динамически создаю словари dtype.
В конце концов я объединяю (с категорическим... спасибо до 0.19) эти фреймы данных в большой фрейм данных, который я сбрасываю в hdf5.
что-то в этом роде
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
Не очень подходящие для Python.... но не работает
надеюсь, что это помогает.
JC
вам лучше использовать типизированный np.массивы, а затем передать данные и имена столбцов в виде словаря.
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, } )