Python数据分析入门与实践
Python数据分析主要基于Pandas的Serise和DataFrame去实现,Serise和DataFrame有点像php里的数组,在数据科学里叫矩阵。把数据使用Pandas进行采样和机器学习计算,在使用Matplotlib/Seaborn来画图实现。
概述
Python数据分析主要基于Pandas的Serise和DataFrame去实现,Serise和DataFrame有点像php里的数组,在数据科学里叫矩阵。
把数据使用Pandas进行采样和机器学习计算,在使用Matplotlib/Seaborn来画图实现。
实验环境
- Anaconda
- python3.6作为基础环境
- 使用Jupyter Notebook作为编程IDE
数据科学领域5个最佳的python库
Numpy
- N维数组(矩阵),快速高效,矢量数学运算
- 高效的Index,不需要循环
- 开源免费跨平台,运行效率足以和C/Matlab媲美
Scipy
- 依赖于Numpy
- 专为科学和工程设计
- 实现了多种常用的科学计算:线性代数,傅里叶变换,信号和图像处理
Pandas
- 结构化数据分析利器(依赖Numpy)
- 提供了多种高级数据结构:Time-Series,DataFrame,Panel
- 强大的数据索引和处理能力
Matplotlib
- Python 2D绘图领域使用最广泛的套件
- 基本能取代Matlab的绘图功能(散点,曲线,柱形)
- 通过mplot3d可以绘制精美的3D图
Scikit-learn
- 机器学习的python模块
- 建立在Scipy之上,提供了常用的机器学习算法:聚类,回归
- 简单易学的Api接口
数学基础之矩阵运算
- 矩阵:矩形的数组,即二维数组。其中向量和标量都是矩阵的特例
- 向量:是指
1 x n
或者n x 1
的矩阵 - 标量:
1 x 1
的矩阵 - 数组:N维的数组,是矩阵的延伸
特殊矩阵
- 全0/全1矩阵
- 单位矩阵
矩阵加减运算
- 相加,减的两个矩阵必须要有相同的行和列
- 行和列对元素相加减
数组乘法(点乘)
- 数组乘法(点乘)是对应元素之间的乘法
矩阵乘法
- 设A为
m x p
的矩阵,B为p x n
的矩阵,m x n
的矩阵C为A与B的乘积,记为C=AB
,其中矩阵C中的第i行第j列元素。
Pandas 实践
Pandas应用
Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。
Pandas数据结构
Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
Pandas 数据结构 - Series
Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。
Series 由索引(index)和列组成,函数如下:
pandas.Series( data, index, dtype, name, copy)
- data:一组数据(ndarray 类型)。
- index:数据索引标签,如果不指定,默认从 0 开始。
- dtype:数据类型,默认会自己判断。
- name:设置名称。
- copy:拷贝数据,默认为 False。
Pandas 数据结构 - DataFrame
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
pandas.DataFrame( data, index, columns, dtype, copy)
- data:一组数据(ndarray、series, map, lists, dict 等类型)。
- index:索引值,或者可以称为行标签。
- columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。
- dtype:数据类型。
- copy:拷贝数据,默认为 False。
pandas 的数据实践
Series和DataFrame的简单数学运算
Series的计算
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
S1 = Series([1,2,3],index=['A','B','C'])
S2 = Series([4,5,6,7],index=['B','C','D','E'])
// S1 + S2 的执行结果:
B 8
C 10
D 12
E 14
dtype: int64
DataFrame的运算:
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df1 = DataFrame(np.arange(4).reshape(2,2),index=['A','B'],columns =['BJ','SH'])
df2 = DataFrame(np.arange(9).reshape(3,3),index=['A','B','C'],columns =['BJ','SH','GZ'])
//df1 + df2 执行结果
BJ GZ SH
A 0.0 NaN 2.0
B 5.0 NaN 7.0
C NaN NaN NaN
df3 = DataFrame([[1,2,3],[4,5,np.nan],[7,8,9]],index=['A','B','C'],columns=['c1','c2','c3'])
//求列的和
df3.sum()
//求行的和
df3.sum(axis =1)
//求列的最小值
df3.min()
//求列的最大值
df3.max()
//求列的统计值
df3.describe()
// 执行结果:
c1 c2 c3
count 3.0 3.0 2.000000
mean 4.0 5.0 6.000000
std 3.0 3.0 4.242641
min 1.0 2.0 3.000000
25% 2.5 3.5 4.500000
50% 4.0 5.0 6.000000
75% 5.5 6.5 7.500000
max 7.0 8.0 9.000000
Series和DataFrame的排序
Series可以根据value和index去排序
import numpy as np
import pandas as pd
from pandas import Series , DataFrame
s1 = Series(np.random.randn(10))
// 可以执行 s1.values / s1.index的值
s1.sort_index()
//ascending=False 值从大小排序
s1.sort_values(ascending=False)
导入csv文件进行排序:
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
csv_user = '/Users/zhangyu/Desktop/user.csv'
pd.read_csv(csv_user,low_memory=False)[["user_id","user_name","user_status","user_nickname","user_display"]].sort_values('user_display',ascending=False)
导入cvs文件的操作
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
csv_user = '/Users/zhangyu/Desktop/user.csv'
pd.read_csv(csv_user,low_memory=False)[["user_id","user_name","user_status","user_nickname","user_display"]].sort_values('user_display',ascending=False)
重命名DataFrame的Index和Columns
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df1 = DataFrame(np.arange(9).reshape(3,3),index=['BJ','SH','SZ'],columns=['A','B','C'])
//第1种方式
df1.index = Series(['bj','sh','sz'])
//第2种方式
df1.index = df1.index.map(str.upper)
//第3种方式
df1.renamee(index={},columns={})
重命名DataFrame的Merge操作
DataFrame对结果集进行merge的时候,要有相同的columns,不然结果是空的。
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
df1 = DataFrame({'key':['X','Y','Z'],'data_set_1':[1,2,3]})
df2 = DataFrame({'key':['X','B','C'],'data_set_2':[4,5,6]})
pd.merge(df1,df2)
//执行结果:
key data_set_1 data_set_2
0 X 1 4
如果是有相同的columns,会执行2遍:
df3 = DataFrame({'key':['X','Y','X'],'data_set_1':[1,2,3]})
df4 = DataFrame({'key':['X','B','C'],'data_set_2':[4,5,6]})
pd.merge(df3,df4)
//执行结果:
key data_set_1 data_set_2
0 X 1 4
1 X 3 4
DataFrame merge函数有两个重要的参数要重点介绍,on
就是对于那个字典合并,how
就是对那部分进行补全,和Mysql的join有点相似。
- how :left/right/outer,默认是inner,取全部数据
pd.merge(df1,df2,on='key',how="outer")
Concatenate和Combine的区别
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
arr1 = np.arange(9).reshape(3,3)
arr2 = np.arange(9).reshape(3,3)
np.concatenate([arr1,arr2])
//执行结果:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
np.concatenate([arr1,arr2],axis=1)
//执行结果:
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8]])
s1 = Series([1,2,3],index=['X','Y','Z'])
s2 = Series([4,5],index=['A','B'])
np.concatenate((s1,s2))
//执行结果:
array([1, 2, 3, 4, 5])
pd.concat([s1,s2])
pd.concat([s1,s2],axis=1)
df1 = DataFrame(np.random.randn(4,3),columns=['X','Y','Z'])
df2 = DataFrame(np.random.randn(3,3),columns=['X','Y','A'])
pd.concat([df1,df2])
//执行结果:
X Y Z A
0 1.988333 0.983833 -1.927185 NaN
1 0.958006 -0.927374 -0.294826 NaN
2 1.748977 -0.162052 -0.975951 NaN
3 -1.476630 0.985365 0.128454 NaN
0 -0.717199 0.371737 NaN 0.957216
1 1.149086 1.761177 NaN -0.601090
2 -2.731751 0.321025 NaN -0.186762
Combine的使用
df1.combine_first(df2)
的函数意义是把df2填充到df1里
s1 = Series([2,np.nan,4,np.nan],index=['A','B','C','D'])
s2 = Series([1,2,3,4],index=['A','B','C','D'])
s1.combine_first(s2)
//执行结果:
A 2.0
B 2.0
C 4.0
D 4.0
dtype: float64
df1 = DataFrame({
'x': [1,np.nan,3,np.nan],
'y': [5,np.nan,7,np.nan],
'z': [9,np.nan,11,np.nan],
})
df2 = DataFrame({
'Z':[np.nan,10,np.nan,12],
'A':[1,2,3,4]
})
df1.combine_first(df2)
通过apply进行数据的预处理
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df = pd.read_csv('/Users/zhangyu/Desktop/user.csv',low_memory=False)
def foo(line):
if line is not None:
items = str(line).strip().split('/')
return Series([items[0]])
df["user_head"].apply(foo)
通过去重进行数据清洗
len + unique
的组合使用是计算重复数据的长度,drop_duplicates
里的keep
如果等于last,取(重复的)最后一条,默认取第一条。
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df = pd.read_csv('/Users/zhangyu/Desktop/user.csv',low_memory=False)
flied = ['user_id','user_name','user_status','user_display'];
df.head(10)[field]
len(df['user_status'].unique())
df['user_display'].duplicated()
df['user_display'].drop_duplicates()
df.head(30)[flied].drop_duplicates(['user_display'],keep="last")
时间序列的操作基础
可以使用s1['2016-09']
来获取Series的值
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
from datetime import datetime
date_list = [
datetime(2016,9,1),
datetime(2016,9,10),
datetime(2017,9,1),
datetime(2017,9,20),
datetime(2017,10,1)
]
s1 = Series(np.random.rand(5),index=date_list)
days = pd.date_range('2016-01-01',periods=100)
s2 = Series(np.random.rand(100),index=days)
时间序列的采样和画图
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
t_range = pd.date_range('2016-01-01','2016-12-31')
s1 = Series(np.random.randn(len(t_range)),index=t_range)
s1_mouth = s1.resample('M').mean()
// 按小时画图
t_range = pd.date_range('2016-01-01','2016-12-31',freq='H')
stock_df = DataFrame(index=t_range)
stock_df['alibaba'] = np.random.randint(80,160,size=8761)
stock_df['baidu'] = np.random.randint(30,60,size=len(t_range))
stock_df.plot()
//按周数据取样
weekly_df = DataFrame()
weekly_df['alibaba'] = stock_df['alibaba'].resample('W').mean()
weekly_df['baidu'] = stock_df['baidu'].resample('W').mean()
weekly_df.plot()
数据分箱技术Binning
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import pandas.util.testing
score_list = np.random.randint(25,100,size=20)
bins = [0,59,75,90,100]
score_cat = pd.cut(score_list,bins)
df = DataFrame()
df['score'] = score_list
df['student'] = [pd.util.testing.rands(3) for i in range(20)]
df['section'] = pd.cut(df['score'],bins,labels=['Low','Pass','Good','Greate'])
数据分组技术GroupBy
使用groupby
分组的g,常用的使用方法:
- g.groups
- g.get_group(74)
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df = pd.read_csv('/Users/zhangyu/Desktop/type.csv',low_memory=False)
g = df.groupby(df['type_topid'])
//执行g
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fc53d997520>
//转化为列表,使用for循环
list(g)
for name , group_df in g:
print(name)
print(group_df)
数据聚合技术Aggregation
df.agg()
透视表
为了更好的去展示数据,临时把原始表结构进行了一次变更,根据这些变化,也产生相应的变化,这是透视表的概念。
使用函数pivot_table
实现透视表。
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df = pd.read_csv('/Users/zhangyu/Desktop/type.csv',low_memory=False)
pd.pivot_table(df,index=['type_id','type_name'])
Matplotlib 绘图和可视化
为什么用python画图?
- GUI太复杂
- Excel太头疼
- python简单,免费
什么是Matplotlib?
- 一个Python包
- 用于2D绘图
- 非常强大和流行
- 有很多扩展
Matplotlib Architecture
- Backend: 主要处理把图显示到哪里喝画到哪里?
- Artist:图像显示成什么样?
- Scripting:pyplot,Python语法和Api
matplotlib简单绘图之plot
plot的参数,是由X轴和Y轴组成的,x和y的元素数量需要对应的。plot
可以把两条线放在一张图里。
import numpy as np
import matplotlib.pyplot as plt
x = [1,2,3]
y = [4,5,6]
plt.plot(x,y)
c = [10,8,6]
d = [1,8,3]
plt.plot(a,b,c,d)
plt.plot(t,s,'r--',label='demo_aaa')
plt.plot(t*2,s ,'b--',label='demo_bbb')
plt.xlabel('this is x')
plt.ylabel('this is y')
plt.title('this is a demo')
plt.legend()
matplotlib简单绘图之subplot
subplot的实现原理就是把一个整图切换成几个合理的子图。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0.0,5.0)
y1 = np.sin(np.pi*x)
y2 = np.sin(np.pi*x*2)
# 在一张画布里
plt.plot(x,y1,'b--',label='sin(pi*x)')
plt.ylabel('y1 value')
plt.plot(x,y2,'r--',label='sin(pi*2x)')
plt.ylabel('y2 value')
plt.xlabel('x value')
plt.title('this is x-y value')
plt.legend()
# 构建subplot画布
plt.subplot(2,2,1)
plt.plot(x,y1,'b--')
plt.ylabel('y1')
plt.subplot(2,2,2)
plt.plot(x,y2,'r--')
plt.ylabel('y2')
plt.xlabel('x')
plt.subplot(2,2,3)
plt.plot(x,y1,'r*')
plt.subplot(2,2,4)
plt.plot(x,y1)
# 画布
figure , ax = plt.subplots(2,2)
ax[0][0].plot(x,y1)
ax[0][1].plot(x,y2)
Pandas绘图之Series
可以对Series 进行绘图,s1.plot()
,常用的参数如下:
- kind : bar(柱状图) , 默认是line
- grid : 显示画布上的方格,默认是False
- label : 曲线说明字符串,与
plt.legend()
合并使用才会显示 - title : this is Serise
import numpy as np
import pandas as pd
from pandas import Series
import matplotlib.pyplot as plt
s1 = Series(np.random.randn(1000)).cumsum()
s2 = Series(np.random.randn(1000)).cumsum()
s1.plot(kind='line',grid=True,label="s1",title="this is Serise")
s2.plot(kind='line',grid=True,label="s2",title="this is Serise")
plt.legend()
Series 使用subplot画布
figure , ax = plt.subplots(2,1)
ax[0].plot(s1)
ax[1].plot(s2)
s1.plot(ax=ax[0],label='S1')
s2.plot(ax=ax[1],label='S2')
Pandas绘图之DataFrame
使用df.plot
来画图,常用参数解释:
- kind : bar(柱状图) 、barh(横向显示柱状图)、area(填充图形式)、kde(密度图)
- stacked : True(把值都叠加在一个柱子)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
df = DataFrame(
np.random.randint(1,10,40).reshape(10,4),
columns=['A','B','C','D']
)
df.plot(kind="bar")
df.plot(kind="bar",stacked=True)
Matplotlib的直方图和密度图
使用plt.hist
函数来实现直方图,常用参数如下:
- data : 需要实现的数据
- rwidth : 线条的宽度
- bins :展示的份数
- color :颜色
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
s = Series(np.random.randn(1000))
plt.hist(s,rwidth=0.9,bins=100,color='r')
Seaborn
seaborn实现直方图和密度图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
import seaborn as sns
s1 = Series(np.random.randn(1000))
sns.distplot(s1,bins=30,hist=True,kde=True,rug=True)
sns.kdeplot(s1,shade=True,color='#00FFFF')
seaborn实现柱状图和热力图
需要的数据可以去https://github.com/mwaskom/seaborn-data
下载。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
import seaborn as sns
df = pd.read_csv('/Users/zhangyu/Downloads/seaborn-data-master/flights.csv')
//做一个年度的透视表
df = df.pivot(index='month',columns='year',values='passengers')
sns.heatmap(df,annot=True,fmt='d')
//seaborn实现一个柱状图
s = df.sum()
sns.barplot(x=s.index,y=s.values)
seaborn图形显示效果的设置
import seaborn as sns
plt.plot(x,y1)
plt.plot(x,y2)
style = ['darkgrid','dark','white','whitegrid','tricks']
sns.set_style(style[3])
sns.axes_style()
sns.set()

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)