P8

知知知…
在这里插入图片描述

1.category 分类变量的创建

① 用Series创建,指定类型为 dtype=‘category’ (类似于用Series创建 string 类)

s = pd.Series([1, 'a', 'uuu', 4.3], dtype='category')
print(s)
'''
0      1
1      a
2    uuu
3    4.3
dtype: category
Categories (4, object): [1, 4.3, 'a', 'uuu']
'''

② 对DataFrame指定类型创建(因为 cat 是 Series的内置函数,所以在创建df指定类型的时候,应该是对df的列(df的列即是Series)进行指定

df = pd.DataFrame({'A': pd.Series(["a", "b", "c", "a"], dtype='category'), 'B': pd.Series(list('abcd'), dtype='category')})
print(df.dtypes)
'''
A    category
B    category
dtype: object
'''

③ 利用内置Categorical类型创建

cat = pd.Categorical(["a", "b", "c", "a"])
print(pd.Series(cat))
'''
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): ['a', 'b', 'c']
'''

④ 利用cut函数创建 (其类是有序的,在日常数据处理中使用pd.cut或pd.qcut时,默认分组标签就是category类型)

cat = pd.cut(np.random.randint(0, 60 ,5), [0, 10, 30, 60])
print(cat)
'''
[(30, 60], (0, 10], (30, 60], (0, 10], (0, 10]]
Categories (3, interval[int64]): [(0, 10] < (10, 30] < (30, 60]]
'''

2.分类变量的性质

一个分类变量包括三个部分,元素值(values)、分类类别(categories)、是否有序(order)

① describe方法

该方法描述了一个分类序列的情况,包括非缺失值个数、元素值类别数(不是分类类别数)、最多次出现的元素及其频数

s = pd.Series(pd.Categorical(["a", "b", "c", 'a',np.nan], categories=['a','b','c','d']))
print(s.describe())
'''
count     3
unique    3
top       a
freq      2
dtype: object
'''

元素值类别数 是指在已设置好的类别中,元素中对应出现的类,有多少个。
比如 设置好类是 a,b,c,d 四个类,若元素为a,a,b 那么 unique = 2 (只出现了 a,b 两类);若元素为 a,b,c,d,b,c 则 unique = 4 (全都出现了,且重复的不算)

② categories和ordered属性 用于查看分类类别和是否排序

s = pd.Series(pd.Categorical(["a", "b", "c", 'a',np.nan], categories=['a','b','c','d']))
print(s.cat.categories)
'''
Index(['a', 'b', 'c', 'd'], dtype='object')
'''

print(s.cat.ordered)
'''
False
'''

③ 类别的修改

s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))

1) 利用set_categories修改 (修改分类,但本身值不会变化;会生成一个新的对象)

s.cat.set_categories(['new_a','c'])

2)利用rename_categories修改(该方法会把值和分类同时修改;对应的值也会跟着类的变化而变化)

s.cat.rename_categories(['new_%s' % i for i in s.cat.categories])

3)利用字典修改值

s.cat.rename_categories({'a':'new_a','b':'new_b'})

4)利用add_categories添加

s.cat.add_categories(['e'])

5)利用remove_categories移除

s.cat.remove_categories(['d'])

6)删除元素值未出现的分类类型

s.cat.remove_unused_categories()

2.分类变量的排序(指的是类的排序,而不是值的)

① 序的建立

1)利用as_ordered方法 可将 一个序列转为有序变量,返回一个新的对象,原序列不受影响

s = pd.Series([5, 7, 2, 6]).astype('category')
print(s.cat.as_ordered())
'''
0    5
1    7
2    2
3    6
dtype: category
Categories (4, int64): [2 < 5 < 6 < 7]
'''
print(s)
'''
0    5
1    7
2    2
3    6
dtype: category
Categories (4, int64): [2, 5, 6, 7]
'''

使用as_unordered 方法,可使有序变量退化为无序变量(事实上,我觉得没啥 luan useful)

2) 利用set_categories方法中的order参数(返回一个新的变量)

s = pd.Series(["a", "d", "c", "a"]).astype('category')
print(s.cat.set_categories(['a', 'd', 'c'], ordered=True))
'''
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): ['a' < 'd' < 'c']
'''

3)利用reorder_categories方法

注:使用该方法是 新设置的分类必须与原分类为同一集合,即个数与种类必须一致,否则会报错

s = pd.Series(["a", "d", "c", "a"]).astype('category')
print(s.cat.reorder_categories(['a', 'd', 'c'], ordered=True))
'''
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): ['a' < 'd' < 'c']
'''

② 排序

没啥好说的,给大家表演一个粘贴复制的倒序吧

s = pd.Series(np.random.choice(['perfect','good','fair','bad','awful'], 50)).astype('category')
print(s.cat.set_categories(['perfect','good','fair','bad','awful'][::-1], ordered=True).head())
'''
0    perfect
1        bad
2       fair
3       fair
4    perfect
dtype: category
Categories (5, object): ['awful' < 'bad' < 'fair' < 'good' < 'perfect']
'''

3.分类变量的比较操作

① 与标量比较 (Series里的每个元素都逐个与单个标量比较,结果返回的是布尔值)

cat = pd.Categorical(["a", "b", "c", "a"])
s = pd.Series(cat)
print(s == 'b')
'''
0    False
1     True
2    False
3    False
dtype: bool
'''

② 与等长序列比较(Series里的每个元素都逐个与等长序列对应位置比较,结果返回的同样是布尔值)

cat = pd.Categorical(["a", "b", "c", "a"])
s = pd.Series(cat)
print(s == list('aaba')
'''
0     True
1    False
2    False
3     True
dtype: bool
'''

③ 与另一分类变量的比较

1)等式判别(包含等号和不等号)

两个分类变量的等式判别需要满足分类完全相同

2)不等式判别(包含>=,<=,<,>)

两个分类变量的不等式判别需要满足两个条件:① 分类完全相同 ② 排序完全相同

题题题…

【问题一】 如何使用union_categoricals方法?它的作用是什么?

好家伙,上面根本都没介绍union_categoricals,要不是这提到,还不知道有这玩意儿呢。。官方文档

Combine list-like of Categorical-like, unioning categories. All categories must have the same dtype. 合并类似于列表的分类变量?且要求这些分类变量必须具有相同的 dtype

union_categoricals(to_union, sort_categories=False, ignore_order=False)

参数:
to_union: 要合并的对象,可以是 dtype = '类别’的 分类列表, 分类索引,或系列

sort_categories: 默认False,如果为 true,则生成的类别将被分类,否则它们将按数据中显示的排序。

ignore_order: 默认False,如果为 true,分类的排序属性将被忽略,导致无序分类

a = pd.Categorical(["b", "c"])
b = pd.Categorical(["a", "b"])
print(union_categoricals([a, b]))
'''
['b', 'c', 'a', 'b']
Categories (3, object): ['b', 'c', 'a']

【问题二】 利用concat方法将两个序列纵向拼接,它的结果一定是分类变量吗?什么情况下不是?

当分类的数量和类别一致是,才是分类变量,否则不是

s = pd.Series(["a", "d", "c", "a"]).astype('category')
s1 = pd.Series(["a", "d", "c", "d"]).astype('category')
print(pd.concat([s, s1]))
'''
0    a
1    d
2    c
3    a
0    a
1    d
2    c
3    d
dtype: category
Categories (3, object): ['a', 'c', 'd']
'''
s = pd.Series(["a", "d", "c", "a"]).astype('category')
s1 = pd.Series(["a", "d", "c", "b"]).astype('category')
print(pd.concat([s, s1]))
'''
0    a
1    d
2    c
3    a
0    a
1    d
2    c
3    b
dtype: object
'''

【问题三】 当使用groupby方法或者value_counts方法时,分类变量的统计结果和普通变量有什么区别?

貌似没啥区别,分量变量的统计会跟对应的普通变量一样

s = pd.Series(["a", "d", "c", "a"]).astype('category')
s1 = pd.Series(["a", "d", "c", "a"])
print(s.value_counts())
'''
a    2
d    1
c    1
dtype: int64
'''
print(s1.value_counts())
'''
a    2
d    1
c    1
dtype: int64
'''

【问题四】 下面的代码说明了Series创建分类变量的什么“缺陷”?如何避免?(提示:使用Series中的copy参数)

缺陷:修改series变量的时候,原分类cat 跟着变化
解决方法:创建的时候设置参数copy=True

s = pd.Series(cat, name="cat", copy=True)

【练习一】 现继续使用第四章中的地震数据集,请解决以下问题:

df = pd.read_csv(r'C:\Users\YANG\Desktop\joyful-pandas-master\data\Earthquake.csv')
print(df.head())
'''
     日期           时间     维度     经度        方向   距离   深度   烈度
0  2003.05.20  12:17:44 AM  39.04   40.38        west   0.1   10.0   0.0
1  2007.08.01  12:03:08 AM  40.79   30.09        west   0.1    5.2   4.0
2  1978.05.07  12:41:37 AM  38.58   27.61  south_west   0.1    0.0   0.0
3  1997.03.22  12:31:45 AM  39.47   36.44  south_west   0.1   10.0   0.0
4  2000.04.02  12:57:38 AM  40.80   30.24  south_west   0.1    7.0   0.0
''' 

(a)现在将深度分为七个等级:[0,5,10,15,20,30,50,np.inf],请以深度等级Ⅰ,Ⅱ,Ⅲ,Ⅳ,Ⅴ,Ⅵ,Ⅶ为索引并按照由浅到深的顺序进行排序。

df['深度'] = pd.cut(df['深度'], [-0.01, 5, 10, 15, 20, 30, 50, np.inf], labels=['Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ'])  # 按要求分类
df.set_index(['深度'], inplace=True)  # 设置索引
df.sort_index(inplace=True) # 索引排序
print(df.head())
'''
            日期       时间     维度     经度    方向    距离   烈度
深度                                                              
Ⅰ     2009.09.09  12:54:13 AM  42.42  43.03  north_east  95.4  0.0
Ⅰ     1997.06.16  12:18:04 AM  37.92  29.17  north_east   3.2  0.0
Ⅰ     2011.10.25  12:29:45 AM  38.96  43.64  south_east   1.6  3.9
Ⅰ     1995.07.23  12:05:04 AM  37.61  29.29  north_east   3.2  0.0
Ⅰ     2013.06.10  12:39:19 AM  38.53  43.85  south_east   1.6  3.7
'''

b)在(a)的基础上,将烈度分为4个等级:[0,3,4,5,np.inf],依次对南部地区的深度和烈度等级建立多级索引排序

同样的先对烈度分类,建好索引,最好再利用这两个索引建立起多级索引

df['烈度'] = pd.cut(df['烈度'], [-0.01, 3, 4, 5, np.inf], labels=['Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ'])
df = df[df['方向'].isin(['south'])]
df.set_index(['烈度'], append=True, inplace=True)
df.sort_index(inplace=True)
print(df.head())
'''
           日期           时间     维度     经度   方向   距离
深度 烈度                                                   
Ⅰ   Ⅰ   1995.04.09  12:52:44 AM  37.02  27.43   south  1.6
     Ⅰ   1999.04.05  12:14:35 AM  37.02  27.43   south  1.6
     Ⅰ   1999.07.17  12:37:09 AM  38.35  40.04   south  1.6
     Ⅰ   1994.03.01  12:24:06 AM  38.63  26.47   south  3.0
     Ⅰ   1970.04.26  12:36:06 AM  39.03  29.77   south  3.0

'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值