pandas
- numpy能够帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据
pandas的常用数据类型
1. Series 一维,带标签数组
(1). Serise的创建
import string
import numpy as np
import pandas as pd
t=pd.Series(np.arange(10),index=list(string.ascii_uppercase[:10]))
print(t)
print(type(t))
a = {string.ascii_uppercase[i]:i for i in range(10)} #字典推导式创建一个字典a
print(a)
print(pd.Series(a))
a = pd.Series(a,index=list(string.ascii_uppercase[5:15])) #从6开始往后数,不行就为空
print(a)
运行结果:
A 0
B 1
C 2
D 3
E 4
F 5
G 6
H 7
I 8
J 9
dtype: int32
<class 'pandas.core.series.Series'>
{'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9}
A 0
B 1
C 2
D 3
E 4
F 5
G 6
H 7
I 8
J 9
dtype: int64
F 5.0
G 6.0
H 7.0
I 8.0
J 9.0
K NaN
L NaN
M NaN
N NaN
O NaN
dtype: float64
(2). Series切片和索引
- 简单的索引操作:
获取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
import string
import numpy as np
import pandas as pd
t=pd.Series(np.arange(10),index=list(string.ascii_uppercase[:10]))
print(t[2:10:2]) #正常切片
print(t[[2,3,6]]) #两个中括号 意思是取 3,4,7行
print(t[t>4]) #取t大于4的
print(t['F']) #F对应的行信息
运行结果:
C 2
E 4
G 6
I 8
dtype: int32
C 2
D 3
G 6
dtype: int32
F 5
G 6
H 7
I 8
J 9
dtype: int32
5
(3). Series的索引和值
import string
import numpy as np
import pandas as pd
t=pd.Series(np.arange(10),index=list(string.ascii_uppercase[:10]))
print(t.index)
print(type(t.index))
print(t.values)
print(type(t.values))
运行结果:
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], dtype='object')
<class 'pandas.core.indexes.base.Index'>
[0 1 2 3 4 5 6 7 8 9]
<class 'numpy.ndarray'>
(4). 读取外部数据
import pandas as pd
from pymongo import MongoClient
df=pd.read_csv('文件路径')
df = df.sort_values(by='对应文件路径下,某一列的标题',ascending=False) #True是升序,False是降序
2. DataFrame 二维,Series容器
(1). DataFrame的基础属性
import string
import numpy as np
import pandas as pd
t = pd.DataFrame(np.arange(12).reshape((3,4)),index=list(string.ascii_uppercase[:3]),columns=list(string.ascii_uppercase[-4:]))
#string.ascii_uppercase[-4:] 从字母后面取四个标记到相应位置
print(t)
print(t.shape) #行数列数
print(t.dtypes) #裂数据类型
print(t.ndim) #数据维度
print(t.index) #行索引
print(t.columns) #列索引
print(t.values) #对象值,二维ndarray数组
运行结果:
W X Y Z
A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
(3, 4)
W int32
X int32
Y int32
Z int32
dtype: object
2
Index(['A', 'B', 'C'], dtype='object')
Index(['W', 'X', 'Y', 'Z'], dtype='object')
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
(2). DataFrame的整体情况查询
import string
import numpy as np
import pandas as pd
t = pd.DataFrame(np.arange(12).reshape((3,4)),index=list(string.ascii_uppercase[:3]),columns=list(string.ascii_uppercase[-4:]))
#string.ascii_uppercase[-4:] 从字母后面取四个标记到相应位置
print(t)
print(t.head(2)) #显示头部几行,默认5行
print(t.tail(2)) #显示末尾几行,默认5行
print(t.info()) #相关信息概览:行数,列数,列索引,列非空值个数,列类型等
print(t.describe()) #快速综合统计结果:计数,均值,标准差等等
运行结果:
W X Y Z
A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
W X Y Z
A 0 1 2 3
B 4 5 6 7
W X Y Z
B 4 5 6 7
C 8 9 10 11
<class 'pandas.core.frame.DataFrame'>
Index: 3 entries, A to C
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 W 3 non-null int32
1 X 3 non-null int32
2 Y 3 non-null int32
3 Z 3 non-null int32
dtypes: int32(4)
memory usage: 72.0+ bytes
None
W X Y Z
count 3.0 3.0 3.0 3.0
mean 4.0 5.0 6.0 7.0
std 4.0 4.0 4.0 4.0
min 0.0 1.0 2.0 3.0
25% 2.0 3.0 4.0 5.0
50% 4.0 5.0 6.0 7.0
75% 6.0 7.0 8.0 9.0
max 8.0 9.0 10.0 11.0
3. loc与iloc
- df.loc 通过标签索引行数据
- df.iloc 通过位置获取行数据
- loc要写行或者列的名字
import string
import numpy as np
import pandas as pd
t = pd.DataFrame(np.arange(12).reshape((3,4)),index=list(string.ascii_uppercase[:3]),columns=list(string.ascii_uppercase[-4:]))
#string.ascii_uppercase[-4:] 从字母后面取四个标记到相应位置
print(t)
print(t.loc['A','W'])
print(t.loc['A',['W','X']])
print(type(t.loc['A',['W','X']]))
print(t.loc[['A','B'],['W','Z']])
print(t.loc['A':'C',['W','X']]) #特殊这个冒号是完全的闭区间
t.loc['A','W']=10 #改变某一行的数字
print(t)
运行结果:
W X Y Z
A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
0
W 0
X 1
Name: A, dtype: int32
<class 'pandas.core.series.Series'>
W Z
A 0 3
B 4 7
W X
A 0 1
B 4 5
C 8 9
W X Y Z
A 10 1 2 3
B 4 5 6 7
C 8 9 10 11
- iloc写数字
print(t.iloc[1:3,[2,3]])
t.iloc[0,0]=0
print(t)
运行结果:
Y Z
B 6 7
C 10 11
W X Y Z
A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
4. 布尔索引
import string
import numpy as np
import pandas as pd
from pymongo import MongoClient
df = pd.read_csv('./dogNames2.csv')
df = df.sort_values(by='Count_AnimalName',ascending=False)
print(df[(df['Count_AnimalName']>700)&(df['Row_Labels'].str.len()>4)]) #取两列且有限制条件
运行结果:
Row_Labels Count_AnimalName
1156 BELLA 1195
2660 CHARLIE 856
12368 ROCKY 823
8552 LUCKY 723
5. 字符串方法
6. 缺失数据的处理
import string
import numpy as np
import pandas as pd
t = pd.DataFrame(np.arange(12).reshape((3,4)),index=list(string.ascii_uppercase[:3]),columns=list(string.ascii_uppercase[-4:]))
#string.ascii_uppercase[-4:] 从字母后面取四个标记到相应位置
print(t)
t.loc['A':'B','W']=np.nan
print(pd.isnull(t))
# t.dropna(axis=0,how='any',inplace=True)
#删除为nan的那些行或者列 axis是选择轴,
# how是决定是整行都是nan的删除还是部分是nan的就删除
# inplace代表原地修改 如果为True就在原数列上做出改动
print(t)
print(t.fillna(t.mean()))
#用numpy很长的代码替换均值,用pandas一行就解决了 t.fillna()括号中可以直接输入想要替换的数字
print(t['X'].fillna(t['X'].mean()))#只改变其中一行的值
运行结果:
W X Y Z
A 0 1 2 3
B 4 5 6 7
C 8 9 10 11
Y Z
B 6 7
C 10 11
W X Y Z
A True False False False
B True False False False
C False False False False
W X Y Z
A NaN 1 2 3
B NaN 5 6 7
C 8.0 9 10 11
W X Y Z
A 8.0 1 2 3
B 8.0 5 6 7
C 8.0 9 10 11
A 1
B 5
C 9
Name: X, dtype: int32
7. 数据合并之join
#coding=utf-8
import numpy as np
import pandas as pd
import string
df1 = pd.DataFrame(np.ones((2,4)),index=['A','B'],columns=list('abcd'))
df2 = pd.DataFrame(np.zeros((3,3)),index=['A','B','C'],columns=list('xyz'))
df3 = pd.DataFrame(np.arange(9).reshape(3,3),columns=list('fax'))
print(df1)
print(df2)
print(df3)
print(df1.join(df2)) #以df1为准 df2只是加入
print(df2.join(df1)) #同理
print(df1.merge(df3,on='a',how='inner'))
#df3相同列对应行上的数字如果与df1中对应该行上的数字相等,则将df3中相同行的数字放在东方df1后面
print(df1.merge(df3,on='a',how='outer'))
print(df1.merge(df3,on='a',how='left'))
print(df1.merge(df3,on='a',how='right'))
#默认how是inner,outer就是并集,给输出的都输出,没有的用nan表示
#left就是以df1为准,right就是以df3为准
运行结果:
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
f a x
0 0 1 2
1 3 4 5
2 6 7 8
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
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 c d f x
0 1.0 1.0 1.0 1.0 0 2
1 1.0 1.0 1.0 1.0 0 2
a b c d f x
0 1.0 1.0 1.0 1.0 0 2
1 1.0 1.0 1.0 1.0 0 2
2 4.0 NaN NaN NaN 3 5
3 7.0 NaN NaN NaN 6 8
a b c d f x
0 1.0 1.0 1.0 1.0 0 2
1 1.0 1.0 1.0 1.0 0 2
a b c d f x
0 1.0 1.0 1.0 1.0 0 2
1 1.0 1.0 1.0 1.0 0 2
2 4.0 NaN NaN NaN 3 5
3 7.0 NaN NaN NaN 6 8
#显示所有列
pd.set_option('display.max_columns', None)
# #显示所有行
pd.set_option('display.max_rows', None)
- 问题:现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?
'''
现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,
或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?
'''
#美国的星巴克数量和中国的哪个多,
import pandas as pd
from matplotlib import pyplot as plt
file_path = './starbucks_store_worldwide.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
print(df.info())
grouped = df.groupby(by='Country') #文件根据Country来分组
print(grouped)
# DataFrameGroupBy
# 进行遍历
for i,j in grouped: #因为是DataFrame所以可以i j两个都写入
print(i) #国家
print('*'*100)
print(j) #国家对应的全部信息
print('-'*100)
#调用聚合方法
print(grouped['Brand'].count()) #count统计数量
country_count = grouped['Brand'].count()
print(country_count['US'])
print(grouped['Brand'].count()['CN']) #两种写法一样
#统计中国每个省份店铺数量
China_data=df[df['Country']=='CN']
group = China_data.groupby(by='State/Province').count()['Brand']
print(group)
#数据按照多个条件进行分组,返回Series
group = df['Brand'].groupby(by=[df['Country'],df['State/Province']]).count()
print(group,type(group))
#数据按照多个条件进行分组,返回DataFrare
group = df[['Brand']].groupby(by=[df['Country'],df['State/Province']]).count()
print(group,type(group))
#索引的方法和属性
print(group.index)
运行结果:
文件在pythonproject04中,结果太长了这儿不写了
8. 分组和聚合
- 在pandas中类似的分组的操作我们有很简单的方式来完成
df.groupby(by=“columns_name”)
- 如果我们需要对国家和省份进行分组统计,应该怎么操作呢?
grouped = df.groupby(by=[df[“Country”],df[“State/Province”]])
很多时候我们只希望对获取分组之后的某一部分数据,或者说我们只希望对某几列数据进行分组,这个时候我们应该怎么办呢?
- 获取分组之后的某一部分数据:
df.groupby(by=[“Country”,“State/Province”])[“Country”].count()
- 对某几列数据进行分组:
df[“Country”].groupby(by=[df[“Country”],df[“State/Province”]]).count()
上述三个结果一样
9. 索引和复合索引
(1). Series的复合索引
import numpy as np
import pandas as pd
import string
t = pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('wxyz'))
print(t)
t.index=(['A','B','C']) #t中有几个行,对应的index就要有几项
print(t.index)
print(t.reindex(['A','F']))
print(t.set_index('w').index)
print(t.set_index('w',drop=False))
#drop为True的话就就不显示列表中的w了,默认为True
print(t['y'].unique())#unique()一个值只返回一次,重复的就不返回了
print(len(t.set_index('w').index.unique()))
print(len(t.set_index('w').index))
print(t.set_index(['w','x','y']))
print(t.set_index(['w','x','y'],drop=False).index)
运行结果:
w x y z
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
Index(['A', 'B', 'C'], dtype='object')
w x y z
A 0.0 1.0 2.0 3.0
F NaN NaN NaN NaN
Int64Index([0, 4, 8], dtype='int64', name='w')
w x y z
w
0 0 1 2 3
4 4 5 6 7
8 8 9 10 11
[ 2 6 10]
3
3
z
w x y
0 1 2 3
4 5 6 7
8 9 10 11
MultiIndex([(0, 1, 2),
(4, 5, 6),
(8, 9, 10)],
names=['w', 'x', 'y'])
(2). DataFrame的复合索引
import pandas as pd
import string
a = pd.DataFrame({'a':range(7),'b':range(7,0,-1),'c':['one','one','one','two','two','two','two'],'d':list('hjklmno')})
print(a)
b = a.set_index(['c','d']) #将c,d设置成索引
print(b)
c = b['a'] #输出b中有‘a’的一排
print(c)
print(c['two']['m']) #'two'与'm'对应的值
print(c['two']) #two对应的全部值
d = a.set_index(['d','c'])['a'] #d,c按顺序,谁在编码时写前面,谁运行时就在前面
print(d)
运行结果:
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
c d
one h 0
j 1
k 2
two l 3
m 4
n 5
o 6
Name: a, dtype: int64
4
d
l 3
m 4
n 5
o 6
Name: a, dtype: int64
d c
h one 0
j one 1
k one 2
l two 3
m two 4
n two 5
o two 6
Name: a, dtype: int64
10. 代码练习
'''
使用matplotlib呈现出店铺总数排名前10的国家
'''
import pandas as pd
from matplotlib import pyplot as plt
file_path = './starbucks_store_worldwide.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
# print(df.info())
data1 = df.groupby(by='Country').count()['Brand'].sort_values(ascending=False)[:10]
print(data1)
print(data1.index)
print(data1.values)
#分别设置x轴y轴坐标的内容
_x=data1.index
_y=data1.values
#画图
plt.figure(figsize=(20,8),dpi=80)
plt.bar(range(len(_x)),_y,width=0.3,color='orange')
plt.xticks(range(len(_x)),_x)
plt.show()
运行结果:
'''
使用matplotlib呈现出每个中国每个城市的店铺数量
'''
import pandas as pd
from matplotlib import pyplot as plt
file_path = './starbucks_store_worldwide.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
df = df[df['Country']=='CN']
data1 = df.groupby(by='City').count()['Brand'].sort_values(ascending=False)[:25]
#sort_values('某一列的索引',ascending=False/True) 将Brand的值按照升序或者降序排列False是降序,True是升序
#分别设置x轴y轴坐标的内容
_x=data1.index
_y=data1.values
#画图
plt.figure(figsize=(20,12),dpi=80)
plt.barh(range(len(_x)),_y,height=0.3,color='orange')
plt.yticks(range(len(_x)),_x)
plt.show()
运行结果:
'''
现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:
1.不同年份书的数量
'''
import pandas as pd
from matplotlib import pyplot as plt
file_path = './books.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
print(df.info())
data1 = df[pd.notnull(df['original_publication_year'])] #给不是nan的拿出来 因为info后发现年份不是10000
grouped =data1.groupby(by='original_publication_year').count()['title']
print(grouped)
运行结果:
-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
'''
2.不同年份书的平均评分情况
'''
import pandas as pd
from matplotlib import pyplot as plt
file_path = './books.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
# print(df.info())
#不同年份平均评分情况
data1=df[pd.notnull(df['original_publication_year'])] #取年份中没有nan的值
grouped = data1['average_rating'].groupby(by=data1['original_publication_year']).mean()
print(grouped)
_x=grouped.index
_y=grouped.values
#画图
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y) #折线图
plt.xticks(list(range(len(_x)))[::10],_x[::10].astype(int),rotation=45)
plt.show()
运行结果:
11. pandas中的时间序列
- 生成一段时间范围
pd.date_range(start=None, end=None, periods=None, freq=‘D’)
start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索 - 关于频率的更多缩写
- 在DataFrame中使用时间序列
index=pd.date_range("20170101",periods=10,freq='D')
df = pd.DataFrame(np.random.rand(10),index=index)
运行结果:
2017-01-01 0.912321
2017-01-02 0.860915
2017-01-03 0.032489
2017-01-04 0.426890
2017-01-05 0.721920
2017-01-06 0.123992
2017-01-07 0.315079
2017-01-08 0.633535
2017-01-09 0.644058
2017-01-10 0.238628
回到最开始的911数据的案例中,我们可以使用pandas提供的方法把时间字符串转化为时间序列
df[“timeStamp”] = pd.to_datetime(df[“timeStamp”],format="")
format参数大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数,比如包含中文。
12. panads重采样
- 重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样
pandas提供了一个resample的方法来帮助我们实现频率转化
import pandas as pd
import numpy as np
t=pd.DataFrame(np.random.uniform(10,50,(100,1)),index=pd.date_range(start='20170101',periods=100,freq='D'))
print(t.resample('M').mean())
print(t.resample('10D').mean())
运行结果:
0
2017-01-31 30.326141
2017-02-28 26.924476
2017-03-31 27.129261
2017-04-30 32.355953
0
2017-01-01 32.629833
2017-01-11 29.896768
2017-01-21 28.646428
2017-01-31 33.071113
2017-02-10 25.645907
2017-02-20 21.469685
2017-03-02 22.558237
2017-03-12 27.974049
2017-03-22 31.608259
2017-04-01 32.355953
13. 911代码
'''
现在我们有2015到2017年25万条911的紧急电话的数据,
统计出出这些数据中不同类型的紧急情况的次数,
统计出911数据中不同月份电话次数的变化情况
统计出911数据中不同月份不同类型的电话的次数的变化情况
'''
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
df = pd.read_csv('./911.csv')
pd.set_option('display.max_columns',None)
# print(df.head(5))
# print(df.info())
# 获取分裂
temp_list = df['title'].str.split(': ').tolist() #split:用冒号空格来分割获取的title
cate_list = list(set(i[0] for i in temp_list))
print(cate_list)
#构造全为0的数组
zero_df = pd.DataFrame(np.zeros((df.shape[0],len(cate_list))),columns=cate_list) #columns:列索引
#赋值
for cate in cate_list:
zero_df[cate][df['title'].str.contains(cate)] = 1
# 第一次运行是将有fire的赋值,第二次运行是将EMS的赋值,第三次运行是将有Traffic的赋值
print(zero_df)
#统计出这些数据中不同类型的紧急情况的次数
#(问题一方法一)
sum_ret = zero_df.sum(axis=0)
print(sum_ret)
#(问题一方法二)
temp_list = df['title'].str.split(': ').tolist() #split:用冒号空格来分割获取的title
cate_list = [i[0] for i in temp_list]
cate_df = pd.DataFrame(np.array(cate_list).reshape((df.shape[0],1)))
df['cate'] = cate_df #在df中添加一列
# print(df.head(5))
print(df.groupby(by='cate').count()['title'])
运行结果:
['Fire', 'EMS', 'Traffic']
Fire EMS Traffic
0 0.0 1.0 0.0
1 0.0 1.0 0.0
2 1.0 0.0 0.0
3 0.0 1.0 0.0
4 0.0 1.0 0.0
... ... ... ...
249732 0.0 1.0 0.0
249733 0.0 1.0 0.0
249734 0.0 1.0 0.0
249735 1.0 0.0 0.0
249736 0.0 0.0 1.0
[249737 rows x 3 columns]
Fire 37432.0
EMS 124844.0
Traffic 87465.0
dtype: float64
#coding=utf-8
#统计出911数据中不同月份电话次数的变化情况
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
df = pd.read_csv('./911.csv')
pd.set_option('display.max_columns',None)
df['timeStamp'] = pd.to_datetime(df['timeStamp'])
df.set_index('timeStamp',inplace=True) #指定某一列作为index inplace是否是基于原地的修改
#统计出911数据中不同月份电话次数的变化情况
count_by_mouth = df.resample('M').count()['title']
#画图
_x = count_by_mouth.index
_y = count_by_mouth.values
_x = [i.strftime('%Y%m%d') for i in _x] #只输出年月日
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y)
plt.xticks(range(len(_x)),_x,rotation=45)
plt.show()
运行结果:
#统计出911数据中不同月份不同类型的电话的次数的变化情况
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
df = pd.read_csv('./911.csv')
pd.set_option('display.max_columns',None)
df['timeStamp'] = pd.to_datetime(df['timeStamp'])
#添加列 表示分类
temp_list = df['title'].str.split(': ').tolist() #split是根据冒号和空格进行分割
cate_list = [i[0] for i in temp_list]
df['cate'] = pd.DataFrame(np.array(cate_list).reshape((df.shape[0],1))) #添加一列
#把时间字符串转换为时间类型设置为索引
df.set_index('timeStamp',inplace=True) #inplace=True 是代表在原有位置改
plt.figure(figsize=(20,8),dpi=80)
#分组
for group_name,group_data in df.groupby(by='cate'):
count_by_mouth = group_data.resample('M').count()['title']
#画图
_x = count_by_mouth.index
_y = count_by_mouth.values
_x = [i.strftime('%Y%m%d') for i in _x]
plt.plot(range(len(_x)),_y,label=group_name)
#画图
plt.xticks(range(len(_x)),_x,rotation=45)
plt.legend(loc='best') #标注的位置
plt.show()
14. PM2.5代码
#coding[utf-8
#现在我们有北上广、深圳、和沈阳5个城市空气质量数据,
# 请绘制出5个城市的PM2.5随时间的变化情况
import pandas as pd
from matplotlib import pyplot as plt
file_path='./PM2.5/BeijingPM20100101_20151231.csv'
df = pd.read_csv(file_path)
pd.set_option('display.max_columns',None)
#把分开的时间字符串通过PeriodIndex的方法转化为pandas的时间类型
period = pd.PeriodIndex(year=df['year'],month=df['month'],day=df['day'],hour=df['hour'],freq='H')
df['datetime'] = period #添加一列
#把datetime 设置为索引
df.set_index('datetime',inplace=True)
#进行降采样
df = df.resample('7D').mean()
#处理确实数据,删除缺失数据
data = df['PM_US Post']
data_china = df['PM_Dongsi']
#画图
_x = data.index
_y = data.values
_x_china = data_china.index
_y_china = data_china.values
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y,label='US Post')
plt.plot(range(len(_x_china)),_y_china,label='Dongsi')
plt.xticks(range(0,len(_x),10),list(_x)[::10],rotation=45)
plt.legend(loc='best')
plt.show()
运行结果: