pandas分组与聚合

应用groupby和聚合函数实现数据的分组与聚合

什么分组与聚合

 

 

分组API

DataFrame.groupby(key, as_index=False)

key:分组的列数据,可以多个

案例:不同颜色的不同笔的价格数据

col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})
col

 

 

col.groupby(["color"])["price1"].mean()      #dataframe
#或
col['price1'].groupby(col['color']).mean()    #serise

 

 

# 分组,数据的结构不变
col.groupby(['color'], as_index=False)['price1'].mean()

 

 

 案例:

星巴克零售店铺数据

现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?

数据来源:https://www.kaggle.com/starbucks/store-locations/data

数据获取

从文件中读取星巴克店铺数据

# 导入星巴克店的数据
starbucks = pd.read_csv("./data/starbucks/directory.csv")
starbucks.head()

进行分组聚合

# 按照国家分组,求出每个国家的星巴克零售店数量
count = starbucks.groupby(['Country']).count()
count['Brand'].plot(kind='bar', figsize=(20, 8))
plt.show()

 

 假设我们加入省市一起进行分组

# 设置多个索引,set_index()
starbucks.groupby(['Country', 'State/Province']).count()
  BrandStore NumberStore NameOwnership TypeStreet AddressCityPostcodePhone NumberTimezoneLongitudeLatitude
CountryState/Province           
AD7 1 1 1 1 1 1 1 1 1 1 1
AEAJ 2 2 2 2 2 2 0 0 2 2 2
AZ 48 48 48 48 48 48 7 20 48 48 48
DU 82 82 82 82 82 82 16 50 82 82 82
FU 2 2 2 2 2 2 1 0 2 2 2
RK 3 3 3 3 3 3 0 3 3 3 3
SH 6 6 6 6 6 6 0 5 6 6 6
UQ 1 1 1 1 1 1 0 0 1 1 1
ARB 21 21 21 21 21 21 18 5 21 21 21
C 73 73 73 73 73 73 71 24 73 73 73
M 5 5 5 5 5 5 2 0 5 5 5
S 3 3 3 3 3 3 3 0 3 3 3
X 6 6 6 6 6 6 6 0 6 6 6
AT3 1 1 1 1 1 1 1 1 1 1 1
5 3 3 3 3 3 3 3 3 3 3 3
9 14 14 14 14 14 14 14 13 14 14 14
AUNSW 9 9 9 9 9 9 9 0 9 9 9
QLD 8 8 8 8 8 8 8 0 8 8 8
VIC 5 5 5 5 5 5 5 0 5 5 5
AWAW 3 3 3 3 3 3 0 3 3 3 3
AZBA 3 3 3 3 3 3 2 3 3 3 3
SAB 1 1 1 1 1 1 1 1 1 1 1
BEBE 4 4 4 4 4 4 4 0 4 4 4
VAN 1 1 1 1 1 1 1 0 1 1 1
VBR 2 2 2 2 2 2 2 0 2 2 2
VLG 10 10 10 10 10 10 10 1 10 10 10
WAL 2 2 2 2 2 2 2 0 2 2 2
BG2 1 1 1 1 1 1 0 0 1 1 1
23 4 4 4 4 4 4 1 0 4 4 4
BH13 16 16 16 16 16 16 2 10 16 16 16
...... ... ... ... ... ... ... ... ... ... ... ...
USMO 188 188 188 188 188 188 188 175 188 188 188
MS 32 32 32 32 32 32 32 28 32 32 32
MT 36 36 36 36 36 36 36 36 36 36 36
NC 338 338 338 338 338 338 338 322 338 338 338
ND 13 13 13 13 13 13 13 13 13 13 13
NE 58 58 58 58 58 58 58 56 58 58 58
NH 29 29 29 29 29 29 29 27 29 29 29
NJ 261 261 261 261 261 261 261 250 261 261 261
NM 76 76 76 76 76 76 76 75 76 76 76
NV 253 253 253 253 253 253 253 230 253 253 253
NY 645 645 645 645 645 645 645 627 645 645 645
OH 378 378 378 378 378 378 377 357 378 378 378
OK 79 79 79 79 79 79 79 76 79 79 79
OR 359 359 359 359 359 359 359 343 359 359 359
PA 357 357 357 357 357 357 357 350 357 357 357
RI 27 27 27 27 27 27 27 27 27 27 27
SC 131 131 131 131 131 131 131 125 131 131 131
SD 25 25 25 25 25 25 25 25 25 25 25
TN 180 180 180 180 180 180 180 162 180 180 180
TX 1042 1042 1042 1042 1042 1042 1042 1002 1042 1042 1042
UT 101 101 101 101 101 101 101 99 101 101 101
VA 432 432 432 432 432 432 432 413 432 432 432
VT 8 8 8 8 8 8 8 8 8 8 8
WA 757 757 757 757 757 757 757 738 757 757 757
WI 145 145 145 145 145 145 145 144 145 145 145
WV 25 25 25 25 25 25 25 23 25 25 25
WY 23 23 23 23 23 23 23 22 23 23 23
VNHN 6 6 6 6 6 6 6 6 6 6 6
SG 19 19 19 19 19 19 19 17 19 19 19
ZAGT 3 3 3 3 3 3 3 2 3 3 3

545 rows × 11 columns

 

 

仔细观察这个结构,与我们前面讲的哪个结构类似??

与前面的MultiIndex结构类似

 

 

 

电影数据案例分析:

需求

现在我们有一组从2006年到2016年1000部最流行的电影数据

数据来源:https://www.kaggle.com/damianpanek/sunday-eda/data

  • 问题1:我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?
  • 问题2:对于这一组电影数据,如果我们想rating,runtime的分布情况,应该如何呈现数据?
  • 问题3:对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?

导入数据:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
movie = pd.read_csv("./data/IMDB-Movie-Data.csv")
movie.head()

 

 

 

问题一:

我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?

得出评分的平均分  ------------使用mean函数

movie["Rating"].mean()

 

 

 

得出导演人数信息

求出唯一值,然后进行形状获取

np.unique(movie["Director"]).shape[0]

 

 

 

问题二:

对于这一组电影数据,如果我们想Rating,Runtime (Minutes)的分布情况,应该如何呈现数据?

  • 直接呈现,以直方图的形式
# Rating分布

movie["Rating"].plot(kind="hist",figsize=(20,8))

 

 

 这样的直方图刻度不会对齐,不明显

于是:

# Rating分布

# 1.创建画布
plt.figure(figsize=(20, 8), dpi=100)

# 2.绘制图像
plt.hist(movie["Rating"].values, bins=20)

# 2.1 添加刻度
max_ = movie["Rating"].max()
min_ = movie["Rating"].min()

t1 = np.linspace(min_, max_, num=21)

plt.xticks(t1)

# 2.2 添加网格
plt.grid()

# 3.显示
plt.show()

 

 

 

# Runtime (Minutes)分布

# 1.创建画布
plt.figure(figsize=(20, 8), dpi=100)

# 2.绘制图像
plt.hist(movie["Runtime (Minutes)"].values, bins=20)

# 2.1 添加刻度
max_ = movie["Runtime (Minutes)"].max()
min_ = movie["Runtime (Minutes)"].min()

t1 = np.linspace(min_, max_, num=21)

plt.xticks(t1)

# 2.2 添加网格
plt.grid()

# 3.显示
plt.show()

 

 

 

问题三:

对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?

思路

  • 1、创建一个全为0的dataframe,列索引置为电影的分类,temp_df
  • 2、遍历每一部电影,temp_df中把分类出现的列的值置为1
  • 3、求和

创建一个全为0的dataframe,列索引置为电影的分类,temp_df

# 进行字符串分割
temp_list = [i.split(",") for i in df["Genre"]]
temp_list

 

 

 

# 获取电影的分类
genre_list = np.unique([i for j in temp_list for i in j]) 
genre_list

 

 

# 增加新的列
temp_df = pd.DataFrame(np.zeros([df.shape[0],genre_list.shape[0]]),columns=genre_list)

 

 遍历每一部电影,temp_df中把分类出现的列的值置为1

for i in range(1000):
    temp_movie.ix[i, temp_list[i]] = 1
temp_movie.head()

 

 求和,绘图

genre = temp_movie.sum().sort_values(ascending=False)     #ascending=False是降序
genre

 

 

genre.plot(kind="bar", colormap="cool", figsize=(20, 8), fontsize=16)

 

posted @ 2021-01-26 21:32  ziyuliu  阅读(154)  评论(0编辑  收藏  举报