JAVA订单报表数据清洗机制_pandas进行数据预处理(数据清洗)
前言:最近在进行NLP学习时,聚类得到的效果总是差强人意,反复思考后发现自己的数据集非常不规范,因此,学习python的pandas库对数据进行预处理。
1.数据集加载
import pandas as pd
import numpy as np
def dataSet():
data_set = [["蒜蓉生耗", "蒙古烤羊腿", "白斩鸡", "纸杯蛋糕", "蒜蓉生耗"],
["有", "无", "有", "有", "有"],
["本店招牌菜,进店必点", "店主强烈推荐", "不辣", "", "本店招牌菜,进店必点"],
[40, 340, 120, 20, 40]]
df = pd.DataFrame(np.array(data_set).T, columns=["菜名", "存货", "描述", "价格"])
df.iloc[2, 1] = np.NaN
return df
def appendSet():
data_set = [["蒜蓉生耗", "蒙古烤羊腿", "白斩鸡", "纸杯蛋糕", "蒜蓉生耗"],
[423, 300, 20, 83, 423]]
return pd.DataFrame(np.array(data_set).T, columns=["菜名", "点赞数"])
2.报表合并
#在进行数据处理前,如果需要结合多张报表内容进行分析,则需要合并报表
set1 = dataSet()
set2 = appendSet()
df = pd.concat([set1, set2], axis=1)
print(df)
菜名 存货 描述 价格 菜名 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 蒜蓉生耗 423
1 蒙古烤羊腿 无 店主强烈推荐 340 蒙古烤羊腿 300
2 白斩鸡 NaN 不辣 120 白斩鸡 20
3 纸杯蛋糕 有 20 纸杯蛋糕 83
4 蒜蓉生耗 有 本店招牌菜,进店必点 40 蒜蓉生耗 423
可以看出对报表是直接进行水平合并的,但这样似乎不是我们想要的结果,因此我们需要进行主键合并。
df = pd.merge(set1, set2, on="菜名")
print(df)
菜名 存货 描述 价格 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
1 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
2 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
3 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
4 蒙古烤羊腿 无 店主强烈推荐 340 300
5 白斩鸡 NaN 不辣 120 20
6 纸杯蛋糕 有 20 83
和我们想要的结果不一样?因为前面说了,函数需要对主键进行合并,但是我们选择的主键是“菜名”。我们知道,主键必须唯一,但在我们函数中我们选择的主键不是唯一的,或者更直接的说,我们这选择的根本不是主键,因此会出现如上结果。上面结果的含义是:set1 中的索引值为0的菜名对应set2中索引值为0的菜名,set1 中的索引值0为的菜名对应set2中索引值为1的菜名,set1 中的索引值为1的菜名对应set2中索引值为0的菜名,set1 中的索引值1为的菜名对应set2中索引值为1的菜名,本质就是一个全连接。
3.数据清洗
上面的数据是不规范的,实际情况下我们会选择主键进行合并,拿这个
例子只是为了演示。
#查看缺失的特征数据
print(df.isnull())
菜名 存货 描述 价格 点赞数
0 False False False False False
1 False False False False False
2 False False False False False
3 False False False False False
4 False False False False False
5 False True False False False
6 False False False False False
#删除"菜名", "描述"相同的行数据
df = df.drop_duplicates(subset=["菜名", "描述"])
#删除重复的列数据
def FeatureEquals(df):
dfEquals = pd.DataFrame([], columns=df.columns, index=df.columns)
dupCol = []
for i in df.columns:
for j in df.columns:
df.loc[i, j] = df.loc[:, i].equals(df.loc[:, j])
for i in range(len(df.columns)):
for j in range(i+1, len(df.columns)):
if df.iloc[i, j] and dfEquals.columns[j] not in dupCol:
dupCol.append(dfEquals.columns[j])
print(“原数据报表“, df)
df.drop(dupCol, axis=1, inplace=True)
print(“删除后的据报表“, df)
print(“删除的列“, dupCol)
FeatureEquals(df)
菜名 存货 描述 价格 菜名 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 蒜蓉生耗 423
1 蒙古烤羊腿 无 店主强烈推荐 340 蒙古烤羊腿 300
2 白斩鸡 NaN 不辣 120 白斩鸡 20
3 纸杯蛋糕 有 20 纸杯蛋糕 83
4 蒜蓉生耗 有 本店招牌菜,进店必点 40 蒜蓉生耗 423
存货 描述 价格 点赞数
0 有 本店招牌菜,进店必点 40 423
1 无 店主强烈推荐 340 300
2 NaN 不辣 120 20
3 有 20 83
4 有 本店招牌菜,进店必点 40 423
['菜名']
#对于缺失值处理
#1.删除缺失值
df.dropna(axis=0, how='any', inplace=True) #inplace: 在原数据集上进行操作
print(df)
菜名 存货 描述 价格 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
4 蒙古烤羊腿 无 店主强烈推荐 340 300
6 纸杯蛋糕 有 20 83
#2.替换缺失值
df.fillna("无", inplace=True)
print(df)
菜名 存货 描述 价格 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
4 蒙古烤羊腿 无 店主强烈推荐 340 300
5 白斩鸡 无 不辣 120 20
6 纸杯蛋糕 有 20 83
#3.插值法(对于数值形数据可以使用该方法。可以使结果变得更加平滑,利于处理,此处不过多介绍,有需要的请自行了解)
#处理字符数据,删除字符为空的数据
df = df[df['描述'].str.len() > 0]
print(df)
菜名 存货 描述 价格 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
4 蒙古烤羊腿 无 店主强烈推荐 340 300
5 白斩鸡 无 不辣 120 20
#处理整型数据,价格小于20的数据
df = df[df["价格"].astype(int) > 20]
菜名 存货 描述 价格 点赞数
0 蒜蓉生耗 有 本店招牌菜,进店必点 40 423
4 蒙古烤羊腿 无 店主强烈推荐 340 300
5 白斩鸡 无 不辣 120 20
异常值处理
在数值分析中,对于一些离群点参与后面的模型应用是十分危险的,这会对结果产生不良影响,导致分析的结果产生偏差或错误。常用的异常值剔除方案是3σ原则。
数值分布
在数据中的占比
(μ-σ,μ+σ)
0.6827
(μ-2σ,μ+2σ)
0.9545
(μ-3σ,μ+3σ)
0.9973
拿点赞数为例
def outRange(Ser1):
means = df['点赞数'].astype('i4').mean()
stds = df['点赞数'].astype('i4').std()
boolInd = np.logical_and(Ser1.astype('i4') < means + 3 * stds, Ser1.astype('i4') > means - 3 * stds)
index = np.arange(Ser1.shape[0])[boolInd]
res = Ser1.iloc[index]
return res
outlier = outRange(df['点赞数'])
print(outlier)
0 423
4 300
5 20
6 83
Name: 点赞数, dtype: object
此处没有去处值,因为样本少了,而且此处大的值对数据的影响比较大。在实际的工作环境中效果更换。举个例子,比如说,现在有10个人,其中9个人的升高都差不多在(160-180cm)左右,但有一个人的身高有3米,
这个人对于这个集体的贡献度太高,以至于不能反应另外9个人的真实情况。但如果现在有100万个人,身高3米的人小伙对于这个集体以及几乎没有贡献了,但总体均值任然反应在(160-180cm)左右,而此人升高必定属于异常数据,因此可以排除。
总结
当我们从数据库或其他地方拿到数据后,会有一些不规范的数据,此时我们需要进行一些预处理,预处理步骤基本可以按照这个套路来。
1.首先从源头加载数据到内存中,转化为DataFrame结构。
2.如果有多张表,可以将这些表进行合并
3.去除重复行和重复列。对缺失数据进行处理, 对字符数据不符合规范的内容进行处理以及对数字型数据中异常数据进行处理。
