Pandas 数据类型

Pandas 数据类型概览

简介

在进行数据分析时,确保使用正确的数据类型非常重要,否则可能会得到意想不到的结果或错误。对 Pandas 而言,它会在很多情况下正确地作出数据类型推断,你可以继续进行分析工作,而无需深入思考该主题。

尽管 Pandas 工作得很好,但在数据分析过程中的某个时刻,你可能需要将数据从一种类型显式转换为另一种类型。本文将讨论 Pandas 的基本数据类型(即 dtypes),它们如何映射到 python numpy 数据类型,以及从一种 Pandas 类型转换为另一种类型的几个方式。

Pandas 的数据类型

数据类型本质上是编程语言用来理解如何存储和操作数据的内部结构。例如,一个程序需要理解你可以将两个数字加起来,比如 5 + 10 得到 15。或者,如果是两个字符串,比如「cat」和「hat」,你可以将它们连接(加)起来得到「cathat」。

有关 Pandas 数据类型的一个可能令人困惑的地方是,PandasPython numpy 的数据类型之间有一些重叠。下表总结了关键点:

Pandas dtype 映射:

Pandas dtype

Python 类型

NumPy 类型

用途

object

str

string, unicode

文本

int64

int

int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64

整数

float64

float

float_, float16, float32, float64

浮点数

bool

bool

bool_

布尔值

datetime64

NA

NA

日期时间

timedelta[ns]

NA

NA

时间差

category

NA

NA

有限长度的文本值列表

大多数情况下,你不必担心是否应该明确地将pandas类型强制转换为对应的 NumPy 类型。一般来说使用 Pandas 的默认 int64  float64 就可以。列出此表的唯一原因是,有时你可能会在代码行间或自己的分析过程中看到 Numpy 的类型。

对于本文,我将重点关注以下 Pandas 类型:

  • object
  • int64
  • float64
  • datetime64
  • bool

如果你有兴趣,我会再写一篇文章来专门介绍 category  timedelta 类型。不过本文中概述的基本方法也适用于这些类型。

我们为什么关心类型?

数据类型是在你遇到错误或意外结果之前并不会关心的事情之一。不过当你将新数据加载到 Pandas 进行进一步分析时,这也是你应该检查的第一件事情。

我将使用一个非常简单的 CSV文件 来说明在 Pandas 中可能会遇到的一些常见的由数据类型导致的错误。另外,在 github 上也一个示例 notbook

import numpy as np

import pandas as pd

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

Customer Number

Customer Name

2016

2017

Percent Growth

Jan Units

Month

Day

Year

Active

0

10002.0

Quest Industries

$125,000.00

$162500.00

30.00%

500

1

10

2015

Y

1

552278.0

Smith Plumbing

$920,000.00

$101,2000.00

10.00%

700

6

15

2014

Y

2

23477.0

ACME Industrial

$50,000.00

$62500.00

25.00%

125

3

29

2016

Y

3

24900.0

Brekke LTD

$350,000.00

$490000.00

4.00%

75

10

27

2015

Y

4

651029.0

Harbor Co

$15,000.00

$12750.00

-15.00%

Closed

2

2

2014

N

乍一看,数据没什么问题,所以我们可以尝试做一些操作来分析数据。我们来试一下把 2016 2017 年的销售额加起来:

df['2016'] + df['2017']

0      $125,000.00$162500.00

1    $920,000.00$101,2000.00

2        $50,000.00$62500.00

3      $350,000.00$490000.00

4        $15,000.00$12750.00

dtype: object

这看起来就不对了。我们希望将总计加在一起,但 Pandas 只是将这两个值连接在一起创建了一个长字符串。这个问题的一个线索是 dtypeobjectobject  Pandas 代表字符串,所以它执行的是字符串操作而不是数学操作。

如果我们想查看 dataframe 中的所有数据类型,使用 df.dtypes

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

此外,df.info() 函数可以显示更有用的信息。

df.info()

<class 'pandas.core.frame.DataFrame'>

RangeIndex: 5 entries, 0 to 4

Data columns (total 10 columns):

Customer Number    5 non-null float64

Customer Name      5 non-null object

2016               5 non-null object

2017               5 non-null object

Percent Growth     5 non-null object

Jan Units          5 non-null object

Month              5 non-null int64

Day                5 non-null int64

Year               5 non-null int64

Active             5 non-null object

dtypes: float64(1), int64(3), object(6)

memory usage: 480.0+ bytes

查看自动分配的数据类型后,有几个问题:

  • Customer Number 被归为 float64 但它应该是 int64
  • 2016  2017 这两列被存储为 object,但应该是 float64  int64 这样的数值类型
  • Percent Growth  Jan Units 也被存储为 object 而不是数值类型
  • MonthDay  Year 这三列应该被转换为 datetime64
  • Active 列应该是布尔型

在我们清洗这些数据类型之前,要对这些数据做更多的附加分析是非常困难的。

为了在 Pandas 中转换数据类型,有三个基本选项:

  • 使用 astype() 来强制转换到合适的 dtype
  • 创建一个自定义函数来转换数据
  • 使用 Pandas 的函数,例如 to_numeric()  to_datetime()

使用 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

为了真正修改原始 dataframe 中的客户编号(Customer Number),记得把 astype() 函数的返回值重新赋值给 dataframe,因为 astype() 仅返回数据的副本而不原地修改。

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

以下是客户编号(Customer Number)为整数的新 dataframe

Customer Number

Customer Name

2016

2017

Percent Growth

Jan Units

Month

Day

Year

Active

0

10002

Quest Industries

$125,000.00

$162500.00

30.00%

500

1

10

2015

Y

1

552278

Smith Plumbing

$920,000.00

$101,2000.00

10.00%

700

6

15

2014

Y

2

23477

ACME Industrial

$50,000.00

$62500.00

25.00%

125

3

29

2016

Y

3

24900

Brekke LTD

$350,000.00

$490000.00

4.00%

75

10

27

2015

Y

4

651029

Harbor Co

$15,000.00

$12750.00

-15.00%

Closed

2

2

2014

N

这一切看起来不错,并且似乎很简单。让我们尝试对 2016 列做同样的事情并将其转换为浮点数:

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

ValueError       Traceback (most recent call last)

<ipython-input-45-999869d577b0> in <module>()

----> 1 df['2016'].astype('float')

[一些错误信息]

ValueError: could not convert string to float: '$15,000.00'

以类似的方式,我们可以尝试将 Jan Units 列转换为整数:

df['Jan Units'].astype('int')

ValueError         Traceback (most recent call last)

<ipython-input-44-31333711e4a4> in <module>()

----> 1 df['Jan Units'].astype('int')

[一些错误信息]

ValueError: invalid literal for int() with base 10: 'Closed'

这两个都返回 ValueError 异常,这意味着转换不起作用。

在这两个例子中,数据都包含不能被解释为数字的值。在销售额(2016)列中,数据包括货币符号以及每个值中的逗号。在 Jan Units 列中,最后一个值是 "Closed",它不是一个数字;所以我们得到了异常。

到目前为止,astype() 作为工具看起来并不怎么好。我们在 Active 列中再试一次。

df['Active'].astype('bool')

0    True

1    True

2    True

3    True

4    True

Name: Active, dtype: bool

第一眼,这看起来不错,但经过仔细检查,存在一个大问题。所有的值都被解释为 True,但最后一个客户有一个 N 的活动(Active)标志,所以这并不正确。

这一节的重点是 astype() 只有在下列情况下才能工作:

  • 数据是干净的,可以简单地解释为一个数字
  • 你想要将一个数值转换为一个字符串对象

如果数据具有非数字字符或它们间不同质(homogeneous),那么 astype() 并不是类型转换的好选择。你需要进行额外的变换才能完成正确的类型转换。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值