数据分析练习

在日常生活及工作中,类别型数据大量存在,对他们采用恰当的分析方法,是数据分析工作中重要的关键点之一。

在类别型数据中,有时候,不同类别之间没有好坏之分,比如性别中的男和女。但在实际生活中,还存在另一种有序类别,他们有好坏顺序之分,比如成绩分级中的优良中差。

针对这样的类别型数据,不管是无序的或是有序的,我们都一起来探讨适合他们各自的处理方法。

知识结构
在这里插入图片描述

数据离散化及分箱操作

在实际的数据处理过程中,有时需要我们将连续的数据值进行划分,放到不同的区间中,减少过多的数据值给分析工作带来的麻烦。

将连续型数据打散放入到不同的区间,就类似将货物进行分箱存放,在数据分析过程中,常被称为“分箱操作”。比如我们常做的将不同年龄的人归为婴幼儿、儿童、少年、青年、中年、老年。

在pandas中,使用cut()方法进行分箱操作,比如以下代码样例,数据中记录了几个学生的姓名和他们各自的成绩,我们对成绩进行分箱:

import pandas as pd

#创建数据
df = pd.DataFrame({'Name':['George','Andrea','micheal','maggie','Ravi','Xien','Jalpa','Tyieren'],
                    'Score':[63,48,56,75,32,77,85,22]})
df
Name Score
0 George 63
1 Andrea 48
2 micheal 56
3 maggie 75
4 Ravi 32
5 Xien 77
6 Jalpa 85
7 Tyieren 22
#对得分进行分箱操作,bins为整数,定义分为几个类别
pd.cut(df['Score'],bins=3)
0      (43.0, 64.0]
1      (43.0, 64.0]
2      (43.0, 64.0]
3      (64.0, 85.0]
4    (21.937, 43.0]
5      (64.0, 85.0]
6      (64.0, 85.0]
7    (21.937, 43.0]
Name: Score, dtype: category
Categories (3, interval[float64]): [(21.937, 43.0] < (43.0, 64.0] < (64.0, 85.0]]

向cut()中传入了两个参数,第一个是需要进行分箱操作的数据列,第二个参数bins表示我们希望将数据分配到几个区间之中。

cut()的操作将这列数据一共划分成了三个区间:(21.937, 43]、(43, 64]和(64, 85]。这个区间是系统根据提供的参数bins将数据区间进行平均划分得到的。请留意所有区间都是半开半闭形态,不包含区间开始的数字而包含区间的结束数字。

从cut()计算的结果列表中可以看到,第0、1、2个元素的结果是(43, 64],它表示原来的数据中,前三个数字(63、48、56)属于这个区间。接下来的数字75属于区间(64, 85],等等。你可以实际的观察一下结果的计算是否正确。

根据实际的应用场景,对于分箱边界的平均划分常常不能满足我们的需求。因此,cut()方法中,pandas让bins参数值可以用另一种方式定义——使用列表形式列出划分边界,如以下的代码:

import pandas as pd

# 创建数据
df = pd.DataFrame({'Name':['George','Andrea','micheal','maggie','Ravi','Xien','Jalpa','Tyieren'],
                    'Score':[63,48,56,75,32,77,85,22]})
                
#对得分进行分箱操作,bins为边界列表
pd.cut(df['Score'],bins=[0,60,80,90,100])
0    (60, 80]
1     (0, 60]
2     (0, 60]
3    (60, 80]
4     (0, 60]
5    (60, 80]
6    (80, 90]
7     (0, 60]
Name: Score, dtype: category
Categories (4, interval[int64]): [(0, 60] < (60, 80] < (80, 90] < (90, 100]]

这段代码中,传入cut()方法的bins参数被定义成了[0, 60, 80, 90, 100],于是分箱的区间就会被定义为(0, 60]、(60, 80]、(80, 90]和(90, 100]。从结果输出的最后一列也能很明确的看到这点。

分箱操作的结果中,会把每个数据所归属的结果区间直接显示出来。但我们可能希望用更直观的文本来表示分箱的结果。

比如成绩案例中,我们希望将前面划分的这几个区间从高分到低分分别叫做优、良、中、差。可以使用cut()方法的labels参数达到这一目的:

import pandas as pd

# 创建数据
df = pd.DataFrame({'Name':['George','Andrea','micheal','maggie','Ravi','Xien','Jalpa','Tyieren'],
                    'Score':[63,48,56,75,32,77,85,22]})

#对得分进行分箱操作,bins为边界列表,并且使用label定义区间的名字
df['Level'] = pd.cut(df['Score'],bins=[0,60,80,90,100],labels=['差','中','良','优'])
df
Name Score Level
0 George 63
1 Andrea 48
2 micheal 56
3 maggie 75
4 Ravi 32
5 Xien 77
6 Jalpa 85
7 Tyieren 22

代码中,在进行了cut()操作之后,将分箱的结果与原有的df数据进行了拼接,成为了df中新的Level列。从结果中能更直观的看出不同学员成绩的好坏。

请注意在指定cut()方法的labels参数值时,labels定义的列表中的类别名顺序,是与bins定义的划分区间按顺序一一对应的。

分箱操作,其实就相当于将连续的数字类型数据(比如分数)映射成了类别型数据(比如这里的成绩等级)。分箱操作之后的结果,时常会再进行groupby操作。比如我们对分好等级之后的成绩再进行分组并计算每组中的平均值:

import pandas as pd

# 创建数据
df = pd.DataFrame({'Name':['George','Andrea','micheal','maggie','Ravi','Xien','Jalpa','Tyieren'],
                    'Score':[63,48,56,75,32,77,85,22]})

# 对得分进行分箱操作,bins为边界列表,并且使用labels定义区间的名字
df['Level'] = pd.cut(df['Score'], bins=[0, 60, 80, 90, 100], labels=['差', '中', '良', '优'])

#获取每个等级的平均成绩
df.groupby('Level').mean()
Score
Level
39.500000
71.666667
85.000000
NaN

这就能得到不同等级的平均成绩分别是多少。

在这个计算每个等级平均分的案例中,由于没有成绩落入优级别,在进行分组以及求均值计算之后,对应结果单元中得到的是NaN。

类别型数据类型

在前面的小节中,我们使用一个学生成绩的案例直接体验了pandas处理类别型数据的方法。现在我们来仔细了解pandas中的类别型数据类型。

跟整型(int)、字符串(str)等类型类似,类别型数据类型在pandas中也是一种数据类型。它使用category表示。

就像整型可以进行加减乘除操作一样,category也包含自己特殊的操作方式。

在之前我们通过pandas的cut()方法操作数据之后,会在结果输出中看到dtype: category这样的字样,这就表示结果数组中的元素,是类别数据类型的。

主动构造类别数据类型的变量,有以下几种主要的方法:

dtype

在创建一个Series变量的时候,使用dtype=‘category’,可以指定元素为类别类型。

import pandas as pd
s=pd.Series(['a','b','c','a'],dtype='category')
s
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]

从代码输出中可以看出,这个Series的元素类型已经是类别型了。

astype()

另一种方式,调用Series的astype(),也可以将其中的元素转换为类别型。

import pandas as pd
s=pd.Series(['a','b','c','a'])
s2=s.astype('category')
print('s的值:')
print(s)
print('\ns2的值:')
print(s2)
s的值:
0    a
1    b
2    c
3    a
dtype: object

s2的值:
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]

astype()方法其实就是pandas中的类型转换方法,参数中传入类型的名字,就可以将数组中的元素类型转换成这个参数指定的类型。

我们在代码中打印了Series变量s和s2的值。从输出内容上看,他们好像是一样的,不同只在于结果中的dtype。

只是内容上看起来一样,并不能说明s与s2是一样的。看以下代码展示类别型元素与字符串类型元素的差别:

import pandas as pd
s=pd.Series(['a','b','c','a'])
s2=s.astype('category')
s.max()
'c'
s2.max()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-11-f92cd5067311> in <module>
----> 1 s2.max()


c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\pandas\core\generic.py in stat_func(self, axis, skipna, level, numeric_only, **kwargs)
  11616             return self._agg_by_level(name, axis=axis, level=level, skipna=skipna)
  11617         return self._reduce(
> 11618             f, name, axis=axis, skipna=skipna, numeric_only=numeric_only
  11619         )
  11620 


c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\pandas\core\series.py in _reduce(self, op, name, axis, skipna, numeric_only, filter_type, **kwds)
   4069             # TODO deprecate numeric_only argument for Categorical and use
   4070             # skipna as well, see GH25303
-> 4071             return delegate._reduce(name, numeric_only=numeric_only, **kwds)
   4072         elif isinstance(delegate, ExtensionArray):
   4073             # dispatch to ExtensionArray interface


c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\pandas\core\arrays\categorical.py in _reduce(self, name, axis, **kwargs)
   2259             msg = "Categorical cannot perform the operation {op}"
   2260             raise TypeError(msg.format(op=name))
-> 2261         return func(**kwargs)
   2262 
   2263     def min(self, numeric_only=None, **kwargs):


c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\pandas\core\arrays\categorical.py in max(self, numeric_only, **kwargs)
   2302         max : the maximum of this `Categorical`
   2303         """
-> 2304         self.check_for_ordered("max")
   2305         if numeric_only:
   2306             good = self._codes != -1


c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\pandas\core\arrays\categorical.py in check_for_ordered(self, op)
   1584                 "Categorical is not ordered for operation {op}\n"
   1585                 "you can use .as_ordered() to change the "
-> 1586                 "Categorical to an ordered one\n".format(op=op)
   1587             )
   1588 


TypeError: Categorical is not ordered for operation max
you can use .as_ordered() to change the Categorical to an ordered one

我们在代码中分别调用了元素是字符串类型的Series变量s以及元素是类别型的Series变量s2的max()方法。

从结果中你会发现,s.max()会输出结果’c’,因为字符串是可以比较大小的,在所有的元素中,'c’的值最大。

而s2.max()执行之后会发生错误。这就是我们之前提到的,类别型数据中,各类别在默认情况下没有大小之分,不能比较,因此就没有最大值。

对于有序型类别,pandas则提供了以下直接创建对象的方式,满足要求:

pandas.Categorical()

通过pandas.Categorical()构建一个对象,并在构建这个对象时,传入参数ordered=True,然后以这个Categorical作为数据模板创建Series,即可得到有序型的类别数据。看以下代码示例:

import pandas as pd
#pd.Categorical(),指定类别以及有序
s = pd.Series(pd.Categorical(['差','中','良','优'],ordered=True))
s
0    差
1    中
2    良
3    优
dtype: category
Categories (4, object): [中 < 优 < 差 < 良]
s.max()
'良'

在代码中,将有序型类别数据s进行输出,可以看到其中对优、良、中、差给出了明确的大小关系描述:[中 < 优 < 差 < 良]。

我们在第二段代码中打印了s.max(),可以从输出结果中看到最大值’良’。

但这里还有个问题,对于优、良、中、差的排序,并不是按照中文意思上的优最大、差最小进行的。

你可以尝试执行print(‘中’<‘优’<‘差’<‘良’),会得到结果True。这说明这里的类别顺序用的就是字符串的排序结果。

如果希望按照自己定义的顺序来定义类别,在构造Categorical对象的时候,还需要提供一个参数:cat

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python数据分析练习是指通过使用Python编程语言来处理和分析数据的实践活动。这些练习旨在让学习者掌握如何使用Python的数据分析库来处理和分析实际的数据集。 在Python数据分析练习中,学习者首先需要了解如何读取和导入数据集。Python有很多库可以用于读取和处理各种格式的数据,例如CSV、Excel、JSON等。学习者需要学习如何使用这些库来加载和处理自己感兴趣的数据。 然后,学习者需要学习如何清洗和预处理数据。数据通常存在一些缺失值、异常值和重复值,需要使用Python库来清洗和处理这些问题。此外,学习者还需要了解如何对数据进行规范化和标准化,以便于后续的分析工作。 接下来,学习者可以学习如何使用Python进行数据分析和可视化。Python有很多数据分析库,例如Pandas、NumPy和Matplotlib等。学习者需要学习如何使用这些库来计算统计指标、绘制图表和进行数据挖掘。学习者可以使用这些库来回答自己感兴趣的问题,例如数据的趋势、相关性和模式等。 最后,学习者需要学习如何进行数据报告和沟通。数据分析不仅仅是处理数据,还需要将结果以清晰和易懂的方式传达给其他人。学习者可以使用Python的文档编写和可视化库来创建数据报告和可视化演示,以向他人展示分析结果。 总之,Python数据分析练习是通过使用Python编程语言来处理和分析数据的实践活动。学习者需要学习如何读取和导入数据、清洗和预处理数据、使用数据分析和可视化库进行数据分析,以及进行数据报告和沟通。这些练习可以帮助学习者掌握Python数据分析的技能,为实际问题提供解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值