Day5
对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?
思路:重新构造一个全为0的数组,列名为分类,如果某一条数据中分类出现过,就让0变为1
#set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
#shape[0]表示行数,shape[1]表示列数
【操作】
#coding=utf-8 |
结果:
Biography Thriller Horror Fantasy ... Comedy Sport Animation Musical
0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
2 0.0 1.0 1.0 0.0 ... 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0 ... 1.0 0.0 1.0 0.0
4 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0
.. ... ... ... ... ... ... ... ... ...
995 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
996 0.0 0.0 1.0 0.0 ... 0.0 0.0 0.0 0.0
997 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
998 0.0 0.0 0.0 0.0 ... 1.0 0.0 0.0 0.0
999 0.0 0.0 0.0 1.0 ... 1.0 0.0 0.0 0.0
[1000 rows x 20 columns]
Biography 81.0
Thriller 195.0
Horror 119.0
Fantasy 101.0
Mystery 106.0
Sci-Fi 120.0
Western 7.0
Family 51.0
History 29.0
Drama 513.0
Adventure 259.0
Action 303.0
Crime 150.0
War 13.0
Music 16.0
Romance 141.0
Comedy 279.0
Sport 18.0
Animation 49.0
Musical 5.0
dtype: float64
数据合并之join
join:默认情况下他是把行索引相同的数据合并到一起
(例如都是A,B,C行,则能合并相同行索引的数据;join():列索引不能相同)
【示例】行索引相同数据(行索引分别为A,B和A,B,C)
#coding=utf-8 |
结果:
a b c d
A 1.0 1.0 1.0 1.0
B 1.0 1.0 1.0 1.0
X Y Z
A 0.0 0.0 0.0
B 0.0 0.0 0.0
C 0.0 0.0 0.0
t1.join(t2):
a b c d X Y Z
A 1.0 1.0 1.0 1.0 0.0 0.0 0.0
B 1.0 1.0 1.0 1.0 0.0 0.0 0.0
t2.join(t1):
X Y Z a b c d
A 0.0 0.0 0.0 1.0 1.0 1.0 1.0
B 0.0 0.0 0.0 1.0 1.0 1.0 1.0
C 0.0 0.0 0.0 NaN NaN NaN NaN
【示例】行索引数据不同(行索引分别为A,B和QWE)
#coding=utf-8 |
结果:
a b c d
A 1.0 1.0 1.0 1.0
B 1.0 1.0 1.0 1.0
X Y Z
Q 0.0 0.0 0.0
W 0.0 0.0 0.0
E 0.0 0.0 0.0
t1.join(t2):
a b c d X Y Z
A 1.0 1.0 1.0 1.0 NaN NaN NaN
B 1.0 1.0 1.0 1.0 NaN NaN NaN
t2.join(t1):
X Y Z a b c d
Q 0.0 0.0 0.0 NaN NaN NaN NaN
W 0.0 0.0 0.0 NaN NaN NaN NaN
E 0.0 0.0 0.0 NaN NaN NaN NaN
数据合并之merge
merge:按照指定的列把数据按照一定的方式合并到一起
默认的合并方式inner,取交集
merge outer,并集,NaN补全
merge left,以左边为准,左边有几行就是几行,NaN补全
merge right,以右边为准,右边有几行就是几行,NaN补全
【操作】
# coding=utf-8 |
结果:
a b c d
A 100.0 1.0 1.0 1.0
B 1.0 1.0 1.0 1.0
f a x
0 0 1 2
1 3 4 5
2 6 7 8
t1.merge内连接 #取并集,a为1时
a b c d f x
0 1.0 1.0 1.0 1.0 0 2
t1.merge外连接 #取交集,剩下nan补全
a b c d f x
0 100.0 1.0 1.0 1.0 NaN NaN
1 1.0 1.0 1.0 1.0 0.0 2.0
2 4.0 NaN NaN NaN 3.0 5.0
3 7.0 NaN NaN NaN 6.0 8.0
t1.merge左连接 #以左边为准
a b c d f x
0 100.0 1.0 1.0 1.0 NaN NaN
1 1.0 1.0 1.0 1.0 0.0 2.0
t1.merge右连接 #以右边为准
a b c d f x
0 1.0 1.0 1.0 1.0 0 2
1 4.0 NaN NaN NaN 3 5
2 7.0 NaN NaN NaN 6 8
现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?
思路:遍历一遍,每次加1 ???
分组和聚合
在pandas中类似的分组的操作我们有很简单的方式来完成
df.groupby(by="columns_name")
那么问题来了,调用groupby方法之后返回的是什么内容?
grouped = df.groupby(by="columns_name")
grouped是一个DataFrameGroupBy对象,是可迭代的
grouped中的每一个元素是一个元组
元组里面是(索引(分组的值),分组之后的DataFrame)
那么,回到之前的问题:
要统计美国和中国的星巴克的数量,我们应该怎么做?
分组之后的每个DataFrame的长度?
长度是一个思路,但是我们有更多的方法(聚合方法)来解决这个问题
要统计美国和中国的星巴克的数量,我们应该怎么做?
【操作】中国和美国星巴克数量
#coding=utf-8 |
结果:
US: 13608
CN 2734
DataFrameGroupBy对象有很多经过优化的方法
如果我们需要对国家和省份进行分组统计,应该怎么操作呢?
【操作】
#coding=utf-8 import pandas as pd china_data = df[df["Country"]=="CN"] |
结果:
State/Province
11 236
12 58
13 24
14 8
15 8
21 57
22 13
23 16
31 551
32 354
33 315
34 26
35 75
36 13
37 75
41 21
42 76
43 35
44 333
45 21
46 16
50 41
51 104
52 9
53 24
61 42
62 3
63 3
64 2
91 162
92 13
Name: Brand, dtype: int64
grouped = df.groupby(by=[df["Country"],df["State/Province"]])
很多时候我们只希望对获取分组之后的某一部分数据,或者说我们只希望对某几列数据进行分组,这个时候我们应该怎么办呢?
获取分组之后的某一部分数据:
df.groupby(by=["Country","State/Province"])["Country"].count()
【示例】
#coding=utf-8 #数据按照多个条件进行分组,返回series |
结果:
Country State/Province
AD 7 1
AE AJ 2
AZ 48
DU 82
FU 2
..
US WV 25
WY 23
VN HN 6
SG 19
ZA GT 3
Name: Brand, Length: 545, dtype: int64
<class 'pandas.core.series.Series'>
对某几列数据进行分组:
df["Country"].groupby(by=[df["Country"],df["State/Province"]]).count()
观察结果,由于只选择了一列数据,所以结果是一个Series类型
如果我想返回一个DataFrame类型呢?
t1=df[["Country"]].groupby(by=[df["Country"],df["State/Province"]]).count()
t2 = df.groupby(by=["Country","State/Province"])[["Country"]].count()
以上的两条命令结果一样
和之前的结果的区别在于当前返回的是一个DataFrame类型
那么问题来了:
和之前使用一个分组条件相比,当前的返回结果的前两列是什么?
是两个索引
索引和复合索引
简单的索引操作:
获取index:df.index
指定index :df.index = ['x','y']
重新设置index : df.reindex(list("abcedf"))
指定某一列作为index :df.set_index("Country",drop=False)
返回index的唯一值:df.set_index("Country").index.unique()
【示例】
#coding=utf-8 |
结果:
A B C D
a 100.0 1.0 1.0 1.0
b 1.0 1.0 1.0 1.0
Index(['a', 'b'], dtype='object')
A B C D
x 100.0 1.0 1.0 1.0
y 1.0 1.0 1.0 1.0
A B C D
a 100.0 1.0 1.0 1.0
f NaN NaN NaN NaN
A B C D
A
100.0 100.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
<bound method Series.unique of x 1.0
y 1.0
Name: B, dtype: float64>
[100.0, 1.0]
假设a为一个DataFrame,那么当a.set_index(["c","d"])即设置两个索引的时候是什么样子的结果呢?
a=pd.DataFrame({'a':range(7),'b':range(7,0,-1),'c':['one','one','one','two','two','two', 'two'],'d': list("hjklmno")})
那么问题来了:我只想取索引h对应值怎么办?
那么:DataFrame是怎样取值呢?
注: #①取b中'one','h'对应的值 |
【示例】
#coding=utf-8 |
结果:
a b c d
0 0 7 one h
1 1 6 one j
2 2 5 one k
3 3 4 two l
4 4 3 two m
5 5 2 two n
6 6 1 two o
a b
c d
one h 0 7
j 1 6
k 2 5
two l 3 4
m 4 3
n 5 2
o 6 1
MultiIndex([('one', 'h'),
('one', 'j'),
('one', 'k'),
('two', 'l'),
('two', 'm'),
('two', 'n'),
('two', 'o')],
names=['c', 'd'])
********
c d
one h 0
j 1
k 2
two l 3
m 4
n 5
o 6
Name: a, dtype: int64
*******
d
h 0
j 1
k 2
Name: a, dtype: int64
a 1
b 6
Name: j, dtype: int64
a b
c
one 1 6
练习:
使用matplotlib呈现出店铺总数排名前10的国家
#coding=utf-8 |
结果:
Country
US 13608
CN 2734
CA 1468
JP 1237
KR 993
GB 901
MX 579
TW 394
TR 326
PH 298
Name: Brand, dtype: int64
使用matplotlib呈现出每个中国每个城市的店铺数量
#coding=utf-8 |
结果:
City
上海市 542
北京市 234
杭州市 117
深圳市 113
广州市 106
* 104
成都市 98
苏州市 90
南京市 73
武汉市 67
宁波市 59
天津市 58
重庆市 41
西安市 40
无锡市 40
佛山市 33
东莞市 31
厦门市 31
青岛市 28
长沙市 26
Name: Brand, dtype: int64
练习:
现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:
不同年份书的数量
#coding=utf-8 |
结果:
original_publication_year
-1750.0 1
-762.0 1
-750.0 2
-720.0 1
-560.0 1
...
2013.0 518
2014.0 437
2015.0 306
2016.0 198
2017.0 11
Name: title, Length: 293, dtype: int64
不同年份书的平均评分情况
#coding=utf-8 |
结果:
original_publication_year
-1750.0 3.630000
-762.0 4.030000
-750.0 4.005000
-720.0 3.730000
-560.0 4.050000
...
2013.0 4.012297
2014.0 3.985378
2015.0 3.954641
2016.0 4.027576
2017.0 4.100909
Name: average_rating, Length: 293, dtype: float64
Day05总结