
本人依据上课学习内容,将dataframe内容浓缩为代码块,一下是今天学习的第二部分:
1.dataframe聚合函数与分组
2.dataframe透视表
数据预处理技术:
3.数据集成(合并)
4.数据清洗
5.数据归约(标准化)
6.数据转换
本文于2021/12/13首发于csdn,如有错误和不足请指出。
import pandas as pd import numpy as np import matplotlib.pyplot as plt rs = pd.read_csv(r"C:Users吴龙道Desktop数据可视化tmprs.csv", encoding='gbk') print(rs) '''1.聚合函数与分组''' # (1)聚合:将多种数据按照某种方式聚合为一个标量 # 如果函数来自第三方或自定义,直接给出函数名,不要写出参数的括号 # 有些数据没有max,min,要注意 agg1 = rs["薪水"].agg(['min', 'max']) # 薪水和小时报酬的min, median agg2 = rs[['薪水', '小时报酬']].agg(['min', np.median]) # 看薪水的max,min,小时报酬的maen, median agg3 = rs.agg({'薪水': ["max", "min"], '小时报酬': ["mean", "median"]}) agg4 = rs.agg({'薪水': np.min, '小时报酬': ['mean', 'median']}) # (2)分组 groupby1 = rs.groupby(['分公司']).mean() # 返回dataframe对象,只显示了可以统计的部分 # groupby1 = rs.groupby("分公司").mean() # 返回dataframe对象,也对 # 对分组后的列 *** 作 groupby2 = rs.groupby(['分公司'])[['薪水']].mean() # dataframe对象 # groupby2 = rs.groupby(["分公司"])['薪水'].mean() # sereis对象 # (3)分组与聚合 # 按分公司分组后,小时报酬与薪水的min,max groupby3 = rs.groupby('分公司')[['薪水', '小时报酬']].agg(["min", 'max']) '''2.透视表''' # index/column设置索引相当于分组,aggfunc设置聚合函数,默认为mean # pt1 = pd.pivot_table(rs, values='小时报酬', index=['分公司'], aggfunc='min') pt1 = rs.pivot_table(values='小时报酬', index=['分公司'], aggfunc='min') # 多索引分组 pt2 = rs.pivot_table(values=['小时报酬', '薪水'], index=['分公司', '部门']) '''数据预处理(清洗,集成,归约,转换)''' '''3.数据合并(集成)''' # (1)堆叠concat rs1 = rs.iloc[:5, :3] rs2 = rs.iloc[4:, 3:] # axis=1,横向(列向)堆叠,axis=0,纵向(行向)堆叠 # 内连接(去除悬浮元组)与外连接(保留悬浮元组) innerjoin = pd.concat([rs1, rs2], axis=1, join='inner') outerjoin = pd.concat([rs1, rs2], axis=1, join='outer') # 当两张表完全一致时,直接完全按轴拼接 join = pd.concat([rs1, rs1], axis=1, join='outer') # (2)主键合并merge/也是连接,但不会出现堆叠(所有列重复出现),会按照主键合并(主键不会重复) xx1 = pd.read_csv(r'C:Users吴龙道Desktop数据可视化tmpxsxx.csv', encoding='gbk') # 读取信息表 xx2 = pd.read_csv(r'C:Users吴龙道Desktop数据可视化tmpxscj.csv', encoding='gbk') # “学号”转换为字符串格式,保证左右连接表格的数据格式一致,为合并做准备(也可以不转换) # xx1['学号'] = xx1['学号'].astype('str') # xx2['学号'] = xx2['学号'].astype('str') # 分别写出左右表的主键(连接的必要) xx_detail = pd.merge(xx1.iloc[:, :2], xx2.iloc[:, :2], left_on='学号', right_on='学号') # xx_detail = pd.merge(xx1.iloc[:, :2], xx1.iloc[:, :2], left_on='学号', right_on='学号') # print("学生信息表与成绩表连接:n", xx_detail) # (3)合并重复数据combine_first(两相同表对比可以互相解决缺失值) combine = rs.combine_first(rs) '''4.数据清洗''' # (1)重复值处理 # ①记录重复duplicated # 只有指定数据中行/列全部一致才会认为重复,缺失值不一样都不行 # 指定列中是否有重复值,subset关键字可以不写出 dup1 = xx_detail.duplicated(subset=['姓名']) # 查找重复值位置 dup2 = xx_detail['姓名'].drop_duplicates() # 去除重复值 # ②特征重复(相关性过高/异名同义) # import scipy # # corr1 = rs[['工作时间', '薪水']].corr(method='kendall') # corr2 = rs.corr(method='kendall') # print(corr1) # 特征重复例子(不用corr,手动查重) detail = pd.read_csv(r'C:Users吴龙道Desktop数据可视化tmpmeal_order_detail.csv', index_col=0, encoding='utf-8') def FeatureEquals(df): # 建立以传入Dataframe的列标签为行、列标签的框架(特征矩阵) dfEquals = pd.Dataframe([], columns=df.columns, index=df.columns) for i in df.columns: for j in df.columns: # 以原数据集列之间的关系判断是否为重复特征 dfEquals.loc[i, j] = df.loc[:, i].equals(df.loc[:, j]) return dfEquals detEquals = FeatureEquals(detail) # print('detail的特征相等矩阵的前5行5列为:n', detEquals.iloc[:5, :5]) lenDet = detEquals.shape[0] # 特征列表长度 dupCol = [] # 去重列表 for k in range(lenDet): for l in range(k+1, lenDet): # 对角矩阵,看右上角是不是True就行了 if detEquals.iloc[k, l] & (detEquals.columns[l] not in dupCol): dupCol.append(detEquals.columns[l]) # 进行去重 *** 作 # print('需要删除的列为:', dupCol) # 沿列方向删除 detail.drop(dupCol, axis=1, inplace=True) # shape = (a,b) shape[1]列数=b(第二维度),[0]行数=a(第一维度) # print('删除多余列后detail的特征数目为:', detail.shape[1]) # (2)缺失值处理 # 查缺失值 null1 = rs.isnull() null2 = rs.notnull() # ①删除缺失值dropna删记录或特征 # 沿行方向(纵轴)删除,默认值1列向(横轴)删除 # any有缺失值就删(默认),all全为缺失值才删,subset指定行列 null3 = rs.dropna(axis=0, how='all') # ②替换缺失值 # 可指定替换方式,如指定值/ffill用上个非缺失值补,bfill用下个非缺失值补 null4 = rs['小时报酬'].fillna(rs['小时报酬'].mean()) # ③插值法 # 利用函数确定值,使用scipy库 # 线性插值例子 # from scipy.interpolate import interp1d # x=np.array([1,2,3,4,5,8,9,10]) ##创建自变量x # y1=np.array([2,8,18,32,50,128,162,200]) ##创建因变量y1 # y2=np.array([3,5,7,9,11,17,19,21]) ##创建因变量y2 # LinearInsValue1 = interp1d(x,y1,kind='linear') ##线性插值拟合x,y1,生成函数 # LinearInsValue2 = interp1d(x,y2,kind='linear') ##线性插值拟合x,y2 # print('当x为6、7时,使用线性插值y1为:',LinearInsValue1([6,7])) # 给x找对应y # print('当x为6、7时,使用线性插值y2为:',LinearInsValue2([6,7])) # 拉格朗日插值例子 # from scipy.interpolate import lagrange # LargeInsValue1 = lagrange(x,y1) ##拉格朗日插值拟合x,y1 # LargeInsValue2 = lagrange(x,y2) ##拉格朗日插值拟合x,y2 # print('当x为6,7时,使用拉格朗日插值y1为:',LargeInsValue1([6,7])) # print('当x为6,7时,使用拉格朗日插值y2为:',LargeInsValue2([6,7])) # 样条插值例子 # from scipy.interpolate import make_interp_spline # SplineInsValue1 = make_interp_spline(x,y1)##样条插值拟合x,y # SplineInsValue2 = make_interp_spline(x,y2) # print('当x为6,7时,使用样条插值y1为:',SplineInsValue1([6,7])) # print('当x为6,7时,使用样条插值y2为:',SplineInsValue2([6,7])) # (3)异常值处理 # ①3theta(标准差)/拉依达法则 # 定义拉依达准则识别异常值函数 def outRange(Ser1): # 如果在3*std区域之外的就是误差的,得到一系列True值的列表 boolInd = (Ser1 < Ser1.mean() - 3*Ser1.std()) | (Ser1 > Ser1.mean() + 3*Ser1.std()) index = np.arange(Ser1.shape[0])[boolInd] # 按照行长度建立数组,但是只保留下为True的值,即异常值的index outrange = Ser1.iloc[index] # 生成异常值dataframe return outrange outlier = outRange(detail['counts']) print('使用拉依达准则判定异常值个数为:', outlier.shape[0]) print('异常值的最大值为:', outlier.max()) print('异常值的最小值为:', outlier.min()) # ②箱线图 p = plt.boxplot(detail['counts'], notch=True) # 箱线图 outlier1 = p['fliers'][0].get_ydata() # fliers为异常值的标签 # plt.savefig('../tmp/菜品异常数据识别.png') print('销售量数据异常值个数为:', len(outlier1)) print('销售量数据异常值的最大值为:', max(outlier1)) print('销售量数据异常值的最小值为:', min(outlier1)) '''5.数据标准化(归约)''' # (1)离差标准化 # 自定义离差标准化函数 def MinMaxScale(data): data = (data - data.min()) / (data.max() - data.min()) return data # data1 = MinMaxScale(detail['counts']) # data2 = MinMaxScale(detail['amounts']) # data3 = pd.concat([data1, data2], axis=1) # print('离差标准化之前销量和售价数据为:n', # detail[['counts', 'amounts']].head(5)) # print('离差标准化之后销量和售价数据为:n', data3.head(5)) # (2)z分数标准化 # 自定义标准差标准化函数 def StandardScaler(data): data = (data - data.mean()) / data.std() return data # 对菜品订单表售价和销量做标准化 # data4 = StandardScaler(detail['counts']) # data5 = StandardScaler(detail['amounts']) # data6 = pd.concat([data4, data5], axis=1) # print('z分数标准化之前销量和售价数据为:n', # detail[['counts', 'amounts']].head(5)) # print('z分数标准化之后销量和售价数据为:n', data6.head(5)) # (3)小数定标标准化 '''6.数据转换''' # (1)哑变量(非数值型变量,无法直接用于数据分析) # pd.get_dummies,输入的数据可以是array,series,dataframe(一维或多维) data2 = rs.loc[:, '部门'] print('哑变量处理前的数据为:n', data2) print('哑变量处理后的数据为:n', pd.get_dummies(data2)) # (2)离散化(有的算法输入参数不希望是连续值) # pd.cut,输入的数据只能是array或series(一维) # bin设置离散化后的分类数 print(pd.cut(rs['小时报酬'], bins=4))
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)