文章数据
收藏(次)

【python数据分析】第十二章 pandas高级应用

加关注
import pandas as pd
import numpy as np
--------------------------------------------------------------------------------
分类数据
--------------------------------------------------------------------------------
数据库中:数据商品的类型,一般是存在一个类型的表,商品表中有一个字段引用类型表的主键
作为外键,而不是在商品的后面直接存储商品的类型,这样存储一个数字外键比存入字符串更节省空间
--------------------------------------------------------------------------------
values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2) # 相当于商品后面直接写类型
pd.unique(values) # 提取他们的类型
输出:array(['apple', 'orange'], dtype=object), 虽然是8条数据,但是类型只有两个
pd.value_counts(values)
输出:不同类型上的数据样本数量
apple 6
orange 2
dtype: int64

这样存储数据就不太好,大量的重复字符串,如果提取特征值 + 映射的方式就会优化存储
--------------------------------------------------------------------------------
这个是存储的数据,两个,一个是字符串,一个是映射关系,需要他们共同作用才能还原数据
values = pd.Series([0, 1, 0, 0] * 2)
dim = pd.Series(['apple', 'orange']) # 存储的是2个字符串和一组数字,而不是8个字符串

### Return the elements in the given *positional* indices along an axis.
dim.take(values)
输出:
0 apple
1 orange
0 apple
0 apple
0 apple
1 orange
0 apple
0 apple
dtype: object
--------------------------------------------------------------------------------
这种用整数表示的方法称为分类或字典编码表示法。
本书中,我们使用分类的说法。表示分类的整数值称为分类编码或简单地称为编码。
分类表示可以在进行分析时大大的提高性能。
好处是,
1、修改类型名称时,直接修改一个地方,还原数据就能应用到全部
2、添加一个新分类,原来的分类顺序和位置都是不变的。
================================================================================
fruits = ['apple', 'orange', 'apple', 'apple'] * 2
N = len(fruits)
df = pd.DataFrame({'fruit': fruits,
'basket_id': np.arange(N),
'count': np.random.randint(3, 15, size=N),
'weight': np.random.uniform(0, 4, size=N)},
columns=['basket_id', 'fruit', 'count', 'weight'])
df 输出:
basket_id fruit count weight
0 0 apple 7 2.364948
1 1 orange 6 3.530644
2 2 apple 11 0.899195
3 3 apple 3 2.468192
4 4 apple 5 2.068400
5 5 orange 11 2.396059
6 6 apple 14 0.978598
7 7 apple 5 1.693896
# astype 方法的作用,把 pandas 数据转换成指定类型, 'category' 表示时 Category 类型
fruit_cat = df['fruit'].astype('category')
fruit_cat 输出:
0 apple
1 orange
2 apple
3 apple
4 apple
5 orange
6 apple
7 apple
Name: fruit, dtype: category
Categories (2, object): [apple, orange] <----------- 两个数据
当数据类型变成 category 以后,实际的数据量只有两个,

c = fruit_cat.values
c.categories # 输出:Index(['apple', 'orange'], dtype='object')
c.codes # 输出:array([0, 1, 0, 0, 0, 1, 0, 0], dtype=int8)
--------------------------------------------------------------------------------
df.dtypes 输出如下,可以看到 fruit 类型是 object
basket_id int32
fruit object
count int32
weight float64
dtype: object

可以把类型改成 category类型,优化存储
df['fruit'] = df['fruit'].astype('category')
df.dtypes 输出: 改变后,变成了 category 类型
basket_id int32
fruit category
count int32
weight float64
dtype: object
--------------------------------------------------------------------------------
既然category 类型好用,那么可以在创建数据的时候直接使用这个类型,不必要事后转换类型啊。
--------------------------------------------------------------------------------
直接构造方法创建
my_category = pd.Categorical(['aa', 'cc', 'bb', 'bb', 'cc', 'aa'])
--------------------------------------------------------------------------------
创建方式2, 还能指定 ordered 参数
categories = ['aa', 'bb', 'cc']
codes = [1,2,0,0,2,2,1,1,0]
my_category2 = pd.Categorical.from_codes(codes, categories, ordered=True)
--------------------------------------------------------------------------------
方式3,这个也可以
cat_s = pd.Series(['a', 'b', 'c', 'd'] * 2, dtype='category')
--------------------------------------------------------------------------------
用分类进行计算
--------------------------------------------------------------------------------
准备:
draws = np.random.randn(1000)
bins = pd.qcut(draws, 4)
bins 输出:
[(-2.872, -0.686], (-0.686, -0.0774], (0.563, 4.122], .... 这个列表共计1000个数据 ....]
Length: 1000
Categories (4, interval[float64]):
[(-2.872, -0.686] < (-0.686, -0.0774] < (-0.0774, 0.563] < (0.563, 4.122]]
输出说明:
输出 Categories 是四个区间,
上面的省略的共计1000个数据是原数据在区间的哪一个,它不展示原数据是什么,而是展示原数据在哪个区间。
这样看起来就有点乱,可以给四个区间起个名字,使用名字就好看点

draws = np.random.randn(1000)
bins = pd.qcut(draws, 4, labels=['Q1', 'Q2', 'Q3', 'Q4']) # 给四个区间起个名字,Q1,Q2...
bins 输出:
[Q1, Q2, Q1, Q3, Q2, ..., Q4, Q4, Q1, Q3, Q1]
Length: 1000
Categories (4, object): [Q1 < Q2 < Q3 < Q4]

bins.codes[0:15] # 映射关系:array([0, 1, 0, 2, 1, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1], dtype=int8)
--------------------------------------------------------------------------------
开始:
draws = np.random.randn(1000)
bins = pd.qcut(draws, 4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
bins = pd.Series(bins, name='quartile') # 使用这样的 categroy 创建 Series
bins 输出:
0 Q1
1 Q2
2 Q1
3 Q3
4 Q2
..
995 Q4
996 Q4
997 Q1
998 Q3
999 Q1
Name: quartile, Length: 1000, dtype: category
Categories (4, object): [Q1 < Q2 < Q3 < Q4]

bins 一开始也是 pd.qcut(draws, 4, labels=['Q1', 'Q2', 'Q3', 'Q4']) 创建的,
但是创建完成以后,包括数据区间,包括原数据都丢失了,这些数据对 Categroy 来说不重要
重要的是它把原数据的位置 和 对应区间关系表达出来。它没有了原数据,但是有原数据的关系
相当于关系和数据分离,以后这个关系还能应用到其他数据上,那其他数据就立刻有了这层关系了。

draws 现在是原始数据,groupby(bins) 相当于应用上面分离出来的数据关系,应用一组聚合方法,重新索引
results = pd.Series(draws).groupby(bins).agg(['count', 'min', 'max']).reset_index()
results 输出:
quartile count min max
0 Q1 250 -2.918524 -0.677039
1 Q2 250 -0.672905 0.005265
2 Q3 250 0.006883 0.751235
3 Q4 250 0.754644 3.281633
--------------------------------------------------------------------------------



>> 目录 << 


 

分享
收藏
点赞人
举报
文章标签
评论列表

推荐

暂无推荐