利用Python进行数据分析--数据聚合与分组运算
2014-11-18 23:44
881 查看
转载自:http://blog.csdn.net/ssw_1990/article/details/22422971
1、quantile计算Series或DataFrame列的样本分位数:
[python] view
plaincopy
>>> import numpy as np
>>> import pandas as pd
>>> 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.228507 -1.820634 a one
1 -1.253050 0.285551 a two
2 1.412322 1.985010 b one
3 1.080160 -0.125354 b two
4 0.077132 -1.168355 a one
>>> grouped = df.groupby('key1')
>>> grouped
<pandas.core.groupby.DataFrameGroupBy object at 0x03EB3510>
>>> grouped['data1']
<pandas.core.groupby.SeriesGroupBy object at 0x03EB3490>
>>> grouped['data1'].quantile(0.9)
key1
a 0.198232
b 1.379106
dtype: float64
说明:
(1)虽然quantile并没有明确地实现于GroupBy,但它是一个Series方法,所以这里是能用的。实际上,GroupBy会高效地对Series进行切片,然后对各片调用piece.quantile(0.9),最后将这些结果组装成最终结果。
(2)如果传入的百分位上没有值,则quantile会进行线性插值。
(3)四分位数(Quartile),即统计学中,把所有数值由小到大排列并分成四等份,处于三个分割点位置的得分就是四分位数。
(4)线性插值经常用于补充表格中的间隔部分。假设一个表格列出了一个国家 1970年、1980年、1990年以及 2000年的人口,那么如果需要估计 1994年的人口的话,线性插值就是一种简便的方法。
2、有些方法(如describe)也是可以用在这里的,即时严格来讲,它们并非聚合运算:
[python] view
plaincopy
>>> grouped.describe()
data1 data2
key1
a count 3.000000 3.000000
mean -0.315804 -0.901146
std 0.815200 1.078218
min -1.253050 -1.820634
25% -0.587959 -1.494495
50% 0.077132 -1.168355
75% 0.152819 -0.441402
max 0.228507 0.285551
b count 2.000000 2.000000
mean 1.246241 0.929828
std 0.234874 1.492253
min 1.080160 -0.125354
25% 1.163201 0.402237
50% 1.246241 0.929828
75% 1.329282 1.457419
max 1.412322 1.985010
经过优化的groupby的方法
3、面向列的多函数应用
对Series或DataFrame列的聚合运算其实就是使用aggregate(使用自定义函数)或者调用mean、std之类的方法。然而,可能希望对不同的列使用不同的聚合函数,或一次应用多个函数,其实这也好办。根据sex和smoker对tips进行分组:
[python] view
plaincopy
>>> import numpy as np
>>> import pandas as pd
>>> tips = pd.read_csv('tips.csv')
>>> # 添加“小费占总额百分比”的列
>>> tips['tip_pct'] = tips['tip']/tips['total_bill']
>>> tips[:6]
total_bill tip sex smoker day time size tip_pct
0 16.99 1.01 Female No Sun Dinner 2 0.059447
1 10.34 1.66 Male No Sun Dinner 3 0.160542
2 21.01 3.50 Male No Sun Dinner 3 0.166587
3 23.68 3.31 Male No Sun Dinner 2 0.139780
4 24.59 3.61 Female No Sun Dinner 4 0.146808
5 25.29 4.71 Male No Sun Dinner 4 0.186240
[python] view
plaincopy
>>> grouped = tips.groupby(['sex', 'smoker'])
>>> grouped_pct = grouped['tip_pct']
>>> grouped
<pandas.core.groupby.DataFrameGroupBy object at 0x03EB3050>
>>> grouped_pct
<pandas.core.groupby.SeriesGroupBy object at 0x03EB3290>
>>> grouped_pct.agg('mean')
sex smoker
Female No 0.156921
Yes 0.182150
Male No 0.160669
Yes 0.152771
Name: tip_pct, dtype: float64
如果传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名:
[python] view
plaincopy
>>> grouped_pct.agg(['mean', 'std'])
mean std
sex smoker
Female No 0.156921 0.036421
Yes 0.182150 0.071595
Male No 0.160669 0.041849
Yes 0.152771 0.090588
如果传入的是一个由(name, function)元组组成的列表,则各元组的第一个元素就会被用作DataFrame的列名(可以将这种二元元组列表看做一个有序映射):
[python] view
plaincopy
>>> grouped_pct.agg([('mean', 'std'), ('bar', np.std)])
mean bar
sex smoker
Female No 0.036421 0.036421
Yes 0.071595 0.071595
Male No 0.041849 0.041849
Yes 0.090588 0.090588
4、假设我们想要对tip_pct和total_bill列计算三个统计信息:
[python] view
plaincopy
>>> functions = ['count', 'mean', 'max']
>>> result = grouped['tip_pct', 'total_bill'].agg(functions)
>>> result
tip_pct total_bill
count mean max count mean max
sex smoker
Female No 54 0.156921 0.252672 54 18.105185 35.83
Yes 33 0.182150 0.416667 33 17.977879 44.30
Male No 97 0.160669 0.291990 97 19.791237 48.33
Yes 60 0.152771 0.710345 60 22.284500 50.81
说明:
(1)对于DataFrame,可以定义一组应用于全部列的函数,或不同的列应用不同的函数。
(2)结果DataFrame拥有层次化的列,这相当于分别对各列进行聚合,然后用concat将结果组装到一起(列名用作keys参数)。
[python] view
plaincopy
>>> result['tip_pct']
count mean max
sex smoker
Female No 54 0.156921 0.252672
Yes 33 0.182150 0.416667
Male No 97 0.160669 0.291990
Yes 60 0.152771 0.710345
跟前面一样,这里也可以传入带有自定义名称的元组列表:
[python] view
plaincopy
>>> ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)]
>>> grouped['tip_pct', 'total_bill'].agg(ftuples)
tip_pct total_bill
Durchschnitt Abweichung Durchschnitt Abweichung
sex smoker
Female No 0.156921 0.001327 18.105185 53.092422
Yes 0.182150 0.005126 17.977879 84.451517
Male No 0.160669 0.001751 19.791237 76.152961
Yes 0.152771 0.008206 22.284500 98.244673
如果想要对不同的列应用不同的函数,具体的办法是向agg传入一个从列名映射到函数的字典:
[python] view
plaincopy
>>> grouped.agg({'tip':np.max, 'size':'sum'})
tip size
sex smoker
Female No 5.2 140
Yes 6.5 74
Male No 9.0 263
Yes 10.0 150
>>> grouped.agg({'tip_pct':['min', 'max', 'mean', 'std'],
... 'size':'sum'})
tip_pct size
min max mean std sum
sex smoker
Female No 0.056797 0.252672 0.156921 0.036421 140
Yes 0.056433 0.416667 0.182150 0.071595 74
Male No 0.071804 0.291990 0.160669 0.041849 263
Yes 0.035638 0.710345 0.152771 0.090588 150
说明:
只有将多个函数应用到至少一列时,DataFrame才会拥有层次化的列。
5、以“无索引”的形式返回聚合数据
到目前为止,所有示例中的聚合数据都有由唯一的分组键组成的索引(可能还是层次化的)。由于并不总是需要如此,所以你可以向groupby传入as_index=False以禁用该功能。
[python] view
plaincopy
>>> tips.groupby(['sex', 'smoker'], as_index=False).mean()
sex smoker total_bill tip size tip_pct
0 Female No 18.105185 2.773519 2.592593 0.156921
1 Female Yes 17.977879 2.931515 2.242424 0.182150
2 Male No 19.791237 3.113402 2.711340 0.160669
3 Male Yes 22.284500 3.051167 2.500000 0.152771
>>> tips.groupby(['sex', 'smoker'], as_index=True).mean()
total_bill tip size tip_pct
sex smoker
Female No 18.105185 2.773519 2.592593 0.156921
Yes 17.977879 2.931515 2.242424 0.182150
Male No 19.791237 3.113402 2.711340 0.160669
Yes 22.284500 3.051167 2.500000 0.152771
6、参考文献
[1] 四分位数:http://baike.baidu.com/link?url=c744i_30IlKA4Jck9nB-Ti5vn3wJnJUGuHO96O_9ZQYQHi_ai42kQtmM3v-J79MS
[2] 线性插值: http://zh.wikipedia.org/wiki/%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC
[3]《利用Python进行数据分析》
1、quantile计算Series或DataFrame列的样本分位数:
[python] view
plaincopy
>>> import numpy as np
>>> import pandas as pd
>>> 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.228507 -1.820634 a one
1 -1.253050 0.285551 a two
2 1.412322 1.985010 b one
3 1.080160 -0.125354 b two
4 0.077132 -1.168355 a one
>>> grouped = df.groupby('key1')
>>> grouped
<pandas.core.groupby.DataFrameGroupBy object at 0x03EB3510>
>>> grouped['data1']
<pandas.core.groupby.SeriesGroupBy object at 0x03EB3490>
>>> grouped['data1'].quantile(0.9)
key1
a 0.198232
b 1.379106
dtype: float64
说明:
(1)虽然quantile并没有明确地实现于GroupBy,但它是一个Series方法,所以这里是能用的。实际上,GroupBy会高效地对Series进行切片,然后对各片调用piece.quantile(0.9),最后将这些结果组装成最终结果。
(2)如果传入的百分位上没有值,则quantile会进行线性插值。
(3)四分位数(Quartile),即统计学中,把所有数值由小到大排列并分成四等份,处于三个分割点位置的得分就是四分位数。
(4)线性插值经常用于补充表格中的间隔部分。假设一个表格列出了一个国家 1970年、1980年、1990年以及 2000年的人口,那么如果需要估计 1994年的人口的话,线性插值就是一种简便的方法。
2、有些方法(如describe)也是可以用在这里的,即时严格来讲,它们并非聚合运算:
[python] view
plaincopy
>>> grouped.describe()
data1 data2
key1
a count 3.000000 3.000000
mean -0.315804 -0.901146
std 0.815200 1.078218
min -1.253050 -1.820634
25% -0.587959 -1.494495
50% 0.077132 -1.168355
75% 0.152819 -0.441402
max 0.228507 0.285551
b count 2.000000 2.000000
mean 1.246241 0.929828
std 0.234874 1.492253
min 1.080160 -0.125354
25% 1.163201 0.402237
50% 1.246241 0.929828
75% 1.329282 1.457419
max 1.412322 1.985010
函数名 | 说明 |
count | 分组中非NA值的数量 |
sum | 非NA值的和 |
mean | 非NA值的平均数 |
median | 非NA值的算术中位数 |
std、var | 无偏(分母为n-1)标准差和方差 |
min、max | 非NA值的最小值和最大值 |
prod | 非NA值的积 |
first、last | 第一个和最后一个非NA值 |
对Series或DataFrame列的聚合运算其实就是使用aggregate(使用自定义函数)或者调用mean、std之类的方法。然而,可能希望对不同的列使用不同的聚合函数,或一次应用多个函数,其实这也好办。根据sex和smoker对tips进行分组:
[python] view
plaincopy
>>> import numpy as np
>>> import pandas as pd
>>> tips = pd.read_csv('tips.csv')
>>> # 添加“小费占总额百分比”的列
>>> tips['tip_pct'] = tips['tip']/tips['total_bill']
>>> tips[:6]
total_bill tip sex smoker day time size tip_pct
0 16.99 1.01 Female No Sun Dinner 2 0.059447
1 10.34 1.66 Male No Sun Dinner 3 0.160542
2 21.01 3.50 Male No Sun Dinner 3 0.166587
3 23.68 3.31 Male No Sun Dinner 2 0.139780
4 24.59 3.61 Female No Sun Dinner 4 0.146808
5 25.29 4.71 Male No Sun Dinner 4 0.186240
[python] view
plaincopy
>>> grouped = tips.groupby(['sex', 'smoker'])
>>> grouped_pct = grouped['tip_pct']
>>> grouped
<pandas.core.groupby.DataFrameGroupBy object at 0x03EB3050>
>>> grouped_pct
<pandas.core.groupby.SeriesGroupBy object at 0x03EB3290>
>>> grouped_pct.agg('mean')
sex smoker
Female No 0.156921
Yes 0.182150
Male No 0.160669
Yes 0.152771
Name: tip_pct, dtype: float64
如果传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名:
[python] view
plaincopy
>>> grouped_pct.agg(['mean', 'std'])
mean std
sex smoker
Female No 0.156921 0.036421
Yes 0.182150 0.071595
Male No 0.160669 0.041849
Yes 0.152771 0.090588
如果传入的是一个由(name, function)元组组成的列表,则各元组的第一个元素就会被用作DataFrame的列名(可以将这种二元元组列表看做一个有序映射):
[python] view
plaincopy
>>> grouped_pct.agg([('mean', 'std'), ('bar', np.std)])
mean bar
sex smoker
Female No 0.036421 0.036421
Yes 0.071595 0.071595
Male No 0.041849 0.041849
Yes 0.090588 0.090588
4、假设我们想要对tip_pct和total_bill列计算三个统计信息:
[python] view
plaincopy
>>> functions = ['count', 'mean', 'max']
>>> result = grouped['tip_pct', 'total_bill'].agg(functions)
>>> result
tip_pct total_bill
count mean max count mean max
sex smoker
Female No 54 0.156921 0.252672 54 18.105185 35.83
Yes 33 0.182150 0.416667 33 17.977879 44.30
Male No 97 0.160669 0.291990 97 19.791237 48.33
Yes 60 0.152771 0.710345 60 22.284500 50.81
说明:
(1)对于DataFrame,可以定义一组应用于全部列的函数,或不同的列应用不同的函数。
(2)结果DataFrame拥有层次化的列,这相当于分别对各列进行聚合,然后用concat将结果组装到一起(列名用作keys参数)。
[python] view
plaincopy
>>> result['tip_pct']
count mean max
sex smoker
Female No 54 0.156921 0.252672
Yes 33 0.182150 0.416667
Male No 97 0.160669 0.291990
Yes 60 0.152771 0.710345
跟前面一样,这里也可以传入带有自定义名称的元组列表:
[python] view
plaincopy
>>> ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)]
>>> grouped['tip_pct', 'total_bill'].agg(ftuples)
tip_pct total_bill
Durchschnitt Abweichung Durchschnitt Abweichung
sex smoker
Female No 0.156921 0.001327 18.105185 53.092422
Yes 0.182150 0.005126 17.977879 84.451517
Male No 0.160669 0.001751 19.791237 76.152961
Yes 0.152771 0.008206 22.284500 98.244673
如果想要对不同的列应用不同的函数,具体的办法是向agg传入一个从列名映射到函数的字典:
[python] view
plaincopy
>>> grouped.agg({'tip':np.max, 'size':'sum'})
tip size
sex smoker
Female No 5.2 140
Yes 6.5 74
Male No 9.0 263
Yes 10.0 150
>>> grouped.agg({'tip_pct':['min', 'max', 'mean', 'std'],
... 'size':'sum'})
tip_pct size
min max mean std sum
sex smoker
Female No 0.056797 0.252672 0.156921 0.036421 140
Yes 0.056433 0.416667 0.182150 0.071595 74
Male No 0.071804 0.291990 0.160669 0.041849 263
Yes 0.035638 0.710345 0.152771 0.090588 150
说明:
只有将多个函数应用到至少一列时,DataFrame才会拥有层次化的列。
5、以“无索引”的形式返回聚合数据
到目前为止,所有示例中的聚合数据都有由唯一的分组键组成的索引(可能还是层次化的)。由于并不总是需要如此,所以你可以向groupby传入as_index=False以禁用该功能。
[python] view
plaincopy
>>> tips.groupby(['sex', 'smoker'], as_index=False).mean()
sex smoker total_bill tip size tip_pct
0 Female No 18.105185 2.773519 2.592593 0.156921
1 Female Yes 17.977879 2.931515 2.242424 0.182150
2 Male No 19.791237 3.113402 2.711340 0.160669
3 Male Yes 22.284500 3.051167 2.500000 0.152771
>>> tips.groupby(['sex', 'smoker'], as_index=True).mean()
total_bill tip size tip_pct
sex smoker
Female No 18.105185 2.773519 2.592593 0.156921
Yes 17.977879 2.931515 2.242424 0.182150
Male No 19.791237 3.113402 2.711340 0.160669
Yes 22.284500 3.051167 2.500000 0.152771
6、参考文献
[1] 四分位数:http://baike.baidu.com/link?url=c744i_30IlKA4Jck9nB-Ti5vn3wJnJUGuHO96O_9ZQYQHi_ai42kQtmM3v-J79MS
[2] 线性插值: http://zh.wikipedia.org/wiki/%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC
[3]《利用Python进行数据分析》
相关文章推荐
- 利用Python进行数据分析--数据聚合与分组运算1
- 利用python进行数据分析-数据聚合与分组运算1
- 利用python进行数据分析-数据聚合与分组运算2
- 利用Python进行数据分析--数据聚合与分组运算
- 利用python进行数据分析之数据聚合和分组运算
- 利用python进入数据分析之数据聚合与数据分组运算
- Python 数据分析(二 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识
- 利用python进行数据分析-pandas.concat/subplots/gropuby/pivot_table,多文件整合、聚合、分组,子图
- Python 数据分析(二 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识
- python数据分析之:数据聚合与分组运算
- python/pandas数据分析(十五)-聚合与分组运算实例
- 利用Python进行数据分析--时间序列
- 利用Python进行数据分析--绘图和可视化
- 利用Python进行数据分析---ch02《MovieLens 1M数据集(下)》读书笔记
- 利用Python进行数据分析--数据规整化:清理、转换、合并、重塑
- 利用Python进行数据分析--数据加载、存储与文件格式
- 利用Python进行数据分析——数据规整化:清理、转换、合并、重塑(七)(1)
- 利用Python进行数据分析——第一章:重要Python库安装配置
- 利用Python进行数据分析笔记(一
- 利用python进行数据分析笔记