当前位置:   article > 正文

Python数据分析入门与实践_python数据分析从入门到实践

python数据分析从入门到实践

概述

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)
  • 1
  • data:一组数据(ndarray 类型)。
  • index:数据索引标签,如果不指定,默认从 0 开始。
  • dtype:数据类型,默认会自己判断。
  • name:设置名称。
  • copy:拷贝数据,默认为 False。

Pandas 数据结构 - DataFrame

DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。

在这里插入图片描述

pandas.DataFrame( data, index, columns, dtype, copy)
  • 1
  • 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

导入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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
导入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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
重命名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={})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
重命名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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

如果是有相同的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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

DataFrame merge函数有两个重要的参数要重点介绍,on就是对于那个字典合并,how就是对那部分进行补全,和Mysql的join有点相似。

  • how :left/right/outer,默认是inner,取全部数据
pd.merge(df1,df2,on='key',how="outer")
  • 1
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
通过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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
通过去重进行数据清洗

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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
时间序列的操作基础

可以使用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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
时间序列的采样和画图
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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
数据分箱技术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'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
数据分组技术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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
数据聚合技术Aggregation
df.agg()
  • 1
透视表

为了更好的去展示数据,临时把原始表结构进行了一次变更,根据这些变化,也产生相应的变化,这是透视表的概念。

使用函数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'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这里插入图片描述

# 画布
figure , ax = plt.subplots(2,2)
ax[0][0].plot(x,y1)
ax[0][1].plot(x,y2)
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

df.plot(kind="bar",stacked=True)
  • 1

在这里插入图片描述

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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

sns.kdeplot(s1,shade=True,color='#00FFFF')
  • 1
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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

//seaborn实现一个柱状图

s = df.sum()
sns.barplot(x=s.index,y=s.values)
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/133828
推荐阅读
相关标签
  

闽ICP备14008679号