分配pandasdataframe列dtypes
我想在pd.Dataframe
设置多列的pd.Dataframe
s(我有一个文件,我不得不手动parsing到列表的列表中,因为该文件不适合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
我可以设置它们的唯一方法是循环遍历每个列variables并用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
有没有更好的办法?
你可以使用convert_objects
来推断更好的dtypes:
In [11]: df Out[11]: xy 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]: xy 0 a 1 1 b 2 In [14]: df.convert_objects(convert_numeric=True).dtypes Out[14]: x object y int64 dtype: object
魔法!
对于那些来自Google(等)的人,比如我自己:
convert_objects
已被弃用 – 如果你使用它,你会得到像这样的警告:
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"])
您可以使用pandas DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)
显式设置typesDataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs)
其传入带有您想要的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
另一种设置列types的方法是首先用你想要的types构造一个numpylogging数组,然后填充它,然后把它传递给一个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日志的文件,我需要手动parsing。
为了灵活使用字段和types,我已经成功使用StringIO + read_cvs进行了testing,确实可以接受dtype规范的字典。
我通常将每个文件(5k-20k行)放入一个缓冲区,dynamic创builddtype字典。
最后,我将这些dataframe连接到一个大型的数据框中,并将其转换为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 ….但是做这个工作
希望能帮助到你。
JC