如何在pandas DataFrame中按列设置数据类型

56 投票
6 回答
54273 浏览
提问于 2025-04-19 06:11

我想把一些数据导入到一个叫做pandas的表格工具中,并且在导入的时候为每一列指定数据类型。这样做是为了处理一些比较大的数据集,里面有很多不同的列。不过,举个例子来说:

myarray = np.random.randint(0,5,size=(2,2))
mydf = pd.DataFrame(myarray,columns=['a','b'], dtype=[float,int])
mydf.dtypes

结果是:

类型错误:数据类型无法理解

我试过其他几种方法,比如:

mydf = pd.DataFrame(myarray,columns=['a','b'], dtype={'a': int})

类型错误:类型为'type'的对象没有长度

如果我写 dtype=(float,int),那么这两列都会被当作浮点数格式处理。

最后,我希望能像传递列名那样,直接传递一个数据类型的列表。

6 个回答

0

在最近版本的pandas(现在是2.X版本)中,有一个解决方案是可以给DataFrame.astype()传递一个字典,这个字典的键是列名,值是该列应该是什么类型。

其他评论和回答提到,在以前的版本中这是不可能的,但在2.X版本中至少可以做到这一点。

df = pd.DataFrame(
    {'some_ints': [1, 2, 3], 'some_strs': ['a', 'b', 'c']},
    dtype={'some_ints': 'str', 'some_strs': 'str'}
)

df.dtypes.to_dict()

>>> {'some_ints': dtype('O'), 'some_strs': dtype('O')}

df = df.astype({'some_ints': 'int64', 'some_strs': 'str'})

df.dtypes.to_dict()

>>> {'some_ints': dtype('int64'), 'some_strs': dtype('O')}

另一个小技巧是,如果你把可能导致类型转换的操作连在一起,可以在df.dtypes.to_dict()的输出上调用.astype

举个例子:

df = (
    df
    .some_type_changing_method()
    .astype(df.dtypes.to_dict()
)

这样可以确保在连锁操作的开始和结束时,你的数据类型是匹配的,或者如果类型无法转换(比如把nans转换成整数),就会报错。

3

在Pandas 1.5.3版本中,可以明确指定数据类型:

import pandas as pd
data = (['Alex', 10],["Bob",12],["Clarke",11.05])
df = pd.DataFrame(data,columns=("Name", "Age"),dtype=(str, float))
print(df)
14

你可以试着把一组Series对象放进DataFrame的构造函数里,这样你就能更具体地控制创建过程,而且应该能更清楚地理解发生了什么。下面是一个模板版本(data1可以是一个数组等等):

df = pd.DataFrame({'column1':pd.Series(data1, dtype='type1'),
                   'column2':pd.Series(data2, dtype='type2')})

这里是一个带数据的例子:

df = pd.DataFrame({'A':pd.Series([1,2,3], dtype='int'),
                   'B':pd.Series([7,8,9], dtype='float')})

print (df)
   A  B
0  1  7.0
1  2  8.0
2  3  9.0

print (df.dtypes)
A     int32
B    float64
dtype: object
29

我刚遇到这个问题,而pandas的问题还没有解决,所以我想分享一下我的解决方法。假设df是我的数据框(DataFrame),而dtype是一个字典,用来把列名和数据类型对应起来:

for k, v in dtype.items():
    df[k] = df[k].astype(v)

(注意:在Python 2中使用dtype.iteritems()

供参考:

11

截至pandas的版本0.24.2(目前的稳定版本),你不能直接给DataFrame构造函数传递一个明确的数据类型列表,文档中是这么说明的:

dtype : dtype, default None

    Data type to force. Only a single dtype is allowed. If None, infer

不过,dataframe类有一个静态方法,可以让你把一个numpy的结构化数组转换成dataframe,所以你可以这样做:

>>> myarray = np.random.randint(0,5,size=(2,2))
>>> record = np.array(map(tuple,myarray),dtype=[('a',np.float),('b',np.int)])
>>> mydf = pd.DataFrame.from_records(record)
>>> mydf.dtypes
a    float64
b      int64
dtype: object

撰写回答