大家好,小编为大家解答python大作业代码及文档的问题。很多人还不知道python大作业有哪些题目,现在让我们一起来看看吧!
使用学习过的知识(Numpy数值分析基础、Matplotlib数据可视化基础、Pandas统计分析基础),对data.csv用户用户用电量数据进行相关处理,其中数据中有编号为1-200的200位电力用户,DATA_DATE表示时间,如2015/1/1表示2015年1月1日,KWH为用电量。请完成以下工作:
一、将数据进行转置,转置后行为用户编号、列为日期、值为用户每日用电量ai伪原创api,如何用php调用。
二、对数据中的异常数据进行识别并处理。
三、统计每个用户用电数据的基本统计量,包括:最大值、最小值、均值、中位数、和、方差、偏度、峰度。
四、每个用户用电数据按日差分,并求取差分结果的基本统计量,统计量同三。
五、求取每个用户的5%分位数。
六、每个用户按周求和并差分(一周7天,年度分开),并求取差分结果的基本统计量,统计量同三。
七、统计每个用户的日用电量在其最大值0.9倍以上的次数。
八、求取每个用户日为最大值/最小值的索引月份,若最大值/最小值存在于多个月份中,则输出含有最大值/最小值最多的那个月份。如1号用户的最小值为0,则看哪个月的0最多。
九、求取每个用户七八月电量和与三四月电量和的比值,最大值的比值,最小值的比值,均值(日均电量)的比值。
十、合并上述特征。
import pandas as pd
data = pd.read_csv('./data/data.csv', encoding='gbk')
# 转置data
# result = data.reset_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)
导入pandas,导入data.csv文件同时编码设置为GBK,把DATA_DATE转换为时间序列,使用透视表将index设置为'CONS_NO',columns设置为'DATA_DATE'。
注意:若此处不把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) # 缺失值处理方法:用前一个数据进行填充
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
使用导入的data数据进行缺失值识别,识别方法为isnull结合sum方法确定缺失值的个数,再使用fillna方法填充缺失值;异常值识别方法为3σ方法识别异常值。偷懒了没有对异常值进行处理
说明:
pandas提供了识别缺失值的方法isnull以及识别非缺失值的方法nonull,这两种方法在使用时返回的都是bool值True和False,结合sum函数,可以检测数据中缺失值的分布以及数据中一共含有多少缺失值。isnull和nonull之间的结果正好相反。
处理缺失值有三种方法:
异常值是指数据中个别值的数值明显偏离其余的数值,有时也成为离群点,检测异常值就是检验数据中是否有录入错误以及是否含有不合理的数据。异常值的检测常用的有两种方法,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)
surface.columns = ['min', 'max', 'mean', 'median', 'sum', 'var', 'skew', 'kurt']
return surface
print("每个用户用电数据的基本统计量:\n",statistics(result.T))
这里使用了自定义函数,是为了之后的题做准备。
数据使用了转置之后的数据result,再进行转置,调用statistics方法进行数据统计并合并统计量。
statistics中使用了pandas.concat方法,这个方法可以用来对表进行纵向堆叠,在默认情况下,即axis=0时,concat做列对齐,将不同行索引的两张或多张表纵向合并。
# 每个用户用电数据按日差分
different = result.T.diff(1) # 对转置后的dataframe进行按日差分
print("每个用户用电数据按日差分:\n",different)
print("每个用户用电数据按日差分的基本统计量:\n",statistics(different))
这里使用result转置,并调用diff方法进行数据的按日差分。
调用statistics,对按日差分的数据进行统计,并输出所有的基本统计量。
print("每个用户的5分位数为:\n",result.T.describe(percentiles=[0.05]))
使用describe方法统计每个用户的5%分位数。
# 每个用户按周求和并差分
data['DATA_DATE'] = pd.to_datetime(data['DATA_DATE'])
key = pd.PeriodIndex(data['DATA_DATE'], freq='w')
sum_week = data.groupby(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统计基本统计量。
a = result.T.apply(lambda x:x>x.max()*0.9).sum()
print("每个用户日用电量在其最大值0.9倍以上的次数:\n",a)
使用apply方法
# 输出含有最大值/最小值最多的那个月份
print("输出含有最大值/最小值最多的那个月份:")
key = pd.PeriodIndex(data['DATA_DATE'], freq='m')
month = data.groupby(by=['CONS_NO', key])['KWH'].max()# 按月进行分组
month_df = pd.DataFrame(month)
max_index = month_df.reset_index().groupby('CONS_NO')['KWH'].idxmax()
max_value = month_df.iloc[max_index]
max_value.columns = ['各用户的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 = surface_min.groupby(by=['CONS_NO', key])['KWH'].count()# 按月进行分组
min_count_df = pd.DataFrame(min_count)
min_count_df_index = min_count_df.reset_index().groupby('CONS_NO')['KWH'].idxmax()
min_value = min_count_df.iloc[min_count_df_index]
min_value.columns = ['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')
df_ratio.columns = ['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 = data.groupby(by=['CONS_NO', key])# 按月进行分组
month_sum = month.sum() # 求和的比值
s_e_1, t_f_1= date_filter(month_sum)
s_e_sum = s_e_1.groupby('CONS_NO').sum()
t_f_sum = t_f_1.groupby('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_e_2.groupby('CONS_NO').max().loc[:,'KWH']
t_f_max = t_f_2.groupby('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_e_3.groupby('CONS_NO').min().loc[:,'KWH']
t_f_min = t_f_3.groupby('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_e_4.groupby('CONS_NO').apply(lambda x:x.sum()/122) # 先计算每个用户七八月份总的用电量,然后除以总天数,得到平均值
t_f_mean = t_f_4.groupby('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 = data.reset_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 xx.max()*0.9).sum()
print("每个用户日用电量在其最大值0.9倍以上的次数:\n",a)
# 第八题,输出含有最大值/最小值最多的那个月份
print("输出含有最大值/最小值最多的那个月份:")
key = pd.PeriodIndex(data['DATA_DATE'], freq='m')
month = data.groupby(by=['CONS_NO', key])['KWH'].max()# 按月进行分组
month_df = pd.DataFrame(month)
max_index = month_df.reset_index().groupby('CONS_NO')['KWH'].idxmax()
max_value = month_df.iloc[max_index]
max_value.columns = ['各用户的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 = surface_min.groupby(by=['CONS_NO', key])['KWH'].count()# 按月进行分组
min_count_df = pd.DataFrame(min_count)
min_count_df_index = min_count_df.reset_index().groupby('CONS_NO')['KWH'].idxmax()
min_value = min_count_df.iloc[min_count_df_index]
min_value.columns = ['KWH最小值次数']
print(min_value) # 输出含有最小值最多的那个月份
# 每个用户七八月电量和与三四月电量和的比值
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')
df_ratio.columns = ['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 = data.groupby(by=['CONS_NO', key])# 按月进行分组
month_sum = month.sum() # 求和的比值
s_e_1, t_f_1= date_filter(month_sum)
s_e_sum = s_e_1.groupby('CONS_NO').sum()
t_f_sum = t_f_1.groupby('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_e_2.groupby('CONS_NO').max().loc[:,'KWH']
t_f_max = t_f_2.groupby('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_e_3.groupby('CONS_NO').min().loc[:,'KWH']
t_f_min = t_f_3.groupby('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_e_4.groupby('CONS_NO').apply(lambda x:x.sum()/122) # 先计算每个用户七八月份总的用电量,然后除以总天数,得到平均值
t_f_mean = t_f_4.groupby('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)
# 合并特征
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)
最后,这是我的python数据分析与应用的大作业(非参考答案,参考需谨慎),肯定有错的或者可以优化的地方欢迎指出。
今后可能会继续把上课内容及作业写出来。(大概,不懒的话)
PS:上传了大作业所需要的文件