当前位置 : 主页 > 编程语言 > python >

python数据分析与挖掘笔记

来源:互联网 收集:自由互联 发布时间:2022-06-24
参考书 小飞蓬对本书选取重要知识点进行归总,并手动编写其中的代码 1 数据分析与挖掘区别 从定义说明:数据分析采用统计学方法,对获取的数据进行描述性和探索性分析,并从分

参考书

python数据分析与挖掘笔记_数组
小飞蓬对本书选取重要知识点进行归总,并手动编写其中的代码

1 数据分析与挖掘区别

  • 从定义说明:数据分析采用统计学方法,对获取的数据进行描述性和探索性分析,并从分析结论中发现数据间存在的价值,价值大多通过图的形式呈现。数据挖掘则是采用统计学,机器学习,人工智能的方法,对获取的数据,进行提炼、转化(类似于赌石),从数据中发掘出表象看不到的价值和规律
  • 从工作侧重点:数据分析更侧重于实际业务,贴合业务展开分析工作,而数据挖掘更侧重于技术,通过更前进更换的算法,去提炼出更有价值的东西
  • 从输出结果出来:数据分析更多是统计描述的呈现,比如总体样本的趋势。数据挖掘更多是模型和规则的输出

2 数据挖掘流程

python数据分析与挖掘笔记_数据挖掘_02

3 python基础知识

数据结构及方法

列表

  • 列表索引:正向索引、负向索引、切片索引、无限索引
  • 列表操作:
    元素增加:append、extend、insert
list=[1,10,100,1000,10000]

#append 在末尾添加数字
list.append(2)
print(list)
out:[1,10,100,1000,10000,2]

#extend在末尾添加多个元素
list.extend([20,200,2000,20000])
print(list)
out:[1,10,100,1000,10000,20,200,2000,20000]

#insert在指定位置插入新值
list.insert(2,11)
print(list)
out:[1,10,11,100,1000,10000]

元素删除:pop、remove、clear

list=[1,10,11,100,1000,10000]

#pop默认删末尾元素,也可以指定位置删除
list.pop()
print(list)
out:[1,10,11,100,1000]
list.pop(2)
print(list)
out:[1,10,100,1000,10000]

#remove删除指定值,但只能删除列表中第一次出现指定值
list.remove(11)
print(list)
out:[1,10,100,1000,10000]

#clear清空列表
list.clear()
print(list)
out:[]
  • 列表计数、查询位置、逆转、排序
list=[7,3,9,11,4,6,10,3,7,4,4,3,6,3]
#计算列表元素3的个数
print(list.count(3))
#找出元素6所在位置
print(list.index(6))
#元素颠倒
print(list.reverse())
#列表元素降序
print(list.sort(reverse=True))

元组

元组与列表操作类似,但最大区别是元组是一种不变的类型的数据结构,简单说元组不能实现元素删除,修改,插入,但可以删除整个元组

字典

  • 字典操作
    字典元素增加:setdefault、update和键索引
dict={'姓名':'张三','年龄':33,'性别':'男','子女':{'儿子':'张四','女儿':'张美'},'兴趣':{'踢球','游泳','唱歌'}}
#增加元素
dict.setdefault('户籍','合肥')
dict.update(('学历':'硕士'))
dict['身高']=178

字典元素删除:pop、popitem、clear

#删除指定值
dict.pop('户籍')
dict['子女'].pop('女儿')
#删除字典中任意的一个元素
dict.popitem()
#清空元素
dict.clear()

字典其他方法:get(),keys(),values(),items()

#get从字典中取出键对应的值
print(dict.get('年龄'))
#keys取出所有键
print(dict.keys())
#values取出字典所有值
print(dict.values())
#items取出所有值对
print(dict.items())

字符串处理方法

字符串的常用方法

方法

使用说明

string[start: end :step]

字符串的切片

string.split

字符串分割

string.strip

删除首尾空白

string.rstrip

删除字符串右边空白

string.lstrip

删除字符串左边空白

string.index

返回子串首次出现的位置

string.replace

字符串替换

sep.join

将可迭代对象按sep分割符拼接为字符串

string.count

对字符串 的子串计数

string.find

返回子串首次出现位置

string.startwith

字符串是否以什么开头

string.endwith

字符串是否以什么结尾

正则表达式

符号

含义

示例

.

可以匹配任意字符,但不包含换行符’\n’

pyt.on~python

\

转义符,一般用于保留字符中特殊元字符

10\ .3~10 .3


逻辑或

人a丨A~人a或者人A

[]

用于匹配一组字符

m[aA]n~man或者mAn

\d与\D

\d匹配任意数字,\D代表非\d

今天\d号~今天3号

\s与\S

\s匹配任意空白字符,\S代表非\s

你\s好~你 好

\w与\W

\w匹配字母数字和下划线,\W代表非\w

p\wy~pay

*

匹配前一个字0到无穷次

OK*~O或者OK或者OKK

+

匹配前一个字符1到无穷次

OK+~OK或者OKK

?

匹配前一个字符0到1次

OK?~0或者OK

{m}

匹配前一个字符m次

OK{3}~OKKK

{m,n}

匹配前一个字符m到n次

OK{1,2}~OK或者OKK

(.*?)

用于分组,默认返回括号内匹配内容

  • 匹配查询函数
    findall(pattern,string,flags=0),获取字符串所有匹配的子串,并返回一个列表结果
  • 匹配替换函数
    sub(pattern,rel,string,count=0,flags=0),该函数根据正则表达式把满足匹配的内容替换为repl
  • 匹配分割函数
    split(pattern,string,maxsplit=0,flags=0),按照指定正则表达式分隔字符

自定义函数

自定义函数可变参数(*args,**kwargs)

*args:可以接纳任意多个实参,接受多个实参,进行捆绑,并组装到元组中
**kwargs:可以把多个实参指定给各自的实参名

def adds(*args):
print(args)
s=sum(args)
return(s)
print('和为%d'%adds(10,13,7,8,2))

def info_collection(tel,birthday,**kwargs):
user_info={}
user_info['tel']=tel
user_info[birthday]=birthday
user_info.update(kwargs)
return(user_info)
info_collection(1214,'1990-11-11',nickname='yewe',gender='nan')

区别*args是用来发送一个非键值对的可变数量的参数列表给一个函数,**kwargs将不定长度的键值对,作为参数传递给一个函数

应用爬虫案例

项目目的为了获取城市的历史天气数据。字段包含日期、最低气温、最高气温、风向、风力、天气状况、空气质量指标值、空气质量等级和空气质量说明

# 导入第三方包
import requests
import time
import random
import pandas as pd
import re

# 生成请求头
headers = {
'Accept':'*/*',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.9',
'Connection':'keep-alive',
'Cookie':'widget_dz_id=54511; widget_dz_cityValues=,; timeerror=1; defaultCityID=54511; defaultCityName=%u5317%u4EAC; Hm_lvt_a3f2879f6b3620a363bec646b7a8bcdd=1516245199; Hm_lpvt_a3f2879f6b3620a363bec646b7a8bcdd=1516245199; addFavorite=clicked',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.0 Safari/537.36'
}

# 生成所有需要抓取的链接
urls = []
for year in range(2011,2018):
for month in range(1,13):
if year <= 2016:
urls.append('http://tianqi.2345.com/t/wea_history/js/58362_%s%s.js' %(year,month))
else:
if month<10:
urls.append('http://tianqi.2345.com/t/wea_history/js/%s0%s/58362_%s0%s.js' %(year,month,year,month))
else:
urls.append('http://tianqi.2345.com/t/wea_history/js/%s%s/58362_%s%s.js' %(year,month,year,month))
urls

# 循环并通过正则匹配获取相关数据
info = []
for url in urls:
seconds = random.randint(3,6)
response = requests.get(url, headers = headers).text
ymd = re.findall("ymd:'(.*?)',",response)
high = re.findall("bWendu:'(.*?)℃',",response)
low = re.findall("yWendu:'(.*?)℃',",response)
tianqi = re.findall("tianqi:'(.*?)',",response)
fengxiang = re.findall("fengxiang:'(.*?)',",response)
fengli = re.findall(",fengli:'(.*?)'",response)
aqi = re.findall("aqi:'(.*?)',",response)
aqiInfo = re.findall("aqiInfo:'(.*?)',",response)
aqiLevel = re.findall(",aqiLevel:'(.*?)'",response)

# 由于2011~2015没有空气质量相关的数据,故需要分开处理
if len(aqi) == 0:
aqi = None
aqiInfo = None
aqiLevel = None
info.append(pd.DataFrame({'ymd':ymd,'high':high,'low':low,'tianqi':tianqi,'fengxiang':fengxiang,'fengli':fengli,'aqi':aqi,'aqiInfo':aqiInfo,'aqiLevel':aqiLevel}))
else:
info.append(pd.DataFrame({'ymd':ymd,'high':high,'low':low,'tianqi':tianqi,'fengxiang':fengxiang,'fengli':fengli,'aqi':aqi,'aqiInfo':aqiInfo,'aqiLevel':aqiLevel}))
time.sleep(seconds)

# 生成数据表
weather = pd.concat(info)
# 数据导出
weather.to_csv('weather.csv',index = False)

4.python数值计算工具-numpy

数组获取[rows,cols]

arr[[1,3],[1,3]]:
python数据分析与挖掘笔记_字符串_03
arr[np.ix_([1,3],[1,3])]
python数据分析与挖掘笔记_数据挖掘_04

数据常用属性

在numpy模块汇总,可以通过genfromtxt函数读取外部文本文件数据

# 读入数据
stu_score = np.genfromtxt(fname = r'C:\Users\Administrator\Desktop\stu_socre.txt',delimiter='\t',skip_header=1)
# 查看数据结构
print(type(stu_score))
# 查看数据维数
print(stu_score.ndim)
# 查看数据行列数
print(stu_score.shape)
# 查看数组元素的数据类型
print(stu_score.dtype)
# 查看数组元素个数
print(stu_score.size)

数组的形状处理

方法:reshape、resize、ravel、flatten、vstack、hstack、row_stack、column_stack
reshape、resize都是对数组进行形状改变
reshape的改变只是预览,没有直接改变数组形状
resize方法不会返回预览,而是直接改变数组形状

如果需要将多维数组降维一维数组,利用ravel、flatten、reshape三种方法

arr4 = np.array([[1,10,100],[2,20,200],[3,30,300]])
print('原数组:\n',arr4)
# 默认排序降维
print('数组降维:\n',arr4.ravel())
print(arr4.flatten())
print(arr4.reshape(-1))
# 改变排序模式的降维
print(arr4.ravel(order = 'F'))
print(arr4.flatten(order = 'F'))
print(arr4.reshape(-1, order = 'F'))

vstack,row_stack纵向堆叠数组
hstack,column_stack横向堆叠数组

线性代数相关计算

函数

说明

np.zeros

生成零矩阵

np.eyes

生成单位矩阵

np.dot

数组点积

np.diag

矩阵主对角线与一维数组间的转化

np.ones

生成所有元素为1矩阵

np.transpose

矩阵转置

np.inner

计算两个数组内积

np.trace

矩阵主对角线元素的和

np.linalg.det

计算矩阵行列式

np.linalg.eig

计算矩阵特征根与特征向量

np.linalg.eigvals

计算方阵特征根

np.linalg.inv

方阵逆

np.linalg.pinv

计算伪逆

np.linalg.solve

计算Ax=b的线性方程组的解

np.linalg.lstsq

计算Ax=b的最小二乘解

np.linalg.qr

QR分解

np.linalg.svd

奇异值分解

np.linalg.norm

计算向量或矩阵的范数

python数据处理工具-pandas

pandas对应的数据构造和数据读取这里不再阐述

数据类型转换及描述统计

通常拿到数据后,观看数据的shape以及的dtypes
修改数据类型,数值类型修改,时间类型修改
对数值类型数据进行统计描述,对离散型数据进行统计描述

# 数据类型转换及描述统计
# 数据读取
sec_cars = pd.read_table(r'C:\Users\Administrator\Desktop\sec_cars.csv', sep = ',')
# 预览数据的前五行
sec_cars.head()
# 查看数据的行列数
print('数据集的行列数:\n',sec_cars.shape)
# 查看数据集每个变量的数据类型
print('各变量的数据类型:\n',sec_cars.dtypes)

# 修改二手车上牌时间的数据类型
sec_cars.Boarding_time = pd.to_datetime(sec_cars.Boarding_time, format = '%Y年%m月')
# 修改二手车新车价格的数据类型
sec_cars.New_price = sec_cars.New_price.str[:-1].astype('float')
# 重新查看各变量数据类型
sec_cars.dtypes

# 数据的描述性统计
sec_cars.describe()
# 数据的形状特征
# 挑出所有数值型变量
num_variables = sec_cars.columns[sec_cars.dtypes !='object'][1:]
# 自定义函数,计算偏度和峰度
def skew_kurt(x):
skewness = x.skew()
kurtsis = x.kurt()
# 返回偏度值和峰度值
return pd.Series([skewness,kurtsis], index = ['Skew','Kurt'])
# 运用apply方法
sec_cars[num_variables].apply(func = skew_kurt, axis = 0)

# 离散型变量的统计描述
sec_cars.describe(include = ['object'])
# 离散变量频次统计
Freq = sec_cars.Discharge.value_counts()
Freq_ratio = Freq/sec_cars.shape[0]
Freq_df = pd.DataFrame({'Freq':Freq,'Freq_ratio':Freq_ratio})
Freq_df.head()

# 将行索引重设为变量
Freq_df.reset_index(inplace = True)
Freq_df.head()

字符与日期数据的处理

python数据分析与挖掘笔记_数组_05
数据处理:

  • 改变出生日期birthday和手机号tel两个字段的数据类型
  • 根据出生日期birthday和开始工作日期start_work两个字段新增年龄和工龄两个字段
  • 将手机号tel的中间四位隐藏
  • 根据邮箱信息新增邮箱域名字段
  • 基于other字段取出每个人员的专业信息
# 数据读入
df = pd.read_excel(r'C:\Users\Administrator\Desktop\data_test03.xlsx')
# 各变量数据类型
print(df.dtypes)
# 将birthday变量转换为日期型
df.birthday = pd.to_datetime(df.birthday, format = '%Y/%m/%d')
# 将手机号转换为字符串
df.tel = df.tel.astype('str')
# 新增年龄和工龄两列
df['age'] = pd.datetime.today().year - df.birthday.dt.year
df['workage'] = pd.datetime.today().year - df.start_work.dt.year
# 将手机号中间四位隐藏起来
df.tel = df.tel.apply(func = lambda x : x.replace(x[3:7], '****'))
# 取出邮箱的域名
df['email_domain'] = df.email.apply(func = lambda x : x.split('@')[1])
# 取出用户的专业信息
df['profession'] = df.other.str.findall('专业:(.*?),')
# 去除birthday、start_work和other变量
df.drop(['birthday','start_work','other'], axis = 1, inplace = True)
df.head()# 常用日期处理方法
dates = pd.to_datetime(pd.Series(['1989-8-18 13:14:55','1995-2-16']), format = '%Y-%m-%d %H:%M:%S')
print('返回日期值:\n',dates.dt.date)
print('返回季度:\n',dates.dt.quarter)
print('返回几点钟:\n',dates.dt.hour)
print('返回年中的天:\n',dates.dt.dayofyear)
print('返回年中的周:\n',dates.dt.weekofyear)
print('返回星期几的名称:\n',dates.dt.weekday_name)
print('返回月份的天数:\n',dates.dt.days_in_month)

数据清洗方法

重复观测处理

df.drop_duplicates(inplace=True)

缺失值处理

当遇到缺失值NaN表示时,采用三种方法处置:

  • 替换法:均值、中位数替换
  • 删除法:当缺失数据比例在5%以内
  • 插补法:回归插补法、K近邻插补、拉格朗日插补
# 数据读入
df = pd.read_excel(r'C:\Users\Administrator\Desktop\data_test05.xlsx')
# 缺失观测的检测
print('数据集中是否存在缺失值:\n',any(df.isnull()))
# 删除法之记录删除
df.dropna()
# 删除法之变量删除
df.drop('age', axis = 1)
# 替换法之前向替换
df.fillna(method = 'ffill')
# 替换法之后向替换
df.fillna(method = 'bfill')
# 替换法之常数替换
df.fillna(value = 0)
# 替换法之统计值替换
df.fillna(value = {'gender':df.gender.mode()[0], 'age':df.age.mean(), 'income':df.income.median()})

异常值处理

对于异常值检测,采用两种方法:

  • n个标准差法
  • 箱线图判别法
    python数据分析与挖掘笔记_数据_06

数据子集获取

iloc、loc、ix(它们的语法可以表示成[row_select,cols_select])

name

gender

age

0

张三


23

1

李四


25

2

王二


23

3

丁一


21

4

李五


20

df1=pd.DataFrame({'name':['张三','李四','王二','丁一','李五'],
'gender':['男','女','女','女','男'],
'age':[23,25,23,21,20],columns=['name','gender','age']})
df1.iloc[1:4,[0,2]]
df1.loc[1:3,['name','age']]
df1.ix[1:3,[0,2]]

name

age

1

李四

25

2

王二

23

3

丁一

21

透视表功能

生成透视表函数

pd.pivot_table(data,values=None,index=None,columns=None,aggfunc='mean',fill_value=None,margins=False,dropna=True,margins_name='All')
  • data:指定需要构造透视表的数据集 values:指定需要拉入的数值的字段列表
  • index:指定拉入的行标签的字段列表
  • columns:指定拉入列标签的字段列表
  • aggfunc:指定数值统计函数
  • fill_value:指定一个标量。用于填充缺失值
  • margins:bool类型参数,是否需要显示行或列的总计值
  • dropna:bool参数,是否需要删除整列缺失字段
  • margins_name:指定行或列的总计名称

挖掘算法实践

线性回归模型

一元线性回归模型

目标函数公式:
python数据分析与挖掘笔记_数据_07
关于目标函数求导:
1.设偏导数为0
python数据分析与挖掘笔记_数组_08
2.公式转化
python数据分析与挖掘笔记_字符串_09
3.化解python数据分析与挖掘笔记_字符串_10
4.求解a、b
python数据分析与挖掘笔记_数据_11
代码实现

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 导入数据集
income = pd.read_csv(r'C:\Users\Administrator\Desktop\Salary_Data.csv')
# 绘制散点图
sns.lmplot(x = 'YearsExperience', y = 'Salary', data = income, ci = None)
# 显示图形
plt.show()

# 简单线性回归模型的参数求解
# 样本量
n = income.shape[0]
# 计算自变量、因变量、自变量平方、自变量与因变量乘积的和
sum_x = income.YearsExperience.sum()
sum_y = income.Salary.sum()
sum_x2 = income.YearsExperience.pow(2).sum()
xy = income.YearsExperience * income.Salary
sum_xy = xy.sum()
# 根据公式计算回归模型的参数
b = (sum_xy-sum_x*sum_y/n)/(sum_x2-sum_x**2/n)
a = income.Salary.mean()-b*income.YearsExperience.mean()
# 打印出计算结果
print('回归参数a的值:',a)
print('回归参数b的值:',b)

# 导入第三方模块
import statsmodels.api as sm
# 利用收入数据集,构建回归模型
fit = sm.formula.ols('Salary ~ YearsExperience', data = income).fit()
# 返回模型的参数值
fit.params

多元线性回归模型

目标函数公式:
python数据分析与挖掘笔记_数据挖掘_12
关于目标函数求导:
1.求偏导为0
python数据分析与挖掘笔记_数据_13
2.计算偏回归系统值
python数据分析与挖掘笔记_数据挖掘_14

回归模型的假设检验

模型的显著性检验-F检验1.提出假设

python数据分析与挖掘笔记_数据挖掘_15
H0为原假设,假设认为模型的所有偏回归系统全为0,认为没有一个自变量可以构成因变量的线性组合,H1为备选假设,与原假设对立。
2.构造统计量
python数据分析与挖掘笔记_数据_16
python数据分析与挖掘笔记_字符串_17python数据分析与挖掘笔记_数据挖掘_18
其中p和n-p-1分别为RSS和ESS的自由度,模型拟合越好,ESS就会越小,RSS则会越大,F统计量也就越大。

KNN模型应用

算法思想:

  • 确定未知样本近邻的个数k值
  • 根据某种度量样本间相似度的指标(如欧式距离)将每个未知类别的样本的最近k个已知样本搜寻出来,形成一个个簇
  • 对搜寻出来的已知样本进行投票,将各簇下类别最多的分类用作未知样本点的预测
  • 最佳k值选择:

  • 设置k近邻样本投票权重
  • 采用多重交叉验证,将选择k个不同的值,在每种值下执行m重交叉验证,最后选出平均误差最小的k值
  • 相似度度量方法

  • 欧式距离
    python数据分析与挖掘笔记_数据_19
  • 曼哈顿距离
    python数据分析与挖掘笔记_数据_20
  • 余弦相似度
    python数据分析与挖掘笔记_数组_21python数据分析与挖掘笔记_数据挖掘_22
  • 杰卡德相似系数
    python数据分析与挖掘笔记_字符串_23
  • 朴素贝叶斯模型

    SVM模型应用

    GBDT模型应用

    待更新。。。。


    上一篇:python数据科学应用
    下一篇:没有了
    网友评论