pandas数据处理进阶(二)

一、数据去重

import pandas as pd

# 对数据进行去重---真实的数据
# 加载数据
detail = pd.read_excel("./meal_order_detail.xlsx")
print("detail :\n", detail)
# print(detail.shape)
print("*" * 80)

# 对amounts  进行去重,拿到 菜 的单价数据--来评估 这家餐厅的消费水平预估

# subset --指定要去重的数据
#  只有同列 才能进行去重
# res = detail.drop_duplicates(subset='amounts',inplace=False)

# print(res.shape)

# 相关性的衡量.corr()

# 衡量 ---counts  与  amounts 之间的相关性
#  [-1,1]之间
# 0 < corr 正相关
# 0 > corr 负相关
#  method  =  默认是皮尔逊相关系数
#  {'pearson', 'kendall', 'spearman'}
print("counts  与  amounts 之间的相关性:\n", detail.loc[:, ['counts', 'amounts']].corr())
print("counts  与  amounts 之间的相关性:\n", detail.loc[:, ['counts', 'amounts']].corr(method='spearman'))

二、dataframe拼接

import pandas as pd

# 加载数据
# data_1 = pd.read_excel("concat数据拼接.xlsx",sheetname=0)
# data_2 = pd.read_excel("concat数据拼接.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)

# 利用concat 进行拼接 ---没有左右连接 (左右连接 只有主键拼接才有)
# outer 代表外连接- 在行的方向上,直接拼接,列的方向上求列的并集
# print(pd.concat((data_1,data_2),axis=0,join='outer'))
# inner 代表内连接- 在行的方向上,直接拼接,列的方向上求列的交集
# print(pd.concat((data_1,data_2),axis=0,join='inner'))

# outer 代表外连接- 在列的方向上,直接拼接,行的方向上求列的并集
# print(pd.concat((data_1,data_2),axis=1,join='outer'))
# inner 代表外连接- 在列的方向上,直接拼接,行的方向上求列的交集
# print(pd.concat((data_1,data_2),axis=1,join='inner'))


# 主键拼接 ---没有行方向的拼接
# 加载数据
# data_1 = pd.read_excel("./merge拼接数据.xlsx",sheetname=0)
# data_2 = pd.read_excel("./merge拼接数据.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)


#  how  = {'left', 'right', 'outer', 'inner'}
# on  就是 值一样的列
# outer -  外连接  key值的列 求并集,没有值的key  用NAN填充
# print(pd.merge(left=data_1,right=data_2,how='outer',on='key'))
# inner -  内连接  key值的列 求交集,没有的数据的key  删除
# print(pd.merge(left=data_1,right=data_2,how='inner',on='key'))
#  left  ---left outer 左外连接 ---外连接,以左表为主
# key 列只关系 左表,右表不关心
# print(pd.merge(left=data_1,right=data_2,how='left',on='key'))
# right  right outer 右外连接
# key 列只关系 右表,左表不关心
# print(pd.merge(left=data_1,right=data_2,how='right',on='key'))


# 特殊情况
# 左表的列的名称 与右表的列的名称 没有一样的,但是里面的数据是一样
data_1 = pd.read_excel("./merge拼接数据1.xlsx",sheetname=0)
data_2 = pd.read_excel("./merge拼接数据1.xlsx",sheetname=1)
#
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)


print(pd.merge(left=data_1,right=data_2,how='outer',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='inner',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='left',left_on='key_l',right_on='key_r'))
print(pd.merge(left=data_1,right=data_2,how='right',left_on='key_l',right_on='key_r'))

# join

三、数据填充

import pandas as pd

# # 加载数据
#
data_1 = pd.read_excel("./数据填充.xlsx",sheetname=0)
data_2 = pd.read_excel("./数据填充.xlsx",sheetname=1)
# print("data_1:\n",data_1)
# print("data_2:\n",data_2)
# print("*"*80)
# # 使用表二来填充表一
res = data_1.combine_first(data_2)
print(res)

四、缺失值处理(删除法,填充法,插值法)

import pandas as pd
import numpy as np

# 加载数据
# data = pd.read_excel('./qs.xlsx')
# print("data:\n",data)
# print("data 的数据类型:\n",data.dtypes)
#
# print("*"*80)

# 如何确定数据里面含有缺失值---缺失值检测
# isnull   缺失值 返回T
# notnll  缺失值返回F
# 推荐使用  isnull + sum 来判断缺失值
# print(data.isnull().sum())
# print("*"*80)
# print(data.notnull().sum())

# 1、删除法--dropna
# 遇到缺失值就删除---按行、按列删除
# axis 指定删除的轴
# how  指定删除的方式 ---any只要有缺失值,就删除
# how  指定删除的方式 ---all只有整列或者整行都是缺失值,才删除
# inplace 指定是否对原来产生影响
# data.dropna(axis=0,how='any',inplace=True)
# data.dropna(axis=1,how='any',inplace=True)
# data.dropna(axis=0,how='all',inplace=True)
# print(data)

#  对于删除法,容易改变数据结构,容易造成大量数据丢失。
# 只有 行 或者列 大部分为缺失值,我们才进行删除
# 或者  行、列的数据对结果不重要 才进行删除
# 2、填充法
# 对于数值型数据---可以均值、中位数、众数来填充
# 对于类别型数据---可以使用众数来填充
# mode = data.loc[:,'商品ID'].mode()[0]
# print(mode)
# data.loc[:,'商品ID'].fillna(value=mode,inplace=True)
# data.loc[:,'类别ID'].fillna(value=data.loc[:,'类别ID'].mode()[0],inplace=True)
# data.loc[:,'门店编号'].fillna(value=data.loc[:,'门店编号'].mode()[0],inplace=True)
# print("*"*80)
# print(data)

# 只要我们填充之后 对结果影响不是很大的情况下,就可以使用。
#  *
#  如果 是一些不能直接处理的缺失值,先转化为能处理的缺失值
# 这里的缺失值 ---np.nan类型 ----float类型
# print(type(np.nan))
# data.replace(to_replace="*",value=np.nan,inplace=True)
# print(data)
# 删除、填充都能进行
# 3、插值法
# 给合适的位置 插上合适的值
x = np.array([1, 2, 3, 4, 5, 8, 9])  #
y = np.array([3, 5, 7, 9, 11, 17, 19])  # y = 2* x + 1
z = np.array([2, 8, 18, 32, 50, 128, 162])  # z = 2 * x^2
#  线性插值、 多项式插值、样条插值
# 线性插值 ---拟合线性关系进行插值
# from  scipy.interpolate  import  interp1d
# line1 = interp1d(x,y,kind='linear')
# line2 = interp1d(x,z,kind='linear')
# print(line1([6,7])) #  [ 13.  15.]
# print(line2([6,7])) # [  76.  102.]
# 多项式插值---牛顿插值法、拉格朗日插值法
# 拟合牛顿多项式 与 拉格朗日多项式
# from  scipy.interpolate import  lagrange
# la1 =  lagrange(x,y)
# la2 =  lagrange(x,z)
#
# print(la1([6,7])) # [ 13.  15.]
# print(la2([6,7])) # [ 72.  98.]
# 样条插值--- 拟合曲线关系进行插值
from scipy.interpolate import spline

print(spline(xk=x, yk=y, xnew=np.array([6, 7])))  # [ 13.  15.]
print(spline(xk=x, yk=z, xnew=np.array([6, 7])))  # [ 72.  98.]

#  对于线性关系的数据 ---线性插值比较准确,多项式插值与 样条插值都不错,
# 如果是线性关系的数据----都可以使用

# 对于非线性数据---线性插值效果较差,多项式插值与样条插值效果较好
# 如果是非线性关系的数据,---推荐使用多项式插值与样条插值

五、异常值处理

import pandas as pd
import numpy as np


#  根据正太分布得出 99.73%的数据都在[u-3sigma ,u+3sigma ]之间,那么我们人为超出这个区间的数据为异常值

# 剔除异常值----保留数据在[u-3sigma ,u+3sigma ]之间
#
def three_sigma(data):
    """
    进行3 sigma异常值剔除
    :param data: 传入的数据
    :return: 剔除之后的数据 或者剔除异常值之后的行索引名称
    """
    bool_id_1 = (data.mean() - 3 * data.std()) <= data
    bool_id_2 = (data.mean() + 3 * data.std()) >= data

    bool_num = bool_id_1 & bool_id_2

    return bool_num


#
# # 以 detail 为例 展示以amounts 进行异常值剔除,查看detail结果
# 加载数据
detail = pd.read_excel("./meal_order_detail.xlsx", sheetname=0)

print("detail:\n", detail)
print("detail 的列名:\n", detail.columns)

print("*" * 80)
#
# # 调用函数进行detail 中 amounts 的异常值剔除
#
bool_num = three_sigma(detail.loc[:, 'amounts'])
#
# # 获取正常的detail
detail = detail.loc[bool_num, :]


#
#
# print(detail.shape)

# 箱线图分析
# arr = pd.Series(np.array([1,2,3,4,5,6,7,8,9,10]))
# print(arr.quantile(0.5))
#  75 % 的数  qu
#  25% 的数  ql

# iqr = qu - ql

# 上限:qu + 1.5*iqr
# 下限 :ql - 1.5*iqr

def box_analysis(data):
    """
    进行箱线图分析,剔除异常值
    :param data: series
    :return: bool数组
    """
    qu = data.quantile(0.75)
    # print(qu)
    ql = data.quantile(0.25)
    # print(ql)

    iqr = qu - ql

    # 上限
    up = qu + 1.5 * iqr
    #  下限
    low = ql - 1.5 * iqr

    # 进行比较运算
    bool_id_1 = data <= up
    bool_id_2 = data >= low

    bool_num = bool_id_1 & bool_id_2

    return bool_num


bool_num = box_analysis(detail.loc[:, 'amounts'])

detail = detail.loc[bool_num, :]

print(detail.shape)

猜你喜欢

转载自blog.csdn.net/qq_40576301/article/details/102461947