资讯专栏INFORMATION COLUMN

Pandas数据类型转换的几个小技巧

luckyw / 365人阅读

摘要:利用的一些辅助函数进行类型转换的函数和复杂的自定函数之间有一个中间段,那就是的一些辅助函数。这些辅助函数对于某些特定数据类型的转换非常有用如。

利用Pandas进行数据分析时,确保使用正确的数据类型是非常重要的,否则可能会导致一些不可预知的错误发生。笔者使用Pandas已经有一段时间了,但是还是会在一些小问题上犯错误,追根溯源发现在对数据进行操作时某些特征列并不是Pandas所能处理的类型。因此本文将讨论一些小技巧如何将Python的基本数据类型转化为Pandas所能处理的数据类型。

Pandas、Numpy、Python各自支持的数据类型


从上述表格中可以看出Pandas支持的数据类型最为丰富,在某种情形下Numpy的数据类型可以和Pandas的数据类型相互转化,毕竟Pandas库是在Numpy的基础之上开发的的。
引入实际数据进行分析

数据类型是你平常可能不太关心,直到得到了错误的结果才映像深刻的东西,因此在这里引入一个实际数据分析的例子来加深理解。

import numpy as np
import pandas as pd

data = pd.read_csv("data.csv", encoding="gbk") #因为数据中含有中文数据
data


数据加载完毕,如果现在想要在该数据上进行一些操作,比如把数据列2016、2017对应项相加。

data["2016"] + data["2017"] #想当然的做法


从结果来看并没有像想象中那样数值对应相加,这是因为在Pandas中object类型相加等价于Python中的字符串相加。

data.info() #在对数据进行处理之前应该先查看加载数据的相关信息


在看到加载数据的相关信息后可以发现如下几个问题:

客户编号的数据类型是int64而不是object类型

2016、2017列的数据类型是object而不是数值类型(int64、float64)

增长率、所属组的数据类型应该为数值类型而不是object类型

year、month、day的数据类型应该为datetime64类型而不是object类型

Pandas中进行数据类型转换有三种基本方法:

使用astype()函数进行强制类型转换

自定义函数进行数据类型转换

使用Pandas提供的函数如to_numeric()、to_datetime()

使用astype()函数进行类型转换
对数据列进行数据类型转换最简单的方法就是使用astype()函数

data["客户编号"].astype("object")

data["客户编号"] = data["客户编号"].astype("object") #对原始数据进行转换并覆盖原始数据列


上面的结果看起来很不错,接下来给出几个astype()函数作用于列数据但失效的例子

data["2017"].astype("float")

data["所属组"].astype("int")


从上面两个例子可以看出,当待转换列中含有不能转换的特殊值时(例子中¥,ErrorValue等)astype()函数将失效。有些时候astype()函数执行成功了也并不一定代表着执行结果符合预期(神坑!)

data["状态"].astype("bool")


乍一看,结果看起来不错,但仔细观察后,会发现一个大问题。那就是所有的值都被替换为True了,但是该列中包含好几个N标志,所以astype()函数在该列也是失效的。

总结一下astype()函数有效的情形:

数据列中的每一个单位都能简单的解释为数字(2, 2.12等)

数据列中的每一个单位都是数值类型且向字符串object类型转换

如果数据中含有缺失值、特殊字符astype()函数可能失效。

使用自定义函数进行数据类型转换
该方法特别适用于待转换数据列的数据较为复杂的情形,可以通过构建一个函数应用于数据列的每一个数据,并将其转换为适合的数据类型。
对于上述数据中的货币,需要将它转换为float类型,因此可以写一个转换函数:

def convert_currency(value):
    """
    转换字符串数字为float类型
     - 移除 ¥ ,
     - 转化为float类型
    """
    new_value = value.replace(",", "").replace("¥", "")
    return np.float(new_value)

现在可以使用Pandas的apply函数通过covert_currency函数应用于2016列中的所有数据中。

data["2016"].apply(convert_currency)


该列所有的数据都转换成对应的数值类型了,因此可以对该列数据进行常见的数学操作了。如果利用lambda表达式改写一下代码,可能会比较简洁但是对新手不太友好。

data["2016"].apply(lambda x: x.replace("¥", "").replace(",", "")).astype("float")

当函数需要重复应用于多个列时,个人推荐使用第一种方法,先定义函数还有一个好处就是可以搭配read_csv()函数使用(后面介绍)。

#2016、2017列完整的转换代码
data["2016"] = data["2016"].apply(convert_currency)
data["2017"] = data["2017"].apply(convert_currency)

同样的方法运用于增长率,首先构建自定义函数

def convert_percent(value):
    """
    转换字符串百分数为float类型小数
    - 移除 %
    - 除以100转换为小数
    """
    new_value = value.replace("%", "")
    return float(new_value) / 100

使用Pandas的apply函数通过covert_percent函数应用于增长率列中的所有数据中。

data["增长率"].apply(convert_percent)

使用lambda表达式:

data["增长率"].apply(lambda x: x.replace("%", "")).astype("float") / 100

结果都相同:

为了转换状态列,可以使用Numpy中的where函数,把值为Y的映射成True,其他值全部映射成False。

data["状态"] = np.where(data["状态"] == "Y", True, False)

同样的你也可以使用自定义函数或者使用lambda表达式,这些方法都可以完美的解决这个问题,这里只是多提供一种思路。

利用Pandas的一些辅助函数进行类型转换
Pandas的astype()函数和复杂的自定函数之间有一个中间段,那就是Pandas的一些辅助函数。这些辅助函数对于某些特定数据类型的转换非常有用(如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三列合并成一个多带带的时间戳。

pd.to_datetime(data[["day", "month", "year"]])

完成数据列的替换

data["new_date"] = pd.to_datetime(data[["day", "month", "year"]]) #新产生的一列数据
data["所属组"] = pd.to_numeric(data["所属组"], errors="coerce").fillna(0)

到这里所有的数据列都转换完毕,最终的数据显示:


在读取数据时就对数据类型进行转换,一步到位

data2 = pd.read_csv("data.csv",
                   converters={
                               "客户编号": str,
                               "2016": convert_currency,
                               "2017": convert_currency,
                               "增长率": convert_percent,
                               "所属组": lambda x: pd.to_numeric(x, errors="coerce"),
                               "状态": lambda x: np.where(x == "Y", True, False)
                              },
                   encoding="gbk")

在这里也体现了使用自定义函数比lambda表达式要方便很多。(大部分情况下lambda还是很简洁的,笔者自己也很喜欢使用)
总结
对数据集进行操作的第一步是确保设置正确的数据类型,然后才能进行数据的分析、可视化等操作,Pandas提供了很多非常方便的函数,有了这些函数那么对数据进行分析将会是很方便的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41673.html

相关文章

  • Pandas之旅(七) 谁说pandas

    摘要:下面让我们开始提速假设我们现在的电价是定值,不根据用电时间段来改变,那么中最快的方法那就是采用,这就是一个简单的矢量化操作示范。它基本是在中运行最快的方式。 Pandas 加速 大家好,今天我们来看有关pandas加速的小技巧,不知道大家在刚刚接触pandas的时候有没有听过如下的说法 pandas太慢了,运行要等半天 其实我想说的是,慢不是pandas的错,大家要知道pandas本身...

    genedna 评论0 收藏0
  • JavaScript 的几个小技巧

    摘要:的几个小技巧尽早将无效的用例尽早返回,避免意外和不必要的代码处理。要添加一种新的就需要再添加一个分支判断多重判断时使用或者,避免过长逻辑判断改进后一次循环两个数组 JavaScript 的几个小技巧 1. 尽早 return function transformData(rawData) { // check if no data if (!rawData) { ret...

    arashicage 评论0 收藏0
  • 关于PHP数组的几个小技巧

    摘要:我们知道在中多了几个对数组使用的新特性。这里我们举两个实际的例子吧例子一仔细体会。例子二看到了吧,可以直接在循环中指定变量,然后在循环体中来使用,是不是很简单好了本文就这些内容了,欢迎继续关注。更多知识,请前往 我们知道在PHP7.1中多了几个对数组使用的新特性。 这里我们举两个实际的例子吧: 例子一: // PHP 7.1+ $options = [enabled => true, ...

    chenjiang3 评论0 收藏0
  • 10个Python Pandas技巧,使您的工作更有效率

    摘要:是一个广泛用于结构化数据的包。因此,的任何变化都会导致发生变化。这是检查值分布的命令。这也是每个人都会使用的命令。我想在这里指出两个技巧。另一个技巧是处理混合在一起的整数和缺失值。将所有浮点数舍入为整数。 showImg(https://segmentfault.com/img/remote/1460000019138448?w=432&h=270); Pandas是一个广泛用于结构化...

    stormjun 评论0 收藏0
  • JavaScript几个小技巧

    摘要:反之左操作数值为真,整个表达式的值则依赖于右操作数。以上的这种特性称为运算符的短路行为,根据这个特性我们可以有效减少语句的使用,还可以增强程序的健壮性。数值上一个空串,会转换为字符串字符串减会转换为数值,如失败则返回。 &&、||运算的高级用法   在JavaSript中,&&运算符除了可以对布尔值进行与(AND)运算之外,还可以对真假值进行与(AND)运算。JavaScript中所有...

    Apollo 评论0 收藏0

发表评论

0条评论

luckyw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<