利用Python进行数据分析笔记-数据加工(分组、聚合及分组应用)

本文详细介绍了Python进行数据分析时的数据加工和分组聚合操作,涵盖GroupBy机制、数据聚合方法如mean、count等,以及如何进行列选择、函数应用、分位数分析、随机抽样和线性回归等高级操作。通过实例展示了如何利用pandas库高效处理数据。
摘要由CSDN通过智能技术生成
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

数据汇总和组操作

1、GroupBy Mechanics(分组机制)

Hadley Wickham,是很多R语言有名库的作者,他描述group operation(组操作)为split-apply-combine(分割-应用-结合)。第一个阶段,存储于series或DataFrame中的数据,根据不同的keys会被split(分割)为多个组。而且分割的操作是在一个特定的axis(轴)上。例如,DataFrame能按行(axis=0)或列(axis=1)来分组。之后,我们可以把函数apply(应用)在每一个组上,产生一个新的值。最后,所以函数产生的结果被combine(结合)为一个结果对象(result object)。下面是一个图示:

每一个用于分组的key能有很多形式,而且keys也不必都是一种类型

df = pd.DataFrame({
  'key1' : ['a', 'a', 'b', 'b', 'a'],
                   'key2' : ['one', 'two', 'one', 'two', 'one'], 
                   'data1' : np.random.randn(5), 
                   'data2' : np.random.randn(5)})
df
data1 data2 key1 key2
0 0.120113 0.412418 a one
1 1.541971 -0.459096 a two
2 -0.480680 0.703068 b one
3 0.438569 -0.891204 b two
4 0.389028 -0.565778 a one
# data1列数据,按key1来进行分组
grouped = df['data1'].groupby(df['key1'])
grouped
<pandas.core.groupby.SeriesGroupBy object at 0x0000000017E5CCC0>

这个grouped变量是一个GroupBy object(分组对象)。实际上现在还没有进行任何计算,除了调用group key(分组键)df[‘key1’]时产生的一些中间数据。整个方法是这样的,这个GroupBy object(分组对象)已经有了我们想要的信息,现在需要的是对于每一个group(组)进行一些操作。例如,通过调用GroupBy的mean方法,我们可以计算每个组的平均值

# data1列数的平均值
grouped.mean()
key1
a    0.683704
b   -0.021055
Name: data1, dtype: float64
# 我们通过group key(分组键)对数据(a series)进行了聚合,这产生了一个新的Series,而且这个series的索引是key1列中不同的值。
grouped.mean().index
Index(['a', 'b'], dtype='object', name='key1')
# 用两个key来分组,得到的结果series现在有一个多层级索引,这个多层索引是根据key1和key2不同的值来构建的
means = df['data1'].groupby([df['key1'], df['key2']]).mean()
means
key1  key2
a     one     0.254570
      two     1.541971
b     one    -0.480680
      two     0.438569
Name: data1, dtype: float64
means.unstack()
key2 one two
key1
a 0.25457 1.541971
b -0.48068 0.438569
# 对整个数据按key1分组
df.groupby('key1').mean()
data1 data2
key1
a 0.683704 -0.204152
b -0.021055 -0.094068
df.groupby(['key1', 'key2']).mean()
data1 data2
key1 key2
a one 0.254570 -0.076680
two 1.541971 -0.459096
b one -0.480680 0.703068
two 0.438569 -0.891204

上面第一例,结果里并没有key2这一列。因为df[‘key2’]这一列不是数值型数据,我们称这种列为nuisance column(有碍列),这种列不会出现在结果中。
默认情况下,所有的数值型列都会被汇总计算,但是出现有碍列的情况的话,就会过滤掉这种列。
另外一点需要注意的是,如果作为group key的列中有缺失值的话,也不会出现在结果中。

# 组大小
df.groupby(['key1', 'key2']).size()
key1  key2
a     one     2
      two     1
b     one     1
      two     1
dtype: int64

2、对组进行迭代

GroupBy对象支持迭代,能产生一个2-tuple(二元元组),包含组名和对应的数据块。

# 用dict
pieces = dict(list(df.groupby('key1')))
pieces
{'a':       data1     data2 key1 key2
 0  0.120113  0.412418    a  one
 1  1.541971 -0.459096    a  two
 4  0.389028 -0.565778    a  one, 'b':       data1     data2 key1 key2
 2 -0.480680  0.703068    b  one
 3  0.438569 -0.891204    b  two}
pieces['b']
data1 data2 key1 key2
2 -0.480680 0.703068 b one
3 0.438569 -0.891204 b two

3、选中一列,或列的子集

如果一个GroupBy对象是由DataFrame创建来的,那么通过列名或一个包含列名的数组来对GroupBy对象进行索引的话,就相当于对列取子集做聚合(column subsetting for aggregation)。这句话的意思是:

df.groupby('key1')['data1'] 
df.groupby('key1')[['data2']]
上面的代码其实就是下面的语法糖(Syntactic sugar):
df['data1'].groupby(df['key1']) 
df[['data2']].groupby(df['key1'])
df
data1 data2 key1 key2
0 0.120113 0.412418 a one
1 1.541971 -0.459096 a two
2 -0.480680 0.703068 b one
3 0.438569 -0.891204 b two
4 0.389028 -0.565778 a one
df.groupby(['key1', 'key2'])['data1'].mean()
key1  key2
a     one     0.254570
      two     1.541971
b     one    -0.480680
      two     0.438569
Name: data1, dtype: float64
df.groupby(['key1', 'key2'])[['data1']].mean()
data1
key1 key2
a one 0.254570
two 1.541971
b one -0.480680
two 0.438569

4、用Dicts与Series进行分组

people = pd.DataFrame(np.random.randn(5, 5),
                      columns=['a', 'b', 'c', 'd', 'e'],
                      index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.iloc[2:3, [1, 2]] = np.nan
people
a b c d e
Joe -0.189645 -0.154784 -0.651044 -0.086191 0.962789
Steve -1.508240 0.568177 -0.745980 0.559590 0.090825
Wes -0.090708 NaN NaN -0.473691 -0.089319
Jim 0.557464 0.796324 0.393388 -0.372522 0.927045
Travis 1.367567 0.507116 -0.745044 0.620176 -1.468771
mapping = {
  'a': 'red', 'b': 'red', 'c': 'blue',
           'd': 'blue', 'e': 'red', 'f': 'orange'}
现在,我们可以通过这个dict构建一个数组,然后传递给groupby,但其实我们可以直接传入dict(可以注意到key里有一个’f’,这说明即使有,没有被用到的group key,也是ok的)
by_column = people.groupby(mapping, axis=1)
by_column.sum()
blue red
Joe -0.737235 0.618361
Steve -0.186390 -0.849238
Wes -0.473691 -0.180027
Jim 0.020865 2.280834
Travis -0.124868 0.405912

这种用法同样适用于series,这种情况可以看作是固定大小的映射(fixed-size mapping)

map_series = pd.Series(mapping)
map_series
a       red
b       red
c      blue
d      blue
e       red
f    orange
dtype: object
people.groupby(map_series, axis=1).count()
blue red
Joe 2 3
Steve 2 3
Wes 1 2
Jim 2 3
Travis 2 3

5、用函数进行分组

比起用dict或series定义映射关系,使用python的函数是更通用的方法。任何一个作为group ke

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值