pandas及与matplotlib结合

前言:为什么要学pandas在这里插入图片描述

一、pandas的series(一维带标签)

1.Series数组的创建

t1 = pd.Series([1,2,15,48,6],index=list("abcde"))

在这里插入图片描述
:其中第一列为所带标签,未指定时默认为索引

②通过字典创建series,其中索引就是字典中的键

temp_dic = {"name":"xiaohong","id":3,"tel":1008611,"age":18}
t = pd.Series(temp_dic)

在这里插入图片描述
在这里插入图片描述
series数组一般必要情况下会自动转换数据类型,其转换数据类型的方法与numpy一样
在这里插入图片描述

2.series的索引和值

t.index
在这里插入图片描述
t.values
在这里插入图片描述

二、pandas的DataFrame(二维Series容器)

1.pandas读取外部数据

(1)读取csv中数据

data_csv = "D:\QQ\数据分析课件数据\dogNames2.csv"
df = pd.read_csv(data_csv)
print(df)

在这里插入图片描述
(2)读取mysql中数据

pd.read_sql(sql_sentence,connection)

(3)更多读取方法
在这里插入图片描述

2.DataFrame的创建

(1)默认索引下

pd.DataFrame(np.arange(12).reshape((3,4)))

在这里插入图片描述
(2)自定义索引

pd.DataFrame(np.arange(12).reshape((3,4)),index=list("abc"),columns=list("WXYZ"))
# index=list("abc")表示自定义列索引
# columns=list("WXYZ"))表示自定义行索引

在这里插入图片描述
在这里插入图片描述
(3)字典式创建

d1={"name":["xiaohong","xiaoming"],"age":[20,32],"tel":[10086,10045]}
t = pd.DataFrame(d1)

在这里插入图片描述
其中字典的键表示DataFrame中的行索引

(4)列表式创建

 d2 = [{"name":"xiaohong","age":"32","tel":10010},{"name":"xiaomin","age":"25","tel":10052},{ "name":"xiaohua","age":15}]
 pd.DataFrame(d2)

在这里插入图片描述
未定义数据时默认NAN

另:DataFrame对象的类型:pandas.core.frame.DataFrame

3.DataFrame的基础性质

print(t.shape)  # 行数列数
print(t.dtypes)  #列数据类型
print(t.ndim)  # 数据维度
print(t.index)  # 行索引
print(t.columns) # 列索引
print(t.values) # 对象值,二维ndarray数组
print(t.head(3)) # 显示头部几行,默认5行
print(t.tail(3)) # 显示末尾几行,默认5行
print(t.info()) # 相关信息概览:行数,列数,列索引,列非空值个数,列类型,行类型,内存占用
print(t.describe()) # 快速综合统计结果:计数,均值,标准差,最大值,四分位数,最小值

排序方法:df.sort_values(by="Count_AnimalName",ascending=False)

其中:by=表示按照什么排序,ascending=True时表示升序,False表示降序

import pandas as pd
data_csv = "D:\QQ\数据分析课件数据\dogNames2.csv"
df = pd.read_csv(data_csv)

# dataFrame中的排序方法:by=表示按照什么排序,ascending=True时表示升序,False表示降序
df = df.sort_values(by="Count_AnimalName",ascending=False)

print(df.head())
# print(df.info())

4.DataFrame的索引

(1)普通索引

pandas去行或列索引的注意点:
1.方括号写数组,表示取行,对行进行操作
2.写字符串,表示的取列索引,对列索引进行操作

print(df[:20])
print(df["Row_Labels"])
print(type(df["Row_Labels"]))  #<class 'pandas.core.series.Series'>

print(df[:20]["Row_Labels"])  #取前20行,"Row_Labels"列

(2)经过pandas优化过选择方式:

前景:
因为普通索引用字符串表示取列索引,而有些行索引也为字符串,这时就需要loc[“A”]表示取行索引为"A"的数据

1.df.loc通过标签索引行数据

t.loc["A","Z"]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.df.iloc通过位置获取行数据

 t.iloc[1]

在这里插入图片描述
赋值:t.iloc[1:,:2]=12
在这里插入图片描述
在这里插入图片描述
其中转换为nan时自动转型

(3)pandas之布尔索引

索引为bool类型:True,False

print(df[df["Count_AnimalName"]>50])
print(df[(df["Count_AnimalName"]>50)&(df["Count_AnimalName"]<80)])
print(df[(df["Count_AnimalName"]>90)|(df["Count_AnimalName"]<2)])
# &表示且,|表示或

# 获取狗的名字的字符串长度大于4且次数超过60
print(df[(df["Count_AnimalName"]>50)&(df["Row_Labels"].str.len()>4)])

另:pandas字符串方法:

如:df["Row_Labels"].str.len()
在这里插入图片描述

5.数据缺失的处理

数据缺失:
1.None,在pandas下是NaN和(np.nan)一样
2.让其为0(有时有意义,不为缺失数据)

缺失数据的处理:
1.NaN数据:先判断是否有NaN:pd.isnull(df),pd.notnull(df)

pd.isnull(t)
pd.notnull(t)
pd.notnull(t["W"])
 t[pd.notnull(t["W"])]  # 布尔索引

在这里插入图片描述

处理方式1:删除NaN所在行列dropna(axis=0,how=‘any’,inplace=False)
  其中{   axis=0表示按轴为0处理,how='any’表示只要该行有nan就删除,而how='all’表示全为nan时才删除,inplace=True表示原地替换相当于赋值给自己df   }
在这里插入图片描述
在这里插入图片描述

处理方式2:填充数据,t.fillna(t.mean()),t.fillna(t.median()),t.fillna(0)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.处理为0的数据:t[t==0]=np.nan ,再按nan数据类型处理缺失数据

原因:计算平均值时,nan是不参与计算的,但是0会
在这里插入图片描述

三、pandas的时间序列

1.生成一段时间范围

在这里插入图片描述
其中start=表示起始日期,end=表示末位日期,periods=表示时间索引的个数,freq=表示时间索引的频率,该方法的返回值是一个时间索引

关于频率的更多缩写:(可以使用:10D)
在这里插入图片描述

 pd.date_range(start='20170101',end='20170707',freq='10D')
 pd.date_range(start='20170101',end='20170707',periods=10)

在这里插入图片描述

2.DataFrame中使用时间序列

(1)
在这里插入图片描述
在这里插入图片描述
(2)

period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H")

该方法可以将多个零散的数据整合成一个时间序列

3.pandas重采样

在这里插入图片描述
在这里插入图片描述

t.resample("M").mean()
 t.resample("10D").count()

在这里插入图片描述

4.举例:

(1)统计911不同月份电话次数的变化情况

# @XST1520203418
# 要天天开心呀

import numpy as np
import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

file_path = "D:\ProgramData\课件数据\datasourse\911\911.csv"
df = pd.read_csv(file_path)

# 字符串时间化
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
# print(df.head(1).T)
df.set_index("timeStamp",inplace=True)
# print(df.head(1).T)


# 统计911数据中不同月份电话次数
count_by_month = df.resample("M").count()["title"]
# print(count_by_month)


# 作图
p.figure(figsize=(15,8),dpi=80)

x = count_by_month.index
y = count_by_month.values
p.plot(x,y)

p.xticks(x[::5],rotation=45)

p.show()

在这里插入图片描述
(2)

# @XST1520203418
# 要天天开心呀

# 统计911不同月份不同类型的电话次数变化情况
import numpy as np
import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

file_path = "D:\ProgramData\课件数据\datasourse\911\911.csv"
df = pd.read_csv(file_path)

# 把时间字符串转换为时间类型设置为索引
df["timeStamp"] = pd.to_datetime(df["timeStamp"])

# 添加列,表示分类
temp_list = df["title"].str.split(":").tolist()
type_list = [i[0] for i in temp_list]
df["type"] = pd.DataFrame(np.array(type_list).reshape((df.shape[0],1)))

df.set_index("timeStamp",inplace=True)

p.figure(figsize=(15, 8), dpi=80)
# 分组
for group_name,group_data in df.groupby(by="type"):
    # 对不同的类进行绘图
    count_by_month = group_data.resample("M").count()["title"]
    # print(count_by_month)
    # 作图
    x = count_by_month.index
    y = count_by_month.values
    p.plot(x, y, label=group_name)



p.xticks(x[::5], rotation=45)
# 添加图例
p.legend(loc="best")
p.show()

在这里插入图片描述

四、统计

1.练习:统计电影信息(runtime,rating):直方图

(1)runtime

import pandas as pd
from matplotlib import pyplot as p

file_path = "D:\ProgramData\课件数据\datasets_IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
# print(df.head(1))
# print(df.info())

# runtime分布情况:选择直方图
runtime_data = df["Runtime (Minutes)"].values
t2 = df["Rating"].tolist()

max_runtime = runtime_data.max()
min_runtime = runtime_data.min()

# 计算组数
num_bin = (max_runtime-min_runtime)//5

# 设置图形大小
p.figure(figsize=(15,8),dpi=80)

p.hist(runtime_data,num_bin)

p.xticks(range(min_runtime,max_runtime+5,5))

# 设置网格
p.grid()

p.show()

在这里插入图片描述
(2)rating

import pandas as pd
from matplotlib import pyplot as p

file_path = "D:\ProgramData\课件数据\datasets_IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)

rating_data = df["Rating"].values

max_rating = rating_data.max()
min_rating = rating_data.min()
# print(max_rating-min_rating)
# 设置组数
# num_bin_list = [1.6]
num_bin_list = [1.6,3.6]
i = num_bin_list[1]
while i<=max_rating+0.5:
    i=i+0.5
    num_bin_list.append(i)
# 设置图形大小
p.figure(figsize=(15,8),dpi=80)

p.hist(rating_data,num_bin_list)

# _x = [min_rating]
# i = min_rating
# j=0
# while i<=max_rating+0.5:
#     i=i+num_bin_list[j]
#     j=j+1
#     _x.append(i)

p.xticks(num_bin_list)

p.grid()

p.show()

在这里插入图片描述
另:还有部分问题尚未解决

2.pandas的统计方法

# 获取平均评分
print(df["Rating"].mean())
# 导演的人数
# print(len(set(df["Director"].tolist())))
print(len(df["Director"].unique()))  # df["Director"].unique()表示自动生成列表形式
# 演员的人数
temp_actors_list = df["Actors"].str.split(",").tolist()
actors_list = [i for j in temp_actors_list for i in j]
actors_num = len(set(actors_list))
print(actors_num)
# 电影时长的最值
max_runtime = df["Runtime (Minutes)"].max()
max_runtime_index = df["Runtime (Minutes)"].argmax()
min_runtime = df["Runtime (Minutes)"].min()
mina_runtime_index = df["Runtime (Minutes)"].argmin()
runtime_median = df["Runtime (Minutes)"].median()

五、数据合并与分组聚合

1.练习:统计电影分类情况:条形图

字符串离散:

思路:重新构造一个全为0的数组,列名为分类,如果某一条数据中分类出现过,就让0变为1

import numpy as np
import pandas as pd
from matplotlib import pylab as p

"""
统计电影分类情况
思路:重新构造一个全为0的数组,列名为分类,如果某一条数据中分类出现过,就让0变为1
"""
file_path = "D:\ProgramData\课件数据\datasets_IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)

# print(df["Genre"])

# 统计分类的列表
temp_list = df["Genre"].str.split(",").tolist()   # Series中是tolist,而DataFrame中是to_list
# print(temp_list)   # [[],[],[]]
genre_list = list(set([i for j in temp_list for i in j]))  # 使用双重循环得到有重复数据的列表,再放入集合去除重复数据
# print(genre_list)   # []无重复数据

# 构造全为0的数组
zero_df = pd.DataFrame(np.zeros((df.shape[0],len(genre_list))),columns=genre_list)
# print(zero_df)

# 给每个电影出现分类的位置赋值
for i in range(df.shape[0]):
    zero_df.loc[i,temp_list[i]]=1
    # zero_df.loc[0,['Action', 'Adventure', 'Sci-Fi']]=1
# print(zero_df.T)

# 统计每个分类的电影数量和
genre_count = zero_df.sum(axis=0)
# print(genre_count)

# 排序
genre_count = genre_count.sort_values(ascending=False)
# print(genre_count)

# 画图
_x = genre_count.values
_y = genre_count.index
# print(_x,_y)
p.figure(figsize=(15,8),dpi=80)
p.barh(range(len(_y)),_x,height=0.2)
p.yticks(range(len(_y)),_y)

p.show()

在这里插入图片描述

2.数据合并之join

join:默认情况下是把行索引相同的数据合并在一起
在这里插入图片描述

t1.join(t2)

注意:
 1.若index(t1)>index(t2),用NaN补充t2少的那一行
 2.若index(t1)<index(t2),删除t2多的那一行
在这里插入图片描述

在这里插入图片描述

3.数据合并之merge

在这里插入图片描述

t1.merge(t4,left_on="a",right_on="c",how="outer")
t1.merge(t4,on="1",how="left")

注意:
(1).其中“on="1"”表示在某一列索引上处理数据,不存在相同索引的可以用“left_on="a",right_on="c" ”表示左边列索引为a的与右边列索引为c的看作相同索引,进行处理

(2).其中“how="left"”表示合并方式,默认情况下为how="inner"表示交集,how="outer"表示并集NaN补全,how="left"表示左边为准NaN补全,how="right"表示右边为准NaN补全

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.分组聚合

pandas中类似的分组的操作:df.groupby(by="columns_name")
在这里插入图片描述
DataFrameGroupBy对象:1.可以遍历 2.可以调用聚合方法

# 进行遍历
for i,j in grouped:
    print(i)
    print("-"*100)
    print(j)
    print("*"*100)
# 按照grouped中分组方式分组后遍历输出
# print(df[df["Country"]=="US"])

#调用聚合方法
country_count = grouped["Brand"].count()
# 获取分组后某一部分数据
print(country_count["US"])
print(country_count["CN"])

在这里插入图片描述
举例:统计中国每个省份星巴克的数量

china_data = df[df["Country"]=="CN"]
# print(china_data.head(1).T)
grouped = china_data.groupby(by="State/Province")["Brand"].count()
# print(grouped)

(1)数据按照多个条件进行分组,返回Series类型

grouped1 = df["Brand"].groupby(by=[df["Country"],df["State/Province"]]).count()  # 俩个索引的Series类型数据
grouped2 = df.groupby(by=["Country","State/Province"]).count()
# 这里的by=[],中df["Country"],df["State/Province"]可写成"Country","State/Province"

(2)数据按照多个条件进行分组,返回DataFrame类型

grouped1 = df[["Brand"]].groupby(by=[df["Country"],df["State/Province"]]).count()
grouped2 = df.groupby(by=[df["Country"],df["State/Province"]]).count()[["Brand"]]
grouped3 = df.groupby(by=[df["Country"],df["State/Province"]])[["Brand"]].count()
# 三者结果相同

5.索引和复合索引

在这里插入图片描述
(1)获取index(2)指定index
在这里插入图片描述
(3)

t4.reindex(list("abc"))

相当于在原数组t4中取index为“abc”的数据,若不存在就为NaN
在这里插入图片描述
(4)指定某一列作为该数组的index

t4.set_index("2",drop=False)

t4.set_index(["2","3"],drop=False) # 两个索引

指定某一列作为该数组的index,其中drop=False表示保留所取列
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(5)返回index的唯一值

t4.set_index("1").index.unique()

在这里插入图片描述
(6)交换内外列表

d.swaplevel()

在这里插入图片描述

六、练习

1.呈现星巴克店铺总数前10的国家

import pandas as pd
from matplotlib import pylab as p

# 使用matplotlib呈现店铺总数排名前10的国家
file_path = "D:\ProgramData\课件数据\datasourse\星巴克\directory.csv"
df = pd.read_csv(file_path)

# 准备数据
num_data = df.groupby(by="Country").count()["Brand"].sort_values(ascending=False)[:10]
# print(num_data)

_x = num_data.index
_y = num_data.values

p.bar(range(len(_x)),_y,width=0.3)

p.xticks(range(len(_x)),_x)

p.show()

在这里插入图片描述

2.呈现中国每个城市的星巴克店铺数量

import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

# 使用matplotlib呈现中国每个城市的店铺数量
file_path = "D:\ProgramData\课件数据\datasourse\星巴克\directory.csv"
df = pd.read_csv(file_path)
# print(df.head(1).T)
# 获取数据
data = df.groupby(by=["Country","City"])["Brand"].count()
num_data = data["CN"].sort_values(ascending=False)[:40]
# print(num_data)
_x = num_data.values
_y = num_data.index

p.figure(figsize=(15,10),dpi=80)

p.barh(range(len(_y)),_x,height=0.4)

p.yticks(range(len(_y)),_y,fontproperties=my_font)

p.grid()

p.show()

在这里插入图片描述

3.统计不同年份书的数量

import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

file_path = "D:/ProgramData/课件数据/datasourse/10000本书/books.csv"
df = pd.read_csv(file_path)
# print(df.head(1).T)

data = df["books_count"].groupby(by=df["original_publication_year"]).sum().sort_values(ascending=False)
# print(data)

x = data.index
y = data.values

p.figure(figsize=(15,8),dpi=80)

p.scatter(x,y)

# p.xticks()

p.show()

在这里插入图片描述

4.统计不同年份书的平均评分情况

import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

file_path = "D:/ProgramData/课件数据/datasourse/10000本书/books.csv"
df = pd.read_csv(file_path)
# print(df.head(1).T)

data = df.groupby(by="original_publication_year")["average_rating"].mean()
# print(data)

_x = data.index
_y = data.values

p.figure(figsize=(15,8),dpi=80)

p.plot(range(len(_x)),_y)

p.xticks(list(range(len(_x)))[::10],_x[::10].astype(int),rotation=45)

p.show()

在这里插入图片描述

5.统计911不同类型的紧急情况的次数

import numpy as np
import pandas as pd
from matplotlib import pylab as p
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")

file_path = "D:\ProgramData\课件数据\datasourse\911\911.csv"
df = pd.read_csv(file_path)
# print(df.head(1).T)

# 获取分类
temp_list = df["title"].str.split(":").tolist()
data_list = list(set([i[0] for i in temp_list]))
# print(data_list)

# # 创建全为0的数组
zero_df = pd.DataFrame(np.zeros((df.shape[0],len(data_list))),columns=data_list)
# print(zero_df)

# 赋值,统计每一种分类的数量和
for i in data_list:
    zero_df[i][df["title"].str.contains(i)]=1  # 布尔索引
# print(zero_df)
type_count = zero_df.sum(axis=0)
print(type_count)

_x = type_count.index
_y = type_count.values

p.figure(figsize=(15,8),dpi=80)

p.bar(_x,_y,width=0.1)

p.show()

在这里插入图片描述

在这里插入图片描述

6.PM2.5

# @XST1520203418
# 要天天开心呀

import pandas as pd
import pylab as p

file_path = "D:\ProgramData\课件数据\datasourse\城市空气质量数据\BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
# print(df.head(1).T)
# print(df.info())

# 把分开的时间字符串通过periodIndex的方法转化为pandas的时间类型
period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H")
# print(period,type(period))
df["datetime"] = period

# 把datetime设置为索引
df.set_index("datetime",inplace=True)
# print(df.head(10).T)

# 进行降采样
df = df.resample("10D").mean()

# 处理确实数据:删除缺失数据
data = df["PM_US Post"].dropna()
data_chain = df["PM_Dongsi"].dropna()
# data=data.tail(200)  # 数据太多,可取末尾200个
# 画图
x=data.index
x=[i.strftime("%Y%m%d") for i in x]  # 修改时间序列的表现方式
x_chain = [i.strftime("%Y%m%d") for i in data_chain.index]
y=data.values
y_chain = data_chain.values

p.figure(figsize=(15,8),dpi=80)
p.plot(range(len(x)),y,label="US")
p.plot(range(len(x_chain)),y_chain,label="CN")
p.xticks(range(0,len(x),10),list(x)[::10],rotation=45)
# 添加图例
p.legend()
p.show()

在这里插入图片描述
注意:该图像橙色后半部分缺失原因与该数据在该段时间内缺失有关

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值