Pandas实现数据类型转换的一些小技巧汇总
目录
前言
有关 Pandas 数据类型的一个可能令人困惑的地方是,Pandas、Python 和 numpy 的数据类型之间有一些重叠。
大多数情况下,你不必担心是否应该明确地将熊猫类型强制转换为对应的 NumPy 类型。一般来说使用 Pandas 的默认 int64 和 float64 就可以。我列出此表的唯一原因是,有时你可能会在代码行间或自己的分析过程中看到 Numpy 的类型。
Pandas、Numpy、Python支持的数据类型
从上述表格中可以看出Pandas支持的数据类型最为丰富,在某种情形下Numpy的数据类型可以和Pandas的数据类型相互转化,毕竟Pandas库是在Numpy的基础之上开发的的。
示例
import numpy as np
import pandas
from pandas import Series,DataFrame
data=pd.read_csv(r"E:\data.csv")
data
#查看数据信息
data.info()
Pandas中进行数据类型转换有三种基本方法:
- 使用astype()函数进行强制类型转换
- 自定义函数进行数据类型转换
- 使用Pandas提供的函数如to_numeric()、to_datetime()
使用astype()函数进行类型转换
对数据列进行数据类型转换最简单的方法就是使用astype()函数
# 原客户编号是int64,对原始数据进行转换并覆盖原始数据列
data['客户编号'] = data['客户编号'].astype('object')
data['客户编号']
'''
0 45646456
1 87676555
2 33456543
3 34454342
4 34546754
5 54657645
Name: 客户编号, dtype: object
'''
上面的结果看起来很不错,接下来给出几个astype()函数作用于列数据但失效的例子
data['2016'].astype('float')
报错如下:
data['所属组'].astype('int')
又报错了(因为这一列有ErrorValue):
从上面两个例子可以看出,当待转换列中含有不能转换的特殊值时(例子中¥,ErrorValue等)astype()函数将失效。有些时候astype()函数执行成功了也并不一定代表着执行结果符合预期(神坑!)
data['状态'].astype('bool')
'''
0 True
1 True
2 True
3 True
4 True
5 True
Name: 状态, dtype: bool
'''
乍一看,结果看起来不错,但仔细观察后,会发现一个大问题。那就是所有的值都被替换为True了,但是该列中包含好几个N标志,所以astype()函数在该列也是失效的。
总结一下astype()函数有效的情形:
- 数据列中的每一个单位都能简单的解释为数字(2, 2.12等)
- 数据列中的每一个单位都是数值类型且向字符串object类型转换
如果数据中含有缺失值、特殊字符astype()函数可能失效。
使用自定义函数转换数据类型
该方法特别适用于待转换数据列的数据较为复杂的情形,可以通过构建一个函数应用于数据列的每一个数据,并将其转换为适合的数据类型。
对于上述数据中的货币,需要将它转换为float类型,因此可以写一个转换函数:
# 转换字符,串数字为float类型,- 移除 ¥ ,- 转化为float类型
def convert_currency(value):
new_value = value.replace(',', '').replace('¥', '')
return np.float(new_value)
现在可以使用Pandas的apply函数通过covert_currency函数应用于2016列中的所有数据中。
data['2016'].apply(convert_currency)
'''
0 125000.0
1 987000.0
2 90000.0
3 350000.0
4 15000.0
5 14000.0
Name: 2016, dtype: float64
'''
还可以使用匿名函数一行代码实现:
data['2016'].apply(lambda x:x.replace(',','').replace('¥','')).astype('float')
当函数需要重复应用于多个列时,个人推荐使用第一种方法,先定义函数还有一个好处就是可以搭配read_csv()函数使用。
#2016 2017转换的完成代码
data['2016'].apply(convert_currency)
data['2017'].apply(convert_currency)
同样的方法用于增长率:
#同样的方法用于增长率:去掉%,然后除以100
def convert_percent(value):
new_value=value.replace('%','')
return float(new_value)/100
data['增长率'].apply(convert_percent)
'''
0 0.3000
1 0.0253
2 0.2222
3 -0.1701
4 0.3333
5 0.8571
Name: 增长率, dtype: float64
'''
使用匿名函数lambda表达式:
data['增长率'].apply(lambda x:x.replace('%','')).astype(float)/100
为了转换状态列,可以使用numpy中的where函数,把值为Y的映射成True,其他值全部映射成False .
data['状态']=np.where(data['状态'] == 'Y',True,False)
利用Pandas的一些辅助函数进行类型转换
Pandas的一些辅助函数,介于pandas的astype()和复杂的自定义函数之间。这些辅助函数对于某些特定数据类型的转换非常有用(如to_numeric()、to_datetime())。所属组数据列中包含一个非数值,用astype()转换出现了错误,然而用to_numeric()函数处理就好很多。
pd.to_numeric(data['所属组'],errors='coerce').fillna(0)
可以看到,非数值被替换成0.0了,当然这个填充值是可以选择的,具体文档见
pandas.to_numeric - pandas 0.22.0 documentation
Pandas中的to_datetime()函数可以把单独的year、month、day三列合并成一个单独的时间戳。
(**to_datetime()里的列名必须是英文的day month year,汉字不可以的,会报错,同时要注意源文件中每个字段前后没有空格,不然会报错:not in index/columns.)
pd.to_datetime(data[['day','month','year']])
'''
0 2015-10-12
1 2014-05-26
2 2016-06-23
3 2017-05-10
4 2014-05-12
5 2014-05-24
dtype: datetime64[ns]
'''
整个处理完的数据如下:
还有一个简便方法,在读取数据的时候就进行转换,一步到位:
参考 https://www.jb51.net/article/139630.htm
本文地址:https://blog.csdn.net/Doris2016/article/details/107639434
上一篇: 阿呆的几条搞笑短信
下一篇: 幽默短信,很搞笑的~.