Python数据分析与应⽤⼤作业
Python数据分析与应⽤⼤作业
使⽤学习过的知识(Numpy数值分析基础、Matplotlib数据可视化基础、Pandas统计分析基础),对data.csv⽤户⽤户⽤电量数据进⾏相关处理,其中数据中有编号为1-200的200位电⼒⽤户,DATA_DATE表⽰时间,如2015/1/1表⽰2015年1⽉1⽇,KWH为⽤电量。请完成以下⼯作:
⼀、将数据进⾏转置,转置后⾏为⽤户编号、列为⽇期、值为⽤户每⽇⽤电量。
⼆、对数据中的异常数据进⾏识别并处理。
三、统计每个⽤户⽤电数据的基本统计量,包括:最⼤值、最⼩值、均值、中位数、和、⽅差、偏度、峰度。
四、每个⽤户⽤电数据按⽇差分,并求取差分结果的基本统计量,统计量同三。
五、求取每个⽤户的5%分位数。
六、每个⽤户按周求和并差分(⼀周7天,年度分开),并求取差分结果的基本统计量,统计量同三。
七、统计每个⽤户的⽇⽤电量在其最⼤值0.9倍以上的次数。
⼋、求取每个⽤户⽇为最⼤值/最⼩值的索引⽉份,若最⼤值/最⼩值存在于多个⽉份中,则输出含有最⼤值/最⼩值最多的那个⽉份。手机wps怎么输入数组公式
如1号⽤户的最⼩值为0,则看哪个⽉的0最多。
九、求取每个⽤户七⼋⽉电量和与三四⽉电量和的⽐值,最⼤值的⽐值,最⼩值的⽐值,均值(⽇均电量)的⽐值。
⼗、合并上述特征。
⼀、将数据进⾏转置,转置后⾏为⽤户编号、列为⽇期、值为⽤户每⽇⽤电量
import pandas as pd
data = pd.read_csv('./data/data.csv', encoding='gbk')
# 转置data
# result = set_index().pivot('CONS_NO', 'DATA_DATE', 'KWH')
data['DATA_DATE']= pd.to_datetime(data['DATA_DATE'])
result = pd.pivot_table(data, index='CONS_NO', columns='DATA_DATE')
print(result)
linux安装mysql依赖检测失败导⼊pandas,导⼊data.csv⽂件同时编码设置为GBK,把DATA_DATE转换为时间序列,使⽤透视表将index设置
为’CONS_NO’,columns设置为’DATA_DATE’。python基础代码作业
注意:若此处不把DATA_DATE转换成时间序列,那么columns的排列顺序将不是按照时间顺序,⽽是按照数字顺序。例:未转换时,顺序为2015/1/1, 2015/1/10, 2015/1/11 , …;转换后,顺序为2015/1/1, 2015/1/2 , 2015/1/3 , …。
⼆、对数据中的异常数据进⾏识别并处理
# 异常值识别处理
null_value = data.isnull().sum()# 缺失值识别
print("data具有的缺失值:\n",null_value)
data.fillna(method='pad', inplace=True)# 缺失值处理⽅法:⽤前⼀个数据进⾏填充
web培训学校null_value = data.isnull().sum()
print("data处理缺失值之后:\n",null_value)
u = data['KWH'].mean()
o = data['KWH'].std()
three_uo = data['KWH'].apply(lambda x: x>u+3*o or x<u-3*o)
result1 = data.loc[three_uo,'KWH']# 使⽤3σ⽅法识别异常值
print("data在3σ下具有的异常值:\n",result1)
使⽤导⼊的data数据进⾏缺失值识别,识别⽅法为isnull结合sum⽅法确定缺失值的个数,再使⽤fillna⽅法填充缺失值;异常值识别⽅法为3σ⽅法识别异常值。偷懒了没有对异常值进⾏处理
说明:
pandas提供了识别缺失值的⽅法isnull以及识别⾮缺失值的⽅法nonull,这两种⽅法在使⽤时返回的都是bool值True和False,结合sum函数,可以检测数据中缺失值的分布以及数据中⼀共含有多少缺失值。isnull和nonull之间的结果正好相反。
处理缺失值有三种⽅法:
删除法 —— 删除法可以分为删除观测记录和删除特征两种,它属于利⽤减少样本量来换取信息完整度的⼀种⽅法,是⼀种最简单的缺失值处理⽅法。pandas中提供了简便的删除缺失值的⽅法 dropna ,该⽅法既可以删除观测记录,亦可以删除特征。
替换法 —— 特征可分为和。当缺失值所在特征为时,通常利⽤其均值、中位数和众数等描述其集中趋势的统计量来代替缺失值;当缺失值所在特征为时,则使⽤众数来替换缺失值。***PS:*这⾥使⽤了pandas提供的 fillna ⽅法进⾏缺失值替换,原理是当 method 为pad 时使⽤上⼀个⾮缺失值填补缺失值,当 method 为 bfill 时使⽤下⼀个⾮缺失值填补缺失值。
数值型
类别型
数值型
类别型
插值法 —— 删除法简单,但是会引起数据结构的变动,样本减少;替换法使⽤难度低,但是会影响数据的标准差,导致信息量变动。
所以除了上⾯两种⽅法,还有⼀种⽅法为插值法。常⽤的插值法有、和。是⼀种较为简单的插值⽅法,他针对已知的值求出线性⽅程,通过求解线性⽅程得到缺失值;是利⽤已知的值拟合⼀个多项式,使得现有的数据满⾜这个多项式,再利⽤这个多项式求解缺失值,常见的多项式插值法有拉格朗⽇插值和⽜顿插值等;是以可变的样条来作出⼀条经过⼀系列点的光滑曲线的插值⽅法,插值样条由⼀些多项式组成,每⼀个多项式都是由相邻两个数据点决定,这样可以保证两个相邻多项式及其导数在连接处连续。
线性插值
多项式插值
样条插值
线性插值
多项式插值
样条插值
异常值是指数据中个别值的数值明显偏离其余的数值,有时也成为离点,检测异常值就是检验数据中是否有录⼊错误以及是否含有不合理的数据。异常值的检测常⽤的有两种⽅法,3σ原则和箱线图分析。
三、统计每个⽤户⽤电数据的基本统计量,包括:最⼤值、最⼩值、均值、中位数、和、⽅差、偏度、峰度
# 求每个⽤户的统计量
def statistics(df):# 数据统计并合并统计量
surface = pd.concat([df.min(), df.max(), df.mean(), df.median(), df.sum(), df.var(), df.skew(), df.kurt()],
axis=1)
return surface
print("每个⽤户⽤电数据的基本统计量:\n",statistics(result.T))
这⾥使⽤了⾃定义函数,是为了之后的题做准备。
数据使⽤了转置之后的数据result,再进⾏转置,调⽤statistics⽅法进⾏数据统计并合并统计量。
statistics中使⽤了at⽅法,这个⽅法可以⽤来对表进⾏纵向堆叠,在默认情况下,即axis=0时,concat做列对齐,将不同⾏索引的两张或多张表纵向合并。
四、每个⽤户⽤电数据按⽇差分,并求取差分结果的基本统计量,统计量同三
# 每个⽤户⽤电数据按⽇差分
different = result.T.diff(1)# 对转置后的dataframe进⾏按⽇差分
print("每个⽤户⽤电数据按⽇差分:\n",different)
print("每个⽤户⽤电数据按⽇差分的基本统计量:\n",statistics(different))
这⾥使⽤result转置,并调⽤diff⽅法进⾏数据的按⽇差分。
调⽤statistics,对按⽇差分的数据进⾏统计,并输出所有的基本统计量。
五、求取每个⽤户的5%分位数
print("每个⽤户的5分位数为:\n",result.T.describe(percentiles=[0.05]))
使⽤describe⽅法统计每个⽤户的5%分位数。
六、每个⽤户按周求和并差分(⼀周7天,年度分开),并求取差分结果的基本统计量,统计量同三
# 每个⽤户按周求和并差分
data['DATA_DATE']= pd.to_datetime(data['DATA_DATE'])
key = pd.PeriodIndex(data['DATA_DATE'], freq='w')
sum_week = upby(by=['CONS_NO', key]).sum()
a = pd.pivot_table(sum_week, index='DATA_DATE', columns='CONS_NO')
different = a.diff(1)
print("每个⽤户按周求和并差分:\n",different)
print("每个⽤户按周求和并差分的基本统计量:\n",statistics(different))
对DATA_DATE进⾏时间序列转换。(由于第⼀题已经转换过了,这⾥可以不⽤再转换了)
frep='w’使DATA_DATE按周的频率排列,同时获取其索引。PS:这⾥好像没有把年度分开
按照CONS_NO及key进⾏分组,并求和。(完成按周求和操作)
创建透视表,并差分,最后使⽤statistics统计基本统计量。
七、统计每个⽤户的⽇⽤电量在其最⼤值0.9倍以上的次数
a = result.T.apply(lambda x:x>x.max()*0.9).sum()
print("每个⽤户⽇⽤电量在其最⼤值0.9倍以上的次数:\n",a)
使⽤apply⽅法
⼋、求取每个⽤户⽇为最⼤值/最⼩值的索引⽉份,若最⼤值/最⼩值存在于多个⽉份中,则输出含有最⼤值/最⼩值最多的那个⽉份。如1号⽤户的最⼩值为0,则看哪个⽉的0最多
# 输出含有最⼤值/最⼩值最多的那个⽉份
print("输出含有最⼤值/最⼩值最多的那个⽉份:")
key = pd.PeriodIndex(data['DATA_DATE'], freq='m')
month = upby(by=['CONS_NO', key])['KWH'].max()# 按⽉进⾏分组
month_df = pd.DataFrame(month)
max_index = set_index().groupby('CONS_NO')['KWH'].idxmax()
max_value = month_df.iloc[max_index]
lumns =['各⽤户的KWH最⼤值']
print(max_value)# 输出含有最⼤值最多的那个⽉份
min_index = data[(data.KWH == data.KWH.min())].index
surface_min = data.iloc[min_index]
key = pd.PeriodIndex(surface_min['DATA_DATE'], freq='m')
min_count = upby(by=['CONS_NO', key])['KWH'].count()# 按⽉进⾏分组
min_count_df = pd.DataFrame(min_count)
min_count_df_index = min_set_index().groupby('CONS_NO')['KWH'].idxmax()
min_value = min_count_df.iloc[min_count_df_index]
lumns =['KWH最⼩值次数']
print(min_value)# 输出含有最⼩值最多的那个⽉份
于第六题相似,使⽤了PeriodIndex⽅法使得DATA_DATE以⽉为单位进⾏分组。
之后,由于groupby得到的是serise类,所以将month转换为dataframe类并结合reset_index与idxmax⽅法获取含有最⼤值最多的那个⽉份的索引。
将获得的索引使⽤iloc进⾏切⽚,得到所需结果。
输出含有最⼩值最多的那个⽉份的⽅法与输出含有最⼤值最多的那个⽉份的⽅法相似,但是需要对最⼩值进⾏⽐较,并求出每⽉最⼩值的个数。
九、求取每个⽤户七⼋⽉电量和与三四⽉电量和的⽐值,最⼤值的⽐值,最⼩值的⽐值,均值(⽇均电量)的⽐值
PS:这道题重复代码有点多,所以肯定不是最优答案,所以仅供参考。(求的是)
def date_filter(df):# ⽇期筛选,选出三四⽉份,七⼋⽉份,返回两张表
idx = pd.IndexSlice
s_e = df.loc[idx[:,['2015-7','2015-8','2016-7','2016-8']],:]
t_f = df.loc[idx[:,['2015-3','2015-4','2016-3','2016-4']],:]
return s_e, t_f
def date_merge(df_1, df_2, name):# 合并符合要求的⽇期,同时进⾏⽐值处理,返回题解
df_ratio = pd.merge(df_1, df_2, on='CONS_NO')
lumns =['7-8⽉','3-4⽉']
df_ratio[name]= df_ratio['7-8⽉']/ df_ratio['3-4⽉']
return df_ratio
key = pd.PeriodIndex(data['DATA_DATE'], freq='m')
month = upby(by=['CONS_NO', key])# 按⽉进⾏分组
month_sum = month.sum()# 求和的⽐值
s_e_1, t_f_1= date_filter(month_sum)
s_e_sum = s_upby('CONS_NO').sum()
t_f_sum = t_upby('CONS_NO').sum()
se_tf_sum_ratio = date_merge(s_e_sum, t_f_sum,'sum_ratio')
print("每个⽤户七⼋⽉电量和与三四⽉电量和的⽐值:\n",se_tf_sum_ratio)
month_max = month.max()# 求最⼤值的⽐值
s_e_2, t_f_2 = date_filter(month_max)
s_e_max = s_upby('CONS_NO').max().loc[:,'KWH']
t_f_max = t_upby('CONS_NO').max().loc[:,'KWH']
se_tf_max_ratio = date_merge(s_e_max, t_f_max,'max_ratio')
print("每个⽤户七⼋⽉电量最⼤值与三四⽉电量最⼤值的⽐值:\n",se_tf_max_ratio)
month_min = month.min()# 求最⼩值的⽐值
s_e_3, t_f_3 = date_filter(month_min)
s_e_min = s_upby('CONS_NO').min().loc[:,'KWH']
t_f_min = t_upby('CONS_NO').min().loc[:,'KWH']
se_tf_min_ratio = date_merge(s_e_min, t_f_min,'min_ratio')
print("每个⽤户七⼋⽉电量最⼩值与三四⽉电量最⼩值的⽐值:\n",se_tf_min_ratio)
month_mean_sum= month.sum()# 求平均值的⽐值
s_e_4, t_f_4 = date_filter(month_mean_sum)
s_e_mean = s_upby('CONS_NO').apply(lambda x:x.sum()/122)# 先计算每个⽤户七⼋⽉份总的⽤电量,然后除以总天数,得到平均值
t_f_mean = t_upby('CONS_NO').apply(lambda x:x.sum()/122)# 同上
se_tf_mean_ratio = date_merge(s_e_mean, t_f_mean,'mean_ratio')
print("每个⽤户七⼋⽉电量平均值与三四⽉电量平均值的⽐值:\n",se_tf_mean_ratio)
第⼀个⾃定义函数date_filter的作⽤是进⾏⽇期的筛选,选出每年七⼋⽉份与每年三四⽉份;⼀个参数接收⼀个表,返回两个表。
第⼆个⾃定义函数date_merge的作业是合并符合要求的⽇期同时进⾏⽐值的处理;三个参数接收两个表⼀个字符串,返回⼀个表。
以求和的⽐值为例:
先将DATA_DATE按照⽉分组,并求和。
调⽤date_filter⽅法分离七⼋⽉份与三四⽉份,并分别求和。
调⽤date_merge⽅法将两张已经求和的七⼋⽉份和三四⽉份的表合并,并将求⽐值的列取名叫sum_ratio。
注意:求平均值的⽐值时,求平均值的⽅法是⽤求和并除以122(总天数)得到平均值。
⼗、合并上述特征
# 合并特征
all_trait = pd.concat([se_tf_sum_ratio.loc[:,'sum_ratio'],
se_tf_max_ratio.loc[:,'max_ratio'],
se_tf_min_ratio.loc[:,'min_ratio'],
se_tf_mean_ratio.loc[:,'mean_ratio']],
axis=1)
print("合并特征:\n",all_trait)
⽅法与第三题相似
PS:题⽬给的参考答案是把第⼀⾄第九题的结果合并,但我理解成了将第九题的特征合并。⼗⼀、代码及运⾏结果
PS:这是我的python数据分析与应⽤的⼤作业(⾮参考答案,参考需谨慎)
PS:这是我的python数据分析与应⽤的⼤作业(⾮参考答案,参考需谨慎)
import pandas as pd
data = pd.read_csv('./data/data.csv', encoding='gbk')
# 转置data
# result = set_index().pivot('CONS_NO', 'DATA_DATE', 'KWH')
data['DATA_DATE']= pd.to_datetime(data['DATA_DATE'])
result = pd.pivot_table(data, index='CONS_NO', columns='DATA_DATE')
print(result)
# 异常值识别处理
null_value = data.isnull().sum()# 缺失值识别
print("data具有的缺失值:\n",null_value)
data.fillna(method='pad', inplace=True)# 缺失值处理⽅法:⽤前⼀个数据进⾏填充
null_value = data.isnull().sum()
print("data处理缺失值之后:\n",null_value)
u = data['KWH'].mean()
o = data['KWH'].std()
three_uo = data['KWH'].apply(lambda x: x>u+3*o or x<u-3*o)
result1 = data.loc[three_uo,'KWH']# 使⽤3σ⽅法识别异常值
print("data在3σ下具有的异常值:\n",result1)
# 求每个⽤户的统计量
def statistics(df):# 数据统计并合并统计量
surface = pd.concat([df.min(), df.max(), df.mean(), df.median(), df.sum(), df.var(), df.skew(), df.kurt()], axis=1)
return surface
print("每个⽤户⽤电数据的基本统计量:\n",statistics(result.T))
# 每个⽤户⽤电数据按⽇差分
different = result.T.diff(1)# 对转置后的dataframe进⾏按⽇差分
print("每个⽤户⽤电数据按⽇差分:\n",different)
print("每个⽤户⽤电数据按⽇差分的基本统计量:\n",statistics(different))
# 每个⽤户的5%分位数
print("每个⽤户的5分位数为:\n",result.T.describe(percentiles=[0.05]))
# 每个⽤户按周求和并差分
data['DATA_DATE']= pd.to_datetime(data['DATA_DATE'])
key = pd.PeriodIndex(data['DATA_DATE'], freq='w')
sum_week = upby(by=['CONS_NO', key]).sum()
powermill软件下载a = pd.pivot_table(sum_week, index='DATA_DATE', columns='CONS_NO')
different = a.diff(1)
print("每个⽤户按周求和并差分:\n",different)
print("每个⽤户按周求和并差分的基本统计量:\n",statistics(different))
# 每个⽤户的⽇⽤电量在其最⼤值0.9倍以上的数据
a = result.T.apply(lambda x:x>x.max()*0.9).sum()
print("每个⽤户⽇⽤电量在其最⼤值0.9倍以上的次数:\n",a)
# 第⼋题,输出含有最⼤值/最⼩值最多的那个⽉份
print("输出含有最⼤值/最⼩值最多的那个⽉份:")
stacktrace什么意思key = pd.PeriodIndex(data['DATA_DATE'], freq='m')
month = upby(by=['CONS_NO', key])['KWH'].max()# 按⽉进⾏分组
month_df = pd.DataFrame(month)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论