数据分析:Python库之numpy、pandas、matplotlib

目录

一、numpy

1、构造一维数组

2、构造二维数组

3、填充

4、矩阵乘法

5、广播

6、一些常用函数

7、io

二、pandas

1、Series

2、DataFrame

3、聚合

4、处理空值

5、日期数据

6、多表连接

7、分组

8、io

三、matplotlib

1、绘制折线图

 2、绘制散点图

 3、绘制多幅子图

 4、在同一图表中绘制多幅图

 5、柱形图


模块(Module)是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句能够有逻辑地组织 Python 代码段。把相关的代码分配到一个模块里能让Python代码更好用,更易懂。模块能定义函数,类和变量,模块里也能包含可执行的代码。

模块定义好后,使用 import 语句来引入模块,语法:import module_name1[, module_name2,...]

python的常用模块有numpy、pandas、matplotlib等等。

一、numpy

Numerical Python,即数值Python,是Python进行科学计算的一个基础模块。

ndarray即N维数组,是numpy模块的核心数据结构。用多维数组计算,非常便捷高效并且可以节省空间。

导入numpy库:import numpy as np,并取了一个更简略的别名,在调用库函数时,通过在函数名前加np.即可调用:np.function_name()。

1、构造一维数组

import numpy as np

a = np.array([1,2,3,4])         #构造一个一维数组,其中元素的数据类型必须一致
a.ndim                          #输出:1。表示数组是一维的
a.size                          #输出:4。表示数组有四个元素
a>2                             #输出array([False, False,  True,  True])。即大于2的元素索引值
a[a>2]                          #输出array([3, 4])。即取出大于2的元素
a.dtype                         #输出dtype('int32')。表示数组中元素是整型

2、构造二维数组

import numpy as np


b = np.array( [[1,2],[3,4]] )    #构造一个二维数组
b.shape                          #输出(2,2)。表示数组结构为2×2
b.ravel()                        #把多维数组变为一维数组

3、填充

在数组的初始化时,通常调用函数对数组填充固定数值或者随机数。

import numpy as np


np.zeros(4)         #生成一维数组,用0填充
np.zeros((2,2))     #生成二维数组,用0填充
np.ones((3,4))      #生成二维数组,用1填充

#以上数组元素的数据类型默认为浮点数,若要指定整型:
np.zeros((2,2),dtype=np.int)

np.empty((2,2))     #填充随机值

np.random.randint(m,n,(p,q))  #构造一个p×q矩阵,其整型元素的值域为[m,n-1]
np.random.random((3,4))       #构造一个3×4数组,填充(0,1)之间的随机浮点数

np.arange(15)                 #元素值为0-14整数
np.arange(15).reshape(3,5)    #将0-14的元素按3×5矩阵排列
np.arange(0,20,3)             #输出array[0,3,6,9,12,15,18],即0-19之间,从0开始间隔为3的数

4、矩阵乘法

import numpy as np
a = np.empty((2,3))
b = np.empty((3,4))
a*a                #a中每个元素自乘平方
c = a.dot(b)  或者 c = np.dot(a,b)
c.shape            #输出(2, 4)

5、广播

numpy两个数组的相加、相减以及相乘都是对应元素之间的操作。但是如果两个数组的形状不相同,这时候就会自动通过扩展数组实现相加、相减、相乘等操作,这就叫做广播机制(broadcasting)。

当数组与一个数做运算,即通过广播,使每个元素都与这个数做运算,数组形状不变。当两个数组的形状不相同,但它们的后缘维度相等,例如形状分别是(2,3)与(3,)的两个数组,后者会沿着0轴扩展。若形状分别是(4,3)与(4,1),后者会沿着1轴扩展。再比如(2,3,4)和(1,4)也是可以相加的。

import numpy as np
a = np.empty((2,3))
a+1                 #a中每个元素+1
a-1                 #a中每个元素-1
a*2                 #a中每个元素*2
b=np.array([1,2,3]) #创建一维数组,shape为(3,)
a*b                 #广播
np.ones((2,3,4)) * np.ones((1,4))  #广播

6、一些常用函数

import numpy as np

x=np.arange(20).reshape(5,4)

np.abs(x)            #绝对值
np.sqrt(x)           #平方根
np.square(x)         #平方
np.power(x,3)        #三次方
np.exp(x)            #指数e的次方
np.log(x)            #底数为e的log
np.log2(x)           #底数为2的log
np.log10(x)          #底数为10的log
np.sign(x)           #计算正负号:1、0或-1
np.sin(x)            #正弦
np.arcsin(x)         #反三角
x.min()              #最小值
x.max()              #最大值
x.mean()             #均值
x.max(axis=0)        #在0轴上聚合求最大值
np.unique(x)         #去重
np.linspace(0,5,11)  #0到5之间(包含0、5),均分为11个数

7、io

import numpy as np
from io import StringIO

#读取
a = StringIO(u'0 1 2\n3 4 5')
np.loadtxt(a)

b = np.loadtxt('x.csv',delimiter=',',dtype=str)
c = np.genfromtxt('y.csv',delimiter=',',dtype=str) 
#genfromtxt可提供选项,如missing_values,filling_values可处理不完整的csv,如skip_header跳过表头

#写入
np.savetxt('x.txt',b,delimiter=',',fmt = '%s') #在保存时需要指明数据类型,若类型不一致会报错
d = np.random.random((4,5,6))*10    
np.savetxt('y.txt',d.reshape((-1,10)),delimiter=',',fmt = '%d') 
#如果数组ndim>2,需转换成二维才能存储

二、pandas

pandas模块是Python用于数据导入及整理的模块,最初被作为金融数据分析工具而开发出来,它提供了大量能使我们快速便捷地处理数据的函数和方法,对于在数据挖掘工作中数据的处理起到非常大的作用。

pandas模块的常用数据结构主要有两种:

(1)、Series。一维数组,与Numpy中的一维array类似,只是在其基础上增加了一组索引。

(2)、DataFrame。二维的表格型数据结构,可以看做是由相同或不同值类型的Series组成的。

1、Series

import numpy as np
import pandas as pd
from pandas import Series

#通过list创建
s1= Series(['a','f','j','p','s'],index=[0,1,2,3,4])
s1.index      #查看索引
s1.values     #查看数据

#通过array创建
s2 = Series(np.ones(10,))

#通过dict创建
s3 = Series({'Tom':99,'Jerry':100,'Bob':98,'Jim':97})
s3[s3>97].mean()  #计算大于97分的同学的平均分。

#空值
s4 = Series([82,100,60,70,None],index=['Bob','Tom','Jim','Jerry','James'])
s4[pd.isnull(s4)]    #查看空值数据
(s3+s4)/2    #根据索引进行运算

#查找
s3['Tom']
s1[1:4]

2、DataFrame

import pandas as pd
from pandas import Series,DataFrame

s1 = Series({'Tom':99,'Jerry':100,'Bob':98,'Jim':97})
d1 = DataFrame(s1,columns=['score'])  #在Series的基础上,增加列索引

d2 = DataFrame([['Tom',99,12],['Jerry',100,15],['Bob',98,13],['Jim',97,10]],columns=['name','score','age'])
d2.index        #行索引
d2.columns      #列索引
d2.values       #值

#查找
d2['score']      #按列查找
d1.loc['Tom']    #按行索引查找
d2.iloc[0]       #按行号查找
d2.iloc[1:3]     #按行切片
d2.iloc[:,0:2]   #按列切片
d2.iloc[1:3,0:2] #按行和列切片
d2['name'][0:2] 或 d2.name[0:2]   #查找'name'列的第0、1行
d2[1:3]          #查找第1、2行
d2.iloc[1,2] 或 d2.loc[1,'age']     #查找第1行第2列元素值
d2.iat[1,2]      #与iloc等效,但是iat不能切片。d2.iat[1:3,0:2]会报错

d2[d2.age>12]    #过滤出年龄>12的数据
d2[d2!=98]       #整体过滤
d2[(d2==98)|(d2==12)]  #整体过滤
d2[d2.age.isin([13])]  #取出年龄=13的数据

d2.sort_values("age")  #按年龄从小到大排序
d2.sort_values("age",ascending=False) #按年龄从大到小排序
d2.sort_values("age",inplace=True) #会保存排序结果(但行号不会变)
d2.reset_index(drop=True)  #重置行号

len(d2)      #查看数据行数
d2.shape      #查看数据规模
d2.head(2)   #显示头部2行
d2.tail(2)   #显示末尾2行

d2["age"]=[10,11,12,13]     #修改列数据
d2["num"]=[996,997,998,999] #新增列
d2= d2.drop(columns=["num"]) #删除列

3、聚合

import numpy as np
from pandas import DataFrame

d2 = DataFrame([['Tom',99,12],['Jerry',100,15],['Bob',98,13],['Jim',97,10]],columns=['name','score','age'])
d2.count()
d2.mean()
d2.std()
d2.min()
d2.max()
d2.sum()
d2.describe()    #显示所有聚类结果
d2.count(0)      #按列聚类
d2.count(1)      #按行聚类
d2.age.max()     #按具体列聚类
d2.apply(lambda x:x.max()+x.min())  #自定义函数计算


d3 = DataFrame([['Tom',99,12],['Tom',96,12],['Jerry',100,15],['Jerry',90,15],['Bob',98,13],['Jim',97,10]],columns=['name','score','age'])
#按name计算均值
d3.pivot_table(index="name",values=["age","score"],aggfunc=np.mean)  

4、处理空值

from pandas import DataFrame

d4 = DataFrame([['Tom',99,12],['Jerry',100,15],['Bob',None,13],['Jim',97,None]],columns=['name','score','age'])
d4.isnull()
d4.dropna()  #删除含有空值的行
d4.dropna(axis=1)  #删除含有空值的列
d4.dropna(axis=0,subset=["age"])  #剔除age列含有空值的行

d5=d4.copy()
d5.age=d4.age.fillna(value = 10)
d5.score=d4.score.fillna(value = 98) #按设定值填补空值

5、日期数据

from pandas import DataFrame
import pandas as pd

d6 = DataFrame([['Tom',99,12,'2009/12/27'],['Jerry',100,15,'2006/11/21'],['Bob',98,13,'2008/5/18'],['Jim',97,10,'2011/7/16']],columns=['name','score','age','birth'])

#转为日期类型
d6['birth']=pd.to_datetime(d6['birth']) 
d6.dtypes #查看表格每列的数据类型

d6['birth'].dt.year   #显示年份
d6['birth'].dt.month  #显示月份
d6['birth'].dt.day    #显示日期

6、多表连接

import pandas as pd
from pandas import DataFrame

#建表
d1 = DataFrame([['Tom',99],['Jerry',100],['Bob',98],['Jim',97]],columns=['name','score'])
d2 = DataFrame([['Tom',12],['Jerry',15],['Bob',13],['James',15]],columns=['name','age'])

#inner内连接(两表交集)
d1.merge(d2,how='inner',on='name')
# output:
#   name  score  age
# 0    Tom     99   12
# 1  Jerry    100   15
# 2    Bob     98   13

#left连接(以d1表为基础,如果d1表中的键在d2表不存在,以缺失值NaN填充)
d1.merge(d2,how='left',on='name')
# output:
#   name  score   age
# 0    Tom     99  12.0
# 1  Jerry    100  15.0
# 2    Bob     98  13.0
# 3    Jim     97   NaN

#right连接(以d1表为基础,如果d1表中的键在d2表不存在,以缺失值NaN填充)
d1.merge(d2,how='right',on='name')
# output:
#   name  score  age
# 0    Tom   99.0   12
# 1  Jerry  100.0   15
# 2    Bob   98.0   13
# 3  James    NaN   15

#outer内连接(两表并集)
d1.merge(d2,how='outer',on='name')
# output:
#    name  score   age
# 0    Tom   99.0  12.0
# 1  Jerry  100.0  15.0
# 2    Bob   98.0  13.0
# 3    Jim   97.0   NaN
# 4  James    NaN  15.0

7、分组

import pandas as pd
from pandas import DataFrame

dept=["O","P","Q"] #三个部门
​
data=pd.DataFrame({
    "dept":[dept[i] for i in np.random.randint(0,3,10)],
    "salary":np.random.randint(500,5000,10),
    "age":np.random.randint(20,50,10) })

# data中每一行数据代表一个员工:
#      dept  salary  age
# 0       Q    3959   47
# 1       P    4237   48
# 2       P    2024   34
# 3       Q    4330   46
# 4       Q    2228   40
# 5       Q    1140   45
# 6       Q    1234   36
# 7       O    1754   48
# 8       Q    3828   34
# 9       P    4202   44

#求不同部门员工的工资、年龄的均值
data.groupby("dept").mean()
# output
#             salary        age
# dept
# O        1754.000000  48.000000
# P        3487.666667  42.000000
# Q        2786.500000  41.333333

#求不同部门员工的工资均值、年龄中位数
data.groupby('dept').agg({'salary':'mean','age':'median'})

#增加一列--部门平均工资
dict = data.groupby('dept').salary.mean().to_dict()
data['avg_salary'] = data.dept.map(dict)
#上两行等价于:
data['avg_salary'] = data.groupby('dept').salary.transform('mean')

同理,可通过data.groupby("company").function()调用其他聚合函数如min(最小值)、max(最大值)、sum(汇总)、median(求中位数)、std(标准差)、var(方差)、count(计数)。

8、io

import pandas as pd
from pandas import DataFrame

d2 = DataFrame([['Tom',99,12],['Jerry',100,15],['Bob',98,13],['Jim',97,10]],columns=['name','score','age'])

#存储为csv文件
d2.to_csv('x.csv')

# 读取csv文件
x = pd.read_csv('x.csv',sep=',',header=0)  #可以设置分隔符,表头等参数
#类似地,也可以用to_excel、read_excel; read_pickle、to_pickle; to_json、read_json等来存取其他类型的文件

三、matplotlib

该模块是一款强大的数据可视化工具,包含丰富的数学绘图函数。不过Matplotlib 默认情况不支持中文,如果要显示中文文字,可以下载OTF 字体

1、绘制折线图

代码中的“UNRATE.csv”文件统计了美国从1948年1月到2016年8月每个月的失业率。表格中只有DATE和VALUE两列数据。

百度云下载链接:https://pan.baidu.com/s/1vIJ1_L3GNWCTAYOYEXjzJA
提取码:abcd

可从中提取出1950年的数据来绘制时间-失业率的折线图。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

unrate = pd.read_csv("UNRATE.csv")
unrate['DATE'] = pd.to_datetime(unrate['DATE'])

#指定x轴和y轴数据
unrate_1950 = unrate[unrate.DATE.dt.year==1950]
plt.plot(unrate_1950['DATE'], unrate_1950['VALUE'])
#x轴数据值倾斜45显示
plt.xticks(rotation=45)
#指定x轴和y轴数据的标签
plt.xlabel('Month')
plt.ylabel('Unemployment Rate')
#指定标题
plt.title('Monthly Unemployment Trends, 1950')
#是否显示辅助方格线
plt.grid(False)

plt.show()

 2、绘制散点图

绘制散点图只需在上列代码中更改以下位置:加上参数"or"。o表示圆点,r表示red红色,即绘制红色圆点。

plt.plot(unrate_1950['DATE'], unrate_1950['VALUE'],"or")

 3、绘制多幅子图

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math as m

#创建画图区域,指定长和宽
fig = plt.figure(figsize=(10,10))
#画图区域指定在2*1矩阵中,第三个参数表示子图的位置
ax1 = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)
#以0-19为横坐标值,以20个随机数组成的向量为纵坐标值画子图1,线是红色
ax1.plot(np.arange(20), np.random.randint(1,5,20), c='red')
#以[0-2π]为横坐标,以sin([0-2π]的值为纵坐标画子图2,线是蓝色
ax2.plot(np.linspace(0,2*m.pi,20), np.sin(np.linspace(0,2*m.pi,20)), c='blue')

plt.show()

 4、在同一图表中绘制多幅图

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

unrate = pd.read_csv("UNRATE.csv")
unrate['DATE'] = pd.to_datetime(unrate['DATE'])
unrate['MONTH'] = unrate['DATE'].dt.month

fig = plt.figure(figsize=(8,4))
colors = ['red', 'blue', 'green', 'orange', 'black']
for i in range(5):
    start_index = i*12
    end_index = (i+1)*12
    subset = unrate[start_index:end_index]
    plt.plot(subset['MONTH'], subset['VALUE'], c=colors[i], label=str(1948+i))

#显示图例在最佳位置    
plt.legend(loc='best')
#显示主方格辅助线
plt.grid(True)
#xy轴标签和图表标题
plt.xlabel('Month, Integer')
plt.ylabel('Unemployment Rate, Percent')
plt.title('Monthly Unemployment Trends, 1948-1952')

plt.show()

 5、柱形图

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

unrate = pd.read_csv("UNRATE.csv")
cols = ['1948', '1949', '1950', '1951', '1952']   #列名
unrate['DATE'] = pd.to_datetime(unrate['DATE'])

bar_heights=[]
for i in range(5):
    bar_height = round(unrate[unrate.DATE.dt.year == (1948+i)].VALUE.mean(),2) #失业率均值
    bar_heights.append(bar_height)

bar_positions = np.arange(5) + 1
# 返回一个 (figure, ax) 的元组
fig,ax = plt.subplots()
# 绘制纵向柱形图
ax.bar(bar_positions, bar_heights, 0.4)     #0.4指定柱的宽度

# 设置x轴bar的位置和x轴数据显示的角度
ax.set_xticks(range(1,6))
ax.set_xticklabels(cols, rotation=45)

# 设置xy轴的标签和图表的标题
ax.set_xlabel('year')
ax.set_ylabel('Unemployment Rate')
ax.set_title('Unemployment Rate , 1948-1952')

plt.show()

 若要将柱形图方向改为横向,只需将ax.bar改为ax.barh,设置y轴刻度,并将x、y轴标题对调。即:

……

# 绘制横向柱形图
ax.barh(bar_positions, bar_heights, 0.4)     #0.4指定柱的宽度

# 设置y轴bar的位置和y轴数据显示的角度
ax.set_yticks(range(1,6))
ax.set_yticklabels(cols, rotation=45)

# 设置xy轴的标签和图表的标题
ax.set_xlabel('Unemployment Rate')
ax.set_ylabel('year')
ax.set_title('Unemployment Rate , 1948-1952')

plt.show()

  • 16
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值