多场景下的算法构建

Posted by iceman on May 18, 2018

最近在学习一门Python数据分析课程,拖延症重度患者,今天晚上12点最后截止日期,赶在12点一起完工,还得出去跑个步。下面简单理出实现

项目要求

课程数据:
某公司A,B产品在2018年1,2,3月的销量数据,数据格式为xlsx

作业要求:
1、批量读取数据,并输出以下信息
(1)数据量
(2)数据字段columns
(3)输出每个文件分别有多少缺失值
要求:
① 创建独立函数,从读取数据到以上输出要求
② 运行代码多次调用创建函数,对数据进行批量处理
提示:
① 将课程excel数据放入单独文件夹(建议英文路径),函数中通过input来输入excel数据所在文件夹路径,再通过遍历来读取文件
② pd.read_excel()中用“index_col”参数,将第一列变为index
③ os.walk(path) → 返回路径中的信息及文件,结果为一个生成器
④ 定位缺失值位置:data[data.isnull().values == True]

2、批量读取数据,用均值填充缺失值数据,并完成以下计算及图表制作
(1)读取数据并用均值填充缺失值;对“日期”字段进行时间序列处理,转换成日period ,最后输出三个Dataframe文件data1,data2,data3
(2)分别计算data1,data2,data3中A,B产品的月总销量,并绘制多系列柱状图,存储在对应的图片文件夹路径
(3)分别计算A产品在每个月中哪一天超过了月度80%的销量,输出日期
要求:
① 分别创建四个函数,对应完成上述需求
② 数据文件夹路径和图片存储路径不要相同
提示:
① 时间序列转换方法提示:pd.to_period
② 时间戳Timestampe转化成字符串用str()方法

3、读取数据并合并,做散点图观察A,B产品销量,并做回归,预测当A销量为1200时,B产品销量值
(1)读取数据删除缺失值;对“日期”字段进行时间序列处理,转换成日period ,合并三个月数据,输出data;
(2)针对A产品销量和B产品销量数据做回归分析,制作散点图并存储,并预测当A销量为1200时,B产品销量值
要求:
① 分别创建两个函数,对应完成上述需求
② 数据文件夹路径和图片存储路径不要相同
提示:
① 用pd.dripna方法去掉缺失值,注意inplace参数

数据格式如下:

data

项目实现

模块导入

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
import os
% matplotlib inline

第一题

'''
1、批量读取数据,并输出以下信息
(1)数据量
(2)数据字段columns
(3)输出每个文件分别有多少缺失值
'''

def read_excel_data(filename):
    if len(filename) > 0 :
        datas = pd.read_excel(filename, index_col = 0)
        datas_count = len(datas)
        columns = datas.columns.tolist()
        nan_counts = len(datas[datas.isnull().values == True])
        
        print("数据量 :%d" % datas_count)
        print("数据字段:%s" % str(columns))
        print("缺失值个数: %d" % nan_counts)
        print("--"*10)
        
for file in os.listdir(r"D:\data"):
   #print(file)
    read_excel_data(file)
结果输出:
数据量 :31
数据字段:['productA', 'productB']
缺失值个数: 3
--------------------
数据量 :28
数据字段:['productA', 'productB']
缺失值个数: 4
--------------------
数据量 :31
数据字段:['productA', 'productB']
缺失值个数: 3
--------------------

第二题

'''
2、批量读取数据,用均值填充缺失值数据,并完成以下计算及图表制作
(1)读取数据并用均值填充缺失值;对“日期”字段进行时间序列处理,转换成日period ,最后输出三个Dataframe文件data1,data2,data3
(2)分别计算data1,data2,data3中A,B产品的月总销量,并绘制多系列柱状图,存储在对应的图片文件夹路径
(3)分别计算A产品在每个月中哪一天超过了月度80%的销量,输出日期
要求:
① 分别创建四个函数,对应完成上述需求
② 数据文件夹路径和图片存储路径不要相同
提示:
① 时间序列转换方法提示:pd.to_period
② 时间戳Timestampe转化成字符串用str()方法
'''

#(1)读取数据并用均值填充缺失值;对“日期”字段进行时间序列处理,转换成日period ,最后输出三个Dataframe文件data1,data2,data3
def func_1(file_datas):
    for file in os.listdir("D:\\data"):
        #print(file)
        datas = pd.read_excel(file, index_col = 0)
        datas.to_period()
        for i in datas.columns:
            if i==0:
                continue
            datas[i][datas[i].isnull().values == True] = datas[i].mean()
        file_datas.append(datas)

def func_2(file_datas):
    sales={}
    idx = 0
    for data in file_datas:
        temp = []
        for col in data.columns:
            if col==0:
                continue
            sum_val = data[col].sum()
            temp.append(sum_val)
        sales[idx] = temp
        idx = idx+1
        
    #{ 'data0x' : ['A', 'B']}
    A_sale = []
    B_sale = []
   #print(sales)
    for k,v in sales.items():
        A_sale.append(v[0])
        B_sale.append(v[1])
    df = pd.DataFrame({'A_sale_sum': A_sale,'B_sale_sum':B_sale},
                     index = pd.period_range('201801','201803',freq = 'M'))
    plt.figure()
    df.plot(kind = 'bar',style = '--o',color = ['r','g'],alpha = 0.8, rot = 0,figsize = (8,4))
    plt.title('1-3月A,B产品总销量柱状图')
    plt.ylim([0,25000])
    plt.grid()
    plt.savefig("D:\\" + '1-3月A,B产品总销量柱状图.png',dpi=400)
    return sales


def func_3(file_datas):
    dates = []
    for data in file_datas:
        data['A_sale_sum%'] = data.iloc[:,[0]].cumsum() / data.iloc[:,[0]].sum()
        dates.append(str(data[data['A_sale_sum%']>0.8].index[0]))
    return dates


file_datas = []
func_1(file_datas)

for item in file_datas:
    print("--"*10)
    print(item.head())


sales = func_2(file_datas)
print(sales)

dates =func_3(file_datas)

结果输出:

    --------------------
                  productA    productB
    日期                                
    2018-01-01  270.997943  371.615646
    2018-01-02  638.322113  788.081579
    2018-01-03  364.454658  454.279288
    2018-01-04  251.432000  340.337651
    2018-01-05  261.411794  419.372368
    --------------------
                  productA    productB
    日期                                
    2018-02-01  448.857786  520.980562
    2018-02-02   90.515626  202.734783
    2018-02-03  690.225301  747.477993
    2018-02-04  461.404824  519.757557
    2018-02-05  853.796573  979.456756
    --------------------
                  productA    productB
    日期                                
    2018-03-01  517.226407  569.806387
    2018-03-02  897.788131  961.403426
    2018-03-03  363.516207  463.210468
    2018-03-04  248.089396  301.271714
    2018-03-05  610.457499  727.682169
    {0: [17774.318140241641, 20634.984308981708], 1: [16825.563937444473, 17644.780873889133], 2: [19867.499953284463, 21840.054394591782]}

销量

第三题

'''
3、读取数据并合并,做散点图观察A,B产品销量,并做回归,预测当A销量为1200时,B产品销量值
(1)读取数据删除缺失值;对“日期”字段进行时间序列处理,转换成日period ,合并三个月数据,输出data;
(2)针对A产品销量和B产品销量数据做回归分析,制作散点图并存储,并预测当A销量为1200时,B产品销量值
要求:
① 分别创建两个函数,对应完成上述需求
② 数据文件夹路径和图片存储路径不要相同
提示:
① 用pd.dripna方法去掉缺失值,注意inplace参数

'''

def func_31():
    for file in os.listdir("D:\\data"):
        datas = pd.read_excel(file, index_col = 0)
        datas.to_period()
        datas.dropna(inplace=True)
        file_datas.append(datas)
    data = pd.concat([file_datas[0],file_datas[1],file_datas[2]])
    return data

def func_32(data):
    model = LinearRegression()
    model.fit(data['productA'][:,np.newaxis],data['productB'])  
    # 构建回归模型
    xtest = np.linspace(0,1000,1000)
    ytest = model.predict(xtest[:,np.newaxis])
    plt.scatter(data['productA'],data['productB'],marker = '.',color = 'k')
    plt.plot(xtest,ytest,color = 'r')
    plt.grid(True)
    plt.title('A-B产品销量回归拟合')
    plt.savefig('D:\\' + 'A-B产品销量回归拟合.png',dpi=400)  
    # 存储图表
    return(model.predict(1200))

data = func_31()
print(data.head())

func_32(data)

结果输出:

              productA    productB  A_sale_sum%
日期                                             
2018-01-01  270.997943  371.615646     0.015247
2018-01-02  638.322113  788.081579     0.051159
2018-01-03  364.454658  454.279288     0.071664
2018-01-04  251.432000  340.337651     0.085810
2018-01-05  261.411794  419.372368     0.100517
array([ 1238.90022268])

拟合

结论

昨晚该项目,瞬间觉得要去重新学习下,同时最后的算法,真心没理解如何下手(还好有参考代码)。后期再整理相关知识点,分享出来