Pandas数据类型操作

7_Pandas数据类型操作

数据处理、分析等操作的首要操作是我们正确地设置了数据类型,笔者自己经常也会遇到数据类型不合理,而造成无法进行后续操作的困境。本文总结了Pandas中进行数据类型转换的三种基本方法,同时介绍了基于数据类型取数的方法:

  • 使用astype()函数进行强制类型转换
  • 通过自定义函数来进行数据类型转换
  • 使用Pandas提供的函数如to_numeric()、to_datetime()等进行转化
  • select_dtypes函数的使用
image

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

下表中展示的是Pandas、Python和Numpy中支持的数据类型,可以看到pandas中支持的类型是最丰富的的。

image

模拟数据

导入数据

下面是模拟的一份数据,包含多个字段名称

image
import pandas as pd
import numpy as np

# 读取数据
df = pd.read_csv("数据类型操作.csv")
df
image

查看数据的字段类型:

image

数据类型查看

df.dtypes # 各字段的数据类型
df.team.dtype # 某个字段的类型
s.dtype # Series 的类型
df.dtypes.value_counts() # 各类型有多少个字段

实际案例

字符型转成数值型

比如我们想在数据上进行一些操作,比如将"2019年"、和"2020年"的数据相加:很明显数据不是我们想要的结果。

根本原因:这两个字段是字符类型,进行+操作,是直接将里面的内容拼接在一起,而不是里面数值的相加。

image

正确的操作:

1、先把这两个字段中的数字单独提取出来

# 分割之后取出第1个元素

df["2020年_新"] = df["2020年"].apply(lambda x:x.split("元")[0])
df["2019年_新"] = df["2019年"].apply(lambda x:x.split("元")[0])
df
image

2、查看数据类型

生成的两个新字段仍然是字符类型,不能直接相加

image

3、将数字表现型的字符型数据转成数值型

有两种方法实现这种需求:

  • pd.astype("float") :指定类型
  • to_numeric():直接转化
##  字符类型的数值转成纯数值型

# 等价写法:df["2020年_新"] = df.astype({"2020年_新":"int")  字典形式传入
df["2020年_新"] = df["2020年_新"].astype("int")
df['2019年_新'] = pd.to_numeric(df['2019年_新'], errors='coerce')  
df
image

3、将两个新的字段相加

df["前两年之和"] = df["2020年_新"] + df["2019年_新"]
df
image

求两个年份之间的差值:

image

数值型转成字符型

求出2020年的增长率:

df["增长率"] = df["前两年之差"] / df["2019年_新"]
df
image

现在整个增长率是float的数值型,我们想把它转成%的形式,也就是字符类型的数据:

顾客姓名        object
顾客编码         int64
客户部门        object
客户组别       float64
2019年       object
2020年       object
日            int64
月            int64
年            int64
是否大客户       object
2020年_新      int64
2019年_新      int64
前两年之和        int64
前两年之差        int64
增长率        float64     # 数值型数据
dtype: object

在这里也是两种方法满足上面的需求:

  • 方法1:通过str函数的转化
  • 方法2:通过format函数的格式化输出
df["增长率1"] = df["增长率"].apply(lambda x: str(round(100*x,2)) + "%")
df["增长率2"] = df["增长率"].apply(lambda x: format(x,'.2%'))
df
image
顾客姓名        object
顾客编码         int64
客户部门        object
客户组别       float64
2019年       object
2020年       object
日            int64
月            int64
年            int64
是否大客户       object
2020年_新      int64
2019年_新      int64
前两年之和        int64
前两年之差        int64
增长率        float64
增长率1        object   #  两个字符类型的数据
增长率2        object
dtype: object

数值型数据存在缺失值

如果某个字段中大部分的数据都是数值型,但是存在少量的缺失值的情况,可以使用下面的方法进行转化:

image
df["客户组别"] = pd.to_numeric(df['客户组别'], errors='coerce').fillna(0)  # 未知的组用0代替;0可以换成其他数值
df
image

数值型类型转成时间类型

如果在实际数据中,我们遇到类似年、月、日等时间的数据,可以进行转化:比如我们想根据数据中的年月日生成一个生日的字段

image

1、上面的日、月、年现在是数值类型的数据,不能直接相加,先进行转化:

df["月"] = df["月"].astype(str)
df["年"] = df["年"].astype(str)

2、转成字符型数据之后,再进行相加:

df["生日"] = df["年"] + "-" + df["月"] + "-" + df["日"]
df
image

3、通过pd.to_datetime转成pandas中的时间类型数据

df["生日"] = df["生日"].apply(lambda x: pd.to_datetime(x,format="%Y-%m-%d"))
df.dtypes
image

经过检验:如果字段是用英文表示的,下面的方法可以直接转成datetime64[ns]类型,使用中文汉字当做属性名的时候,该方法不适用。Pandas中的to_datetime()函数可以把单独的year、month、day三列合并成一个单独的时间戳:

pd.to_datetime(df[['year', 'month', 'day']]) # 组合成日期
image
image

布尔值判断使用

比如在是否为大客户中,我们想将Y换成True,N换成False,可以通过np.where来是实现:

df["是否大客户"] = np.where(df["是否大客户"] == "Y", True, False)
df
image

读取文件直接转换

在使用pandas读取文件的时候,我们可以直接改变数据类型,使用参数是converters:

df0 = pd.read_csv("数据类型操作.csv",
                  converters={
                    "顾客编码":str,  # 指定改变的函数
                    "2019年":lambda x:float(x.split("元")[0]),  # 切割函数
                    "2020年":lambda x:float(x.replace("元","")),  # 替换函数
                    "客户组别":lambda x: pd.to_numeric(x, errors='coerce'), 
                    "是否大客户":lambda x:np.where(x == "Y",True,False)
                  }
                 )
df0 
image

根据数据类型取数

我们看看df数据中存在的数据类型:object、int64、float64、bool、datetime64[ns]

df.dtypes

# 结果
顾客姓名               object
顾客编码                int64
客户部门               object
客户组别              float64
2019年              object
2020年              object
日                  object
月                  object
年                  object
是否大客户                bool
2020年_新             int64
2019年_新             int64
前两年之和               int64
前两年之差               int64
增长率               float64
增长率1               object
增长率2               object
生日         datetime64[ns]
dtype: object

包含数据类型

df.select_dtypes(include=["object"])  # 包含object类型的数据
image

也可以同时筛选包含多个数据类型:

df.select_dtypes(include=["object","bool"])
image

不包含数据类型

df.select_dtypes(exclude=["object"])   # 不包含object类型的数据
image

同时排除多个字段数据类型:

df.select_dtypes(exclude=["object","bool"])   # 两个类型的数据同时排除
image

总结

对数据进行操作的第一步就是保证我们设置了正确的数据类型,然后才能进行后续的数据处理、数据分析、可视化等一系列的操作。不用的数据类型可以用不同的处理方法。注意,一个列只能有一个总数据类型。本文中介绍了Pandas中常见的数据类型转化和基于数据类型取数的方法,希望对读者有所帮助。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容