pandas的数据类型转换

pandas的数据类型转换_第1张图片

当我们做数据分析时,确保自己使用的是正确的数据类型,这一点很重要。而在pandas中,一般情况下会根据我们导入的数据,自动分配最合适的数据类型。

但是有时候pandas也会犯错,这时候我们就需要diy自定义数据类型。本文主要将pandas的dtype,如何进行数据类型的操作。

pands数据类型

数据类型是编程语言的基础性概念,ta会告诉电脑如何存储数据、如何操作数据。

例如,当我们给程序两个数字,进行 5+10操作时, 程序要能理解这是两个整数,且知道整数是可以进行加法操作。

而当有两个字符串,进行 "cat"+"hat" 我们知道会得到 cathat 。

现在可能大家有点疑惑,python、pandas、numpy代表着数据分析领域三大数据类型门派,彼此会有重合,导致各位看官学杂学邪,走火入魔。我列一个表格,以作区分。

pandas的数据类型转换_第2张图片

本文主要学习pandas的:

  • object

  • int64

  • float64

  • datetime64

  • bool

为什么这么在意数据类型?

一般情况我们都不会去想数据类型问题,直到发现问题出现了。

import pandas as pd

import numpy as np

df = pd.read_csv('sales_data_types.csv')

df

pandas的数据类型转换_第3张图片

一打眼看这结果,我就发现一个问题。Customer number 应该是整数,不应该带有小数点(浮点型数字)。2016和2017是字符串,但是如果后续对2016和2017列进行数值计算,肯定不行,所以也应该转换成数字型数据。看来问题还是有不少对,那么我们看看所有字段的数据类型

df.dtypes
Customer Number float64

Customer Name object

2016 object

2017 object

Percent Growth object

Jan Units object

Month int64

Day int64

Year int64

Active object

dtype: object

数据中暴露的问题

现在我们可以总结下这个数据有哪些问题:

  • Customer number 应该是int64,不应该是float64

  • 2016和2017两个字段是object字符串,但我们应该将其转换为float64或者int64

  • Percent Growth 应该是数字,但是这里是object字符串

  • Year、Month、Day 三个字段应该合并为一个datetime类型的日期数据

  • Active应该是bool型数据

转换数据类型的思路

  • 使用astype()方法强制转化dtype

  • 自定义一个数据转换函数函数

  • 使用pandas内置的tonumeric()和todatetime()

  • 导入数据时转换数据类型

一、使用astype()方法

处理pandas数据类型最简单的办法是astype(),例如,我们将Customer Number 转为整数型数据。

df['Customer Number'].astype('int')
0 10002

1 552278

2 23477

3 24900

4 651029

Name: Customer Number, dtype: int64

为了将原始数据更改,我们需要进行原地操作,将处理结果更新到原始数据中

df['Customer Number'] = df['Customer Number'].astype('int')

df.dtypes
Customer Number int64

Customer Name object

2016 object

2017 object

Percent Growth object

Jan Units object

Month int64

Day int64

Year int64

Active object

dtype: object

现在我们再看看心的dataframe

df

pandas的数据类型转换_第4张图片

我们试着将 2016、2017、PercentGrowth、JanUnits列 从 字符串 转化为 数字

df['2016'].astype('int')

ValueError Traceback (most recent call last)in----> 1 df['2016'].astype('int') ... ValueError: invalid literal for int() with base 10: '$125,000.00'

同样的问题出现在2017、Percent Growth、Jan Units列, 说明astype这种方法不是万能的,还是需要设计自定义转换函数,具体问题具体处理。

二、自定义转换函数

这里我们以 2016和2017列为例,在强制从字符串转为数字之前,我们需要先将 "$"、"."、"," 剔除掉,然后再转换。

def convert_currency(val):

"""

将字符串val转为一个浮点型数值

- 移除 $

- 去掉 ','、 '.'

- 转为 浮点型数值

"""

new_val = val.replace(',', '').replace('$', '')

return float(new_val)

df['2016'] = df['2016'].apply(convert_currency)
df['2017'] = df['2017'].apply(convert_currency)

df

 

pandas的数据类型转换_第5张图片

可能有的人会说用 lambda 一行代码就能解决的事儿

#df['2016'] = df['2016'].apply(lambda x:x.replace('.', '').replace(',', '')).astype('float')

上面这一样确实能一行搞定,但是我不推荐,原因有:

  • 对于初学者不友好,你写的能看懂,但不代表其他人能看懂你的代码

  • 如果要处理的字段比较多,我们可以多次调用自定义函数。比如定义好以后,在2016和2017上调用

下面我们再用自定义方法处理 PercentGrowth 列

def convert_percent(val):

"""

将百分比字符串数据 转为 浮点型数值

- 移除 '%'

- 除以100

"""

new_val = val.replace('%', '')

return float(new_val)/100

df['Percent Growth'] = df['Percent Growth'].apply(convert_percent)

df['Percent Growth']

0 0.30

1 0.10

2 0.25

3 0.04

4 -0.15

Name: Percent Growth, dtype: float64

如果你还是想用lambda处理 PercentGrowth, 那么处理方法如下

#df['Percent Growth'] = df['Percent Growth'].apply(lambda x: x.replace('%', '')).astype('float')/100

最后我们要将 Active 从 Y、X 转为 True和False 

def convert_active(val):

if val=='Y':

return True

else:

return False

df['Active'] = df['Active'].apply(convert_active)

df['Active']
0 True

1 True

2 True

3 True

4 False

Name: Active, dtype: bool

这里我们不自定义函数,也可以用numpy中的np.where函数

np.where(condition, do1, do2)

如果condition满足条件,执行do1,否则执行do2

#df['Active'] = np.where(df['Active']=='Y', True, False)

#df['Active']

三、pandas内置的处理函数

pandas还有 pd.to_numeric(arg,errors='raise')和pd.to_datetime(arg,errors='raise') 函数帮助我们转为数据类型。

errors参数有:

  • raise, errors默认为raise

  • ignore 忽略错误

  • coerce 将错误数据标注为NaN

pd.to_numeric(df['Jan Units'], errors='coerce')
0 500.0

1 700.0

2 125.0

3 75.0

4 NaN

Name: Jan Units, dtype: float64

我们将处理结果中的NaN用0替代

df['Jan Units'] = pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)

df['Jan Units']
  1.  

0 500.0

1 700.0

2 125.0

3 75.0

4 0.0

Name: Jan Units, dtype: float64

最后一个要转换的是日期数据,我们要把 Year、Month、Day 三列数据 转化 为一个日期数据型新列

 
  1. df['Start_Date'] = pd.to_datetime(df[['Month', 'Day', 'Year']])

  2. df

pandas的数据类型转换_第6张图片

四、导入数据时转换数据类型

除了上面的三种方法,实际上我们也可以在导入数据的时候就处理好。

df2 = pd.read_csv("sales_data_types.csv",

dtype = {'Customer Number': 'int'},

converters={'2016': convert_currency,

'2017': convert_currency,

'Percent Growth': convert_percent,

'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),

'Active': lambda x: True if x=='Y' else False})

df2

pandas的数据类型转换_第7张图片

df2.dtypes
Customer Number int64

Customer Name object

2016 float64

2017 float64

Percent Growth float64

Jan Units float64

Month int64

Day int64

Year int64

Active bool

dtype: object

总结

做数据分析时,我们要确保数据类型是正常的,这要求我们导入数据后就要检查数据类型。

如果数据类型不满足我们的需求,需要转换数据类型,思路有

  • 使用astype()方法强制转化dtype

  • 自定义一个数据转换函数函数

  • 使用pandas内置的tonumeric()和todatetime()

  • 导入数据时转换数据类型

你可能感兴趣的:(Pandas)