分配pandas dataframe列dtypes

hat*_*rix 94 python pandas

我想设置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'])
Run Code Online (Sandbox Code Playgroud)

我明白了

ValueError: entry not a 2- or 3- tuple
Run Code Online (Sandbox Code Playgroud)

我可以设置它们的唯一方法是循环遍历每个列变量并重铸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
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Jac*_*tes 59

对于那些来自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.
Run Code Online (Sandbox Code Playgroud)

您应该执行以下操作:


And*_*den 55

从0.17开始,您必须使用显式转换:

pd.to_datetime, pd.to_timedelta and pd.to_numeric
Run Code Online (Sandbox Code Playgroud)

(如下所述,不再有"魔法",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
Run Code Online (Sandbox Code Playgroud)

您可以将这些应用于要转换的每列:

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
Run Code Online (Sandbox Code Playgroud)

并确认dtype已更新.


pandas的旧/弃用答案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
Run Code Online (Sandbox Code Playgroud)

魔法!(很遗憾看到它被弃用了.)

  • 我注意到`convert_objects()`已经被弃用了...我不知道是什么取代了它? (18认同)
  • 要重新推断对象列的数据dtypes,请使用DataFrame.infer_objects() (5认同)
  • 像R中的`type.convert`一样; 很好,但确实留下一些希望在某些情况下明确的规格. (2认同)

Lau*_*ren 35

您可以使用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"})
Run Code Online (Sandbox Code Playgroud)

现在你可以看到它已经改变了

In [18]: data_df.dtypes
Out[18]:
wheel_number       int64
car_name          object
minutes_spent    float64
Run Code Online (Sandbox Code Playgroud)


Kau*_*ose 11

设置列类型的另一种方式是先构造一个numpy的记录阵列成你想要的类型,填好,然后将它传递给一个数据帧的构造.

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
Run Code Online (Sandbox Code Playgroud)


Cle*_*ang 7

您最好使用类型化的 np.arrays,然后将数据和列名称作为字典传递。

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,
   }
 )
Run Code Online (Sandbox Code Playgroud)