计设工作

Zincsearch是什么?如何利用它建立索引与调用api?

参考文章:ZincSearch轻量级全文搜索引擎入门到-CSDN博客

官方:https://github.com/zincsearch/zincsearch

数据清洗的步骤?具体实现?

数据清洗(Data cleaning)– 对数据进行重新审查和校验的过程,目的在于删除重复信息、纠正存在的错误,并提供数据一致性。 数据清洗从名字上也看的出就是把“脏”的“洗掉”,指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。

常用的数据清洗方法主要有以下四种:丢弃、处理和真值转换。让我们来看看这四种常见的数据清洗方法:

1、丢弃部分数据

丢弃,即直接删除有缺失值的行记录或列字段,以减少趋势数据记录对整体数据的影响,从而提高数据的准确性。但这种方法并不适用于任何场景,因为丢失意味着数据特征会减少,以下两个场景不应该使用丢弃的方法:数据集中存在大量数据记录不完整和数据记录缺失值明显的数据分布规则或特征。

2、补全缺失的数据

与丢弃相比,补充是一种更常用的缺失值处理方法,通过某种方法补充缺失的数据,形成完整的数据记录对后续的数据处理。分析和建模非常重要。

3、不处理数据

不处理是指在数据预处理阶段,不处理缺失值的数据记录。这主要取决于后期的数据分析和建模应用。许多模型对缺失值有容忍度或灵活的处理方法,因此在预处理阶段不能进行处理。

4、真值转换法

承认缺失值的存在,并将数据缺失作为数据分布规律的一部分,将变量的实际值和缺失作为输入维度参与后续数据处理和模型计算。然而,变量的实际值可以作为变量值参与模型计算,而缺失值通常不能参与计算,因此需要转换缺失值的真实值。

实例:

解决缺失值

大多数情况下,缺失值必须手工填入(即手工清理)。而本例介绍的是利用Python中的fillna() 来对大量数据进行填补缺失值,还有dropna()可以直接将包含空值的数据删除。一般情况下,会以平均值、最大值、最小值或更为复杂的概率估计代替缺失值,具体问题具体分析,重点在于补全值对原数据的影响不大。

以下<缺失值.py>代码用到Kaggle中的Titanic数据集

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
#解决缺失值
#需要提前在Windows PowerShell中输入pip install numpy 和 pip install pandas 命令来安装两个包
import pandas as pd
import numpy as np

titanic_df=pd.read_csv('C:/Users/pc/Desktop/mydata/train.csv')
#用pandas.read_csv()方法读入train.csv,读入后数据的类型默认是DataFrame

#选择用于训练的特征
features=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
x_train = titanic_df[features]
x_train.info()
#用DataFrame.info()方法得到它的列变量信息,通过信息可看出训练数据中Age,Embarked存在缺失值
x_train[x_train.isnull().values==True]
#数据框引用某一列有两种方式,一个是用.引用,一个是[]引用
#isnull()会返回一个值是boolean的Series序列,所以上一句代码可以返回含有缺失值的行和列,从而找到缺失值的位置

#Age是数值型数据,可以使用平均值来补全空值,尽量减小补全值对结果的影响。
#使用平均年龄来填充年龄中nan值
x_train['Age'].fillna(x_train['Age'].mean(),inplace=True)
#fillna()会填充nan数据,返回填充后的结果。如果希望在原DataFrame中修改,则把inplace设置为True

#Embarked是类别数据,取出现次数最多的类别来补全空值。
#使用登录最多的港口来填充登录港口的nan值
print(x_train['Embarked'].value_counts())
x_train['Embarked'].fillna('S',inplace=True)
#重新检查数据中是否存在缺失值
x_train.info()

检测并消除重复值

数据中属性值相同的记录被认为是重复记录,通过判断记录间的属性值是否相等来检测记录是否相等,相等的记录合并为一条记录,简称为去重。

本例主要用到了Python中的duplicated()drop_duplicates(),前者标记出哪些是重复的(true),后者直接将重复删除。

以下<去重.py>代码沿用上例的Titanic数据集

1
2
3
4
5
6
7
8
9
10
11
12
#检测并消除重复值
import pandas as pd
import numpy as np
titanic_df=pd.read_csv('C:/Users/pc/Desktop/mydata/train.csv')
features= = ['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
x_train = titanic_df[features]
x_train.info() #通过信息可知x_train是一个891×7的数据框
print(x_train.duplicated()) #输出重复行
x_train_noDup = x_train.drop_duplicates() #删除重复行
x_train_noDup.info()
#重新查看去重后的数据,x_train_noDup是一个764×7的数据框
#即删除了27行

检测并解决错误值

用统计分析的方法识别可能的错误值或异常值,如偏差分析、识别不遵守分布或回归方程的值,也可以用简单规则库(常识性规则、业务特定规则等)检查数据值,或使用不同属性间的约束、外部的数据来检测和清理数据。

异常值的存在会影响实验结果。异常值是指样本中的个别值,也称为离群点,其数值明显偏离其余的观测值。常用检测方法3σ原则和箱型图。其中,3σ原则只适用服从正态分布的数据。在3σ原则下,异常值被定义为观察值和平均值的偏差超过3倍标准差的值。在正态分布假设下,大于3σ的值出现的概率小于0.003,属于小概率事件,故可认定其为异常值。

3σ原则对数据分布有一定限制,而箱型图并不限制数据分布,只是直观表现出数据分布的本来面貌。其识别异常值的结果比较客观,而且判断标准以四分位数和四分位间距为标准,多达25%的数据可以变得任意远而不会扰动这个标准,鲁棒性更强,所以更受大家亲睐。

实例:

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#检测并解决错误值
#需要提前在Windows PowerShell中输入pip install matplotlib来安装包
#-*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt #导入图像库

number = 'C:/Users/pc/Desktop/mydata/all_musicers.csv'
data = pd.read_csv(number)

data1=data.iloc[:,0:10]
#pandas中的iloc[]通过行号获取行数据,10位歌手的183天音乐播放量
#data2=data.iloc[:,10:20]
#data3=data.iloc[:,20:30]
#data4=data.iloc[:,30:40]
#data5=data.iloc[:,40:50]

plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
plt.figure(1, figsize=(8, 10)) #可设定图像大小
#plt.figure() #建立图像
p = data1.boxplot(return_type='dict')
#画箱线图,直接使用DataFrame的方法.代码到这为止,就已经可以显示带有异常值的箱型图了,但为了标注出异常值的数值,还需要以下代码进行标注.

for i in range(0,10):
x = p['fliers'][i].get_xdata()
# 'flies'即为异常值的标签.[0]是用来标注第1位歌手的异常值数值,同理[i]标注第i+1位歌手的异常值.
y = p['fliers'][i].get_ydata()
y.sort() #从小到大排序
#用annotate添加注释
#其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。
#以下参数都是经过调试的,需要据以问题具体调试。
#xy表示要标注的位置坐标,xytext表示文本所在位置
for j in range(len(x)):
if j>0:
plt.annotate(y[j], xy = (x[j],y[j]), xytext=(x[j]+0.05 -0.8/(y[j]-y[j-1]),y[j]))
else:
plt.annotate(y[j], xy = (x[j],y[j]), xytext=(x[j]+0.08,y[j]))

plt.show() #展示箱线图
#输出结果中,○所表示的均是(统计学认为的)异常值.工作中,要结合数据应用背景, 距离箱型图上下界很近的可归为正常值.

#异常值处理
#通过分析以上标注的异常值及其位置,决定将异常值视为缺失值,并用前后值的均值来填补
for i in range(0,182):
if data1.iloc[:,1][i]>125:
data1.iloc[:,1][i]=(data1.iloc[:,1][i+1]+data1.iloc[:,1][i-1])/2
for i in range(0,182):
if data1.iloc[:,2][i]>600:
data1.iloc[:,2][i]=(data1.iloc[:,2][i+1]+data1.iloc[:,1][i-1])/2
for i in range(0,182):
if data1.iloc[:,4][i]>225:
data1.iloc[:,4][i]=(data1.iloc[:,4][i+1]+data1.iloc[:,4][i-1])/2
for i in range(0,182):
if data1.iloc[:,7][i]>60:
data1.iloc[:,7][i]=(data1.iloc[:,7][i+1]+data1.iloc[:,7][i-1])/2
for i in range(0,182):
if data1.iloc[:,8][i]>2500:
data1.iloc[:,8][i]=(data1.iloc[:,8][i+1]+data1.iloc[:,8][i-1])/2

#datan=pd.concat([data1,data2,data3,data4,data5],axis=1)
data1.to_csv('C:/Users/pc/Desktop/mydata/train_innoraml.csv',index=False)

异常值处理

删除:对于数据量比较小的数据,删除会造成样本不足,减少有用信息。

视为缺失值:用均值、插值等方法进行填补

不处理:将缺失值视为一种特征,统计其缺失个数等信息作为缺失特征。

检测并解决不一致性

从多数据源集成的数据可能有语义冲突,发生在数据源内部和数据源之间,可定义完整性约束用于检测不一致性。

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
#检测并解决不一致性
import numpy as np
import pandas as pd
loandata=pd.read_csv('C:/Users/pc/Desktop/mydata/LoanStats3a.csv')
loandata.duplicated()
#通过信息可看出没有重复值
loandata.info()
loandata['annual_inc']=loandata['annual_inc'].fillna(loandata['annual_inc'].mean())
#对于annual_inc列,选择用现有数据的均值进行填充。
loandata['loan_status'].value_counts()
#对loan_status列进行频率统计时,由于空格问题,相同的贷款状态被重复计算,造成统计结果不可用。
#因此,我们需要解决字段中存在的空格问题。
loandata['loan_status']=loandata['loan_status'].map(str.strip) #去除两边的空格
loandata['loan_status'].value_counts()
#重新查看loan_status列中每种贷款状态的频率,之前空格造成的影响已经没有了。
#但这里还有大小写的问题。因此,我们还需要对每种贷款状态的大小写进行统一化处理。
loandata['loan_status']=loandata['loan_status'].map(str.title)
#将所有贷款状态转换为首字母大写模式,并再次进行频率统计。
loandata['loan_status'].value_counts()
#最后我们还需要对数据表中关键字段的内容进行检查,确保关键字段中内容的统一。
#主要包括数据是否全部为字符,或数字。
#下面我们对emp_length列进行检验,此列内容由数字和字符组成,如果只包括字符,说明可能存在问题。
#下面的代码中我们检查该列是否全部为字符。答案全部为False。
loandata['emp_length'].apply(lambda x: x.isalpha())
#由于贷款金额通常为整数,因此将数据格式改为int64
loandata['loan_amnt']=loandata['loan_amnt'].astype(np.int64)
#利用to_datetime函数处理日期格式的数据
loandata['issue_d']=pd.to_datetime(loandata['issue_d'])
#更改后可通过dtypes函数来查看每个字段的数据格式
loandata.dtypes
loandata.to_csv('C:/Users/pc/Desktop/mydata/loandat1.csv',index=False)

数据存在多余的空格。当我们想要对某一列的数据进行频率统计的时候,由于空格的问题,相同的内容可能被重复计算,造成统计结果不可用。因此,我们需要解决字段中存在的空格问题。

1
2
3
4
5
6
7
去除空格的方法有三种:
去除数据两边的空格:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.strip)
去除数据左边的空格:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.lstrip)
去除数据右边的空格:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.rstrip)

数据大小写不一致。英文大小写不一致也是常常遇到的问题。

1
2
3
4
5
6
7
大小写转换的方法也有三种:
全部转为大写:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.upper)
全部转为小写:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.lower)
首字母大写:
loandata[' loan_status’]=loandata[‘loan_status’].map(str.title)

数据的格式不一致。有时候经过多次数据处理之后,出现数据内容格式不统一、数据格式不规范等问题,这个时候就需要我们采取一定的措施。

1
2
3
4
5
6
7
8
9
10
检查是否全部为字符:
loandata[‘emp_length’].apply(lambda x: x.isalpha())
检查是否全部为字母:
loandata[‘emp_length’].apply(lambda x: x.isalnum())
检查是否全部为数字:
loandata[‘emp_length’].apply(lambda x: x.isdigit())
更改数据格式:
loandata[‘loan_amnt’]=loandata[‘loan_amnt’].astype(np.int64)
日期格式的数据:
loandata[‘issue_id’]=pd.to_datetime(loandata[‘issue_d’])

数据预处理

在经过了一定的数据清洗操作之后,我们或许还希望数据更加适合后续的分析工作。提前对数据进行预处理,后面的挖掘和分析工作会更加高效。这些预处理包括数据分组、数据分列、添加或删除前后缀、字符拼接和转换文件的格式。下面我们逐一来介绍这部分的操作过程和使用到的函数。

(1) 数据分组、分列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#数据分组
import numpy as np
import pandas as pd
loandata=pd.read_csv('C:/Users/pc/Desktop/mydata/loandata1.csv')
#首先设置数据分组的依据bins,然后设置每组对应的名称group_names。
bins = [0, 5, 10, 15, 20]
group_names = ['A', 'B', 'C', 'D']
#使用cut函数对数据进行分组并将分组后的名称添加到数据表中。
loandata['categories'] = pd.cut(loandata['open_acc'], bins, labels=group_names)

#数据分列
#在原数据表中grade列中包含了两个层级的用户等级信息,现在我们通过数据分列将分级信息进行拆分。
#数据分列操作使用的是split函数。
grade_split=pd.DataFrame((x.split('-') for x in loandata.grade),
index=loandata.index,columns=['grade','sub_grade'])
#完成数据分列操作后,使用merge()函数将数据匹配回原始数据表
loandata=pd.merge(loandata,grade_split,right_index=True, left_index=True)
loandata.to_csv('C:/Users/pc/Desktop/mydata/loandata2.csv',index=False)

(2) 添加或删除前后缀。

如果想对数据的前或后添加相同的内容,可以利用Notepad++中的“替换工具,实际上,这里用到的是正则不等式。正则不等式在提取有效数据上很有帮助,但由于正则不等式十分繁杂,所以不再这里做过多的介绍。当需要用到正则不等式时再在网上搜索相关知识就可以了。

(3) 字符拼接。

下面总结了五种在python中的字符串拼接方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#字符串拼接
#第一种方式
print('第一种方式通过加号形式连接 :' + 'love'+'Python' + '\n')

#第二种方式
print('第二种方式通过逗号形式连接 :' + 'love', 'Python' + '\n')

#第三种方式
print('第三种方式通过直接连接形式连接 (一) :' + 'love''Python' + '\n')
print('第三种方式通过直接连接形式连接 (二) :' + 'love' 'Python' + '\n')

#第四种方式
print('第四种方式通过格式化形式连接 :' + '%s %s' % ('love', 'Python') + '\n')

#第五种方式
str_list = ['love', 'Python']
print('第五种方式通过join形式连接 :' + ''.join(str_list) + '\n')

(4) 转换文件格式。有时候我们需要转换文件的格式,从而是适应某一些处理方式。接下来介绍如何利用python在CSV与JSON之间转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#使用Python实现CSV到JSON的数据转换
#使用内置的csv和json库
import json
import csv

#读取文件
with open('C:/Users/pc/Desktop/mydata/loandata2.csv') as file:
file_csv = csv.DictReader(file) #数据是字典类型,表格的表头为键、每一行的值为值,值有几行就打印几个字典。
output = '['
#处理每一个目录
for row in file_csv:
#两个实体之间加入逗号
output+=json.dumps(row) + ',' #将Python数据结构转换为JSON格式(字符串)
output = output.rstrip(',') + ']' #rstrip()函数将从字符串最右边删除逗号
#把文件写入磁盘中去
f = open('C:/Users/pc/Desktop/mydata/loandata2Py.json','w')
f.write(output)
f.close()
1
2
3
4
5
6
7
8
9
10
11
#Python 实现JSON到CSV的数据转换
import json
import csv

with open('C:/Users/pc/Desktop/mydata/loandata2Py.json','r') as f:
dicts = json.load(f) #加载json数据
out = open('C:/Users/pc/Desktop/mydata/loandata2Py.csv','w')
writer = csv.DictWriter(out,dicts[0].keys()) #将一个JSON编码的文件转换为一个Python数据结构的文件
writer.writeheader() #将表头名称写入csv文件
writer.writerows(dicts) #同时写入多行信息
out.close()

相关链接:

另一种概述:关于数据清洗的步骤及方法的理解_数据清洗的基本步骤-CSDN博客

excel数据清洗举例:https://www.woshipm.com/data-analysis/4293282.html

课程PPT详述(较为详细可作为具体实现指导):通过网盘分享的文件:数据清洗PPT.zip
链接: https://pan.baidu.com/s/13_HB2XDGqdIbw_xJkStLyw?pwd=rv27 提取码: rv27
—来自百度网盘超级会员v5的分享