Назначить pandas datpes столбца dataframe
Я хочу установить dtype
из нескольких столбцов в 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
Есть ли лучший способ?
Ответы
Ответ 1
Вы можете использовать convert_objects
для вывода более качественных типов:
In [11]: df
Out[11]:
x y
0 a 1
1 b 2
In [12]: df.dtypes
Out[12]:
x object
y object
dtype: object
In [13]: df.convert_objects(convert_numeric=True)
Out[13]:
x y
0 a 1
1 b 2
In [14]: df.convert_objects(convert_numeric=True).dtypes
Out[14]:
x object
y int64
dtype: object
Магия!
Ответ 2
Для тех, кто приходит от Google (и т.д.), например, я:
convert_objects
устарел - если вы его используете, вы получите предупреждение, подобное этому:
FutureWarning: convert_objects is deprecated. Use the data-type specific converters
pd.to_datetime, pd.to_timedelta and pd.to_numeric.
Вы должны сделать что-то вроде следующего:
Ответ 3
вы можете явно установить типы с помощью pandas 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
Ответ 4
Другой способ установить типы столбцов - сначала создать массив записей 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
Ответ 5
сталкивается с аналогичной проблемой для вас. В моем случае у меня есть 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
Не очень pythonic.... но делает работу
Надеюсь, что это поможет.
х