好的,各位观众老爷们,欢迎来到今天的《数据类型强制转换与错误处理奇遇记》!我是你们的老朋友,数据界的老司机,今天就带大家一起闯荡一下 pd.to_numeric
和 pd.to_datetime
这两个数据转换界的“变形金刚”。
开场白:数据类型,你搞清楚了吗?
在数据分析的世界里,数据类型就像人的性格,千奇百怪,各有所长。有憨厚的整数型(int
),有精打细算的浮点型(float
),还有能说会道的字符串型(str
)。但有时候,数据就像个叛逆期的孩子,明明应该是个数字,非要伪装成字符串,让我们头疼不已。
举个栗子 🌰:
你从一个CSV文件中读取了一列数据,本以为是价格,结果打印出来一看,全是字符串!这就像你满怀期待地打开一个礼物盒,结果发现里面装的是袜子一样令人失望。
import pandas as pd
data = {'价格': ['100', '200', '300.5', '400.25']}
df = pd.DataFrame(data)
print(df['价格'].dtype) # 输出:object (在Pandas中,object 通常代表字符串)
这时候,我们就需要请出我们今天的两位主角:pd.to_numeric
和 pd.to_datetime
,让他们来“拨乱反正”,把这些叛逆的数据类型转换成我们需要的样子。
第一幕:pd.to_numeric
——数字变形记
pd.to_numeric
,顾名思义,就是把数据转换成数值类型的。它就像一个魔法棒,能把字符串、甚至是混合类型的数据,变成整数或浮点数。
1. 基本用法:简单粗暴,一步到位
最简单的用法就是直接把要转换的 Series 或 DataFrame 列丢给它:
import pandas as pd
data = {'价格': ['100', '200', '300.5', '400.25']}
df = pd.DataFrame(data)
df['价格'] = pd.to_numeric(df['价格'])
print(df['价格'].dtype) # 输出:float64
print(df['价格'])
看,字符串变成了浮点数,是不是很神奇?
2. errors
参数:错误处理的艺术
但是,现实往往比理想更骨感。如果你的数据里混入了一些不能转换成数字的“捣蛋分子”,比如字母、符号等等,pd.to_numeric
就会毫不留情地报错。
data = {'价格': ['100', '200', '300.5', 'abc']}
df = pd.DataFrame(data)
# df['价格'] = pd.to_numeric(df['价格']) # 这行代码会报错!
这时候,errors
参数就派上用场了。它有三个选项:
'raise'
(默认值):遇到错误直接报错,毫不留情。'coerce'
:遇到错误,把不能转换的值变成NaN
(Not a Number),也就是缺失值。'ignore'
:遇到错误,忽略它,保持原来的数据类型不变。
让我们来试试 'coerce'
:
import pandas as pd
data = {'价格': ['100', '200', '300.5', 'abc']}
df = pd.DataFrame(data)
df['价格'] = pd.to_numeric(df['价格'], errors='coerce')
print(df['价格'].dtype) # 输出:float64
print(df['价格'])
看到没,'abc'
变成了 NaN
。
'ignore'
就像一个鸵鸟,把头埋在沙子里,眼不见为净:
import pandas as pd
data = {'价格': ['100', '200', '300.5', 'abc']}
df = pd.DataFrame(data)
df['价格'] = pd.to_numeric(df['价格'], errors='ignore')
print(df['价格'].dtype) # 输出:object
print(df['价格'])
'abc'
依然是 'abc'
,世界还是那个世界,只是我们选择了视而不见。
3. downcast
参数:节约内存,从我做起
downcast
参数可以帮助我们把数值类型转换成更小的类型,从而节省内存空间。它有四个选项:
'integer'
:尝试把数据转换成最小的整数类型(int8
,int16
,int32
,int64
)。'signed'
:与'integer'
类似,但只考虑有符号整数。'unsigned'
:与'integer'
类似,但只考虑无符号整数。'float'
:尝试把数据转换成最小的浮点数类型(float32
,float64
)。
举个栗子:
import pandas as pd
data = {'数量': ['10', '20', '30', '40']}
df = pd.DataFrame(data)
df['数量'] = pd.to_numeric(df['数量'], downcast='integer')
print(df['数量'].dtype) # 输出:int8 (取决于数据范围)
print(df['数量'])
如果数据范围比较小,比如都在 -128 到 127 之间,那么就会被转换成 int8
,大大节省了内存。
表格总结 pd.to_numeric
:
参数 | 作用 |
---|---|
errors |
指定错误处理方式:'raise' (默认), 'coerce' , 'ignore' |
downcast |
指定数值类型转换成更小的类型,节省内存:'integer' , 'signed' , 'unsigned' , 'float' |
第二幕:pd.to_datetime
——时间旅行者的指南
pd.to_datetime
,顾名思义,就是把数据转换成日期时间类型的。它就像一个时间机器,能把各种各样的日期时间格式,变成统一的 datetime64
类型。
1. 基本用法:化腐朽为神奇
最简单的用法:
import pandas as pd
dates = ['2023-10-26', '2023/10/27', '10/28/2023']
dates_series = pd.Series(dates)
dates_series = pd.to_datetime(dates_series)
print(dates_series.dtype) # 输出:datetime64[ns]
print(dates_series)
看到了吗?不管是 'YYYY-MM-DD'
还是 'YYYY/MM/DD'
,甚至是 'MM/DD/YYYY'
,pd.to_datetime
都能识别出来,并转换成统一的格式。
2. format
参数:指定日期时间格式
但有时候,pd.to_datetime
也不是万能的。如果你的日期时间格式太奇葩,它可能就认不出来了。这时候,就需要 format
参数来帮忙了。
format
参数可以指定日期时间的格式,让 pd.to_datetime
知道该怎么解析。
举个栗子:
import pandas as pd
dates = ['26-10-2023', '27-10-2023', '28-10-2023'] # DD-MM-YYYY 格式
dates_series = pd.Series(dates)
dates_series = pd.to_datetime(dates_series, format='%d-%m-%Y')
print(dates_series)
'%d'
表示日,'%m'
表示月,'%Y'
表示年(四位数)。
常用的格式代码:
%Y
: 年(四位数)%y
: 年(两位数)%m
: 月(01-12)%d
: 日(01-31)%H
: 时(00-23)%M
: 分(00-59)%S
: 秒(00-59)
3. errors
参数:错误处理,似曾相识
pd.to_datetime
也有 errors
参数,作用和 pd.to_numeric
类似:
'raise'
(默认值):遇到错误直接报错。'coerce'
:遇到错误,把不能转换的值变成NaT
(Not a Time),也就是时间类型的缺失值。'ignore'
:遇到错误,忽略它,保持原来的数据类型不变。
import pandas as pd
dates = ['2023-10-26', 'abc', '2023-10-28']
dates_series = pd.Series(dates)
dates_series = pd.to_datetime(dates_series, errors='coerce')
print(dates_series)
'abc'
变成了 NaT
。
4. origin
和 unit
参数:从数字到时间
有时候,日期时间不是以字符串的形式存在,而是以数字的形式存在,比如 Unix 时间戳。这时候,我们可以用 origin
和 unit
参数来把数字转换成日期时间。
origin
参数指定起始时间,unit
参数指定数字的单位。
举个栗子:
import pandas as pd
timestamps = [1698307200, 1698393600, 1698480000] # Unix 时间戳 (秒)
timestamps_series = pd.Series(timestamps)
dates_series = pd.to_datetime(timestamps_series, unit='s', origin='1970-01-01')
print(dates_series)
'1970-01-01'
是 Unix 时间戳的起始时间,'s'
表示单位是秒。
表格总结 pd.to_datetime
:
参数 | 作用 |
---|---|
format |
指定日期时间的格式,让 pd.to_datetime 知道该怎么解析 |
errors |
指定错误处理方式:'raise' (默认), 'coerce' , 'ignore' |
origin |
指定起始时间,用于把数字转换成日期时间 |
unit |
指定数字的单位,用于把数字转换成日期时间,例如 's' (秒), 'ms' (毫秒), 'us' (微秒), 'ns' (纳秒) |
第三幕:实战演练——数据清洗小技巧
光说不练假把式,让我们来一个实战演练,看看如何用 pd.to_numeric
和 pd.to_datetime
来清洗数据。
假设我们有一个包含销售数据的 DataFrame:
import pandas as pd
data = {'日期': ['2023-10-26', '2023/10/27', '10/28/2023', '2023-10-29'],
'商品': ['A', 'B', 'C', 'D'],
'价格': ['100', '200', '300.5', 'abc'],
'数量': ['10', '20', '30', '40']}
df = pd.DataFrame(data)
print(df)
print(df.dtypes)
数据类型有点乱,我们需要做以下几步:
- 把
'日期'
列转换成datetime64
类型。 - 把
'价格'
列转换成float64
类型,遇到错误变成NaN
。 - 把
'数量'
列转换成int32
类型。 - 把
NaN
值填充为 0。
代码如下:
import pandas as pd
import numpy as np
data = {'日期': ['2023-10-26', '2023/10/27', '10/28/2023', '2023-10-29'],
'商品': ['A', 'B', 'C', 'D'],
'价格': ['100', '200', '300.5', 'abc'],
'数量': ['10', '20', '30', '40']}
df = pd.DataFrame(data)
# 1. 转换日期
df['日期'] = pd.to_datetime(df['日期'])
# 2. 转换价格
df['价格'] = pd.to_numeric(df['价格'], errors='coerce')
# 3. 转换数量
df['数量'] = pd.to_numeric(df['数量'], downcast='integer')
# 4. 填充 NaN 值
df.fillna(0, inplace=True)
print(df)
print(df.dtypes)
看,数据是不是变得干净多了?
结语:数据类型转换,任重道远
数据类型转换是数据分析中必不可少的一步,pd.to_numeric
和 pd.to_datetime
是我们手中的利器。掌握了它们,就能轻松应对各种奇葩的数据类型,让数据分析工作事半功倍。
当然,数据类型转换不是一蹴而就的,需要我们不断学习、实践、总结。希望今天的分享能对大家有所帮助。
记住,数据分析的世界,永远充满惊喜和挑战!
最后的彩蛋:
大家可以思考一下,如果你的数据中包含了中文字符,比如 '一千'
、'两百'
,如何转换成数字呢? 欢迎在评论区留言,分享你的想法! 让我们一起进步,共同成长! 🚀