【机器学习(14)】指定路径下文件的选取、数据缺失值查询及处理、帕累托分析、多文件数据合并与线性回归预测一条龙解析(全过程函数式编程)

1. 指定路径下文件的选取

       一般工作或者科研过程中,往往需要对某一文件夹中的多个文件数据进行处理,那么数据处理之前需要先定位保存该数据文件的位置,也就是找到文件所在的路径,方便进行数据的读取,关于文件路径读取的方式,这里介绍三种

        1) os.walk() 方法

        2) pathlib.Path() 方法

        3) glob.glob() 方法

个人比较倾向于第三种方式,下面就对这三种对于路径的方法进行详解

1) os.walk() 方法

import os
path_dir = "D:\\projects"
os.chdir(path_dir)
for dirpaths,dirnames,filenames in os.walk('./'):
    print(filenames)

–> 输出的结果为:

['data01.xlsx', 'data02.xlsx', 'data03.xlsx']

2) pathlib.Path() 方法

import pathlib
path_root = pathlib.Path(path_dir)
print(path_root,type(path_root))#这种路径 是windowspath并不是我们可以直接操作的路径
path_list = []
for item in path_root.iterdir():#对里面所有的文件进行迭代
    path_list.append(item)
all_file_paths = [str(path) for path in path_list] #列表推导式直接将所有路径给放在列表里面
print("通过pathlib生成绝对路径:")
all_file_paths[:3] #这种返回的是绝对路径

–> 输出的结果为:

D:\projects  <class 'pathlib.WindowsPath'>

['D:\\projects\\data01.xlsx',
 'D:\\projects\\data02.xlsx',
 'D:\\projects\\data03.xlsx']

3) glob.glob() 方法

import glob
path_ob = glob.glob("D:\\projects\\*")
print("通过glob生成绝对路径:\n{}".format(path_ob))

–> 输出的结果为:(这里使用的是绝对路径)

通过glob生成绝对路径:
['D:\\projects\\data01.xlsx', 'D:\\projects\\data02.xlsx', 'D:\\projects\\data03.xlsx']

如果使用相对路径的方式进行获取的话,可以先将程序运行的路径指定为目标文件夹

import os
os.chdir(r"D:\projects")
import glob
path_ob = glob.glob("*")
print("通过glob生成绝对路径:\n{}".format(path_ob))

–> 输出的结果为:(这里使用的是相对路径)

通过glob生成绝对路径:
['D:\\projects\\data01.xlsx', 'D:\\projects\\data02.xlsx', 'D:\\projects\\data03.xlsx']
2. 数据缺失值查询

前期准备: 至此正式开始进行数据处理了,在进行代码编写之前,习惯将要使用的库在最前面都加载进来

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
print('finished!')

–> 输出的结果为:

finished!

封装函数:第一步是获取指定路径下的文件,前面已经介绍过了,然后就是获取数据的总量和列标题,通过data[data.isnull().values == True]计算数据缺失数量,最后加上一个计数器n,来记录每个文件的情况

def Data_glimpse():
    import glob
    path_files = glob.glob("D:\\projects\\*")
    n = 1
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        data_counts = len(data)   # 计算数据量
        columns = data.columns.tolist()  # 输出数据columns
        #indexs = data.index.tolist()  #输出索引列
        nan_counts = len(data[data.isnull().values == True])   # 计算缺失值数量
        #nan_counts = data.isna().sum()#这种方式会把数据在每一列的数据缺失值给统计出来
        print("第{}个文件数据量为:{}\n列表数据字段:{}\n其中缺失数据量:{}".format(n,data_counts,columns,nan_counts))
        print('------')
        n += 1
 
Data_glimpse()

–> 输出的结果为:(本函数的难点在于如何定位缺失值的位置,并进行缺失值计数)

1个文件数据量为:31
列表数据字段:['productA', 'productB']
其中缺失数据量:3
------2个文件数据量为:28
列表数据字段:['productA', 'productB']
其中缺失数据量:4
------3个文件数据量为:31
列表数据字段:['productA', 'productB']
其中缺失数据量:3
------
3. 缺失值处理

处理方式:遍历每个字段(列),以某个指定数据进行填充(这里是以均值的方式)

def Missing_value_processing():
    import glob
    path_dir = glob.glob("D:\\projects\\*")
    path_files = [path_dir][0]
    data_files = []
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        columns = data.columns.tolist()
        data.index.to_period()
        for column in columns:
            data[column].fillna(data[column].mean(),inplace = True)
        data_files.append(data)#这个添加的方式不可以写错位置,不然输出的就是6个数据了
    return(data_files)

data = Missing_value_processing()
data1,data2,data3 = data[0],data[1],data[2]
print(data1.head())

–> 输出的结果为:(这里只展示data1中的数据,其余的数据也是类似)

              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
4. 数据分析

1) 简单地绘制条形图

注意:这里面的部分代码需要根据具体的数据内容进行调整的,比如里面的要确定几个表格存放数据,以及要显示的时间和频率等

def Data_analysis(*data_files):
    A_sales = []
    B_sales = []
    for data in data_files:
        columns = data.columns
        A_sales.append(data[columns[0]].sum())
        B_sales.append(data[columns[1]].sum())
    df = pd.DataFrame({"A_sales_sum":A_sales,"B_sales_sum":B_sales},
                      index = pd.period_range('2018-01','201803',freq = "M"))
    df.plot(kind="bar",style= "--o",color =['r','g'],alpha = 0.7, figsize = (12,8),rot= 0, edgecolor ="k")
    plt.grid(linestyle = "--",axis='y',alpha = 0.7)
    plt.title("1-3月A,B产品总销量")
    plt.savefig('C:\\Users\\86177\\Desktop\\' + 'A,B产品1-3月总销量柱状图.png',dpi=400)

Data_analysis(data1,data2,data3)

–> 输出的结果为:(关键在于DataFrame数据的构建)
在这里插入图片描述
2) 帕累托分析

帕累托分析(贡献度分析) → 帕累托法则:20/80定律

“原因和结果、投入和产出、努力和报酬之间本来存在着无法解释的不平衡。一般来说,投入和努力可以分为两种不同的类型:多数,它们只能造成少许的影响;少数,它们造成主要的、重大的影响。”

比如:一个公司,80%利润来自于20%的畅销产品,而其他80%的产品只产生了20%的利润

def Pareto_analysis(*data_files):
    key_dates =[]
    for data in data_files:
        columns = data.columns #虽然在前面已经知道里面的内容,但是代码要具有泛化性能,所以这样表达是没有问题的
        data['A_sales_sum%'] = data[columns[0]].cumsum() / data[columns[0]].sum()
        key_date = data[data['A_sales_sum%']>0.8].index[0]#会返回超过0.8的全部的dataframe,这时候索引第一个索引就是对应的天数
        #print(key_date)
        key_dates.append(str(key_date).split(" ")[0]) #这里结果的话只需要日期就行,不要后面的时分秒
    return(key_dates)

Pareto_analysis(data1,data2,data3)

–> 输出的结果为:(这里也可以进行遍历循环进行绘图,前面已经有一个基础图了,这里就不绘制了)

['2018-01-26', '2018-02-23', '2018-03-25']
5. 多文件数据合并

这里的内容和博客python数据处理(3)里面的内容同理,但是这里进行函数的封装,方便调用

def data_concat():
    import glob
    path_files = glob.glob("D:\\projects\\*")
    data_files = []
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        columns = data.columns.tolist()
        data.index.to_period()
        data.dropna(inplace=True)
        data_files.append(data)
    data = pd.concat([data_files[0], data_files[1], data_files[2]])
    return(data)

data_count = len(data_concat())
print('数据总量为:\n{}'.format(data_count))

–> 输出的结果为:(由缺失值查看可知,三个文件总共缺失10条数据,那么合并三个列表,应当是90条数据,由于之前已经进行过缺失值的填充处理,那么这里就进行缺失值的删除处理,所以最后的数据量就为80条了)

数据总量为:
80
6. 线性回归预测
def line_predict(num):
    from sklearn.linear_model import LinearRegression
    model = LinearRegression() #加载模型
    data = data_concat() #直接调用函数就行
    x,y = data['productA'][:,np.newaxis],data["productB"] #配置数据,注意对x数据的处理
    model.fit(x,y)#模型拟合
    xtest = np.linspace(0,1000,1000)[:,np.newaxis] #尽量在使用之前将x数据处理好
    ytest = model.predict(xtest) #设置好检验数据
    plt.scatter(data['productA'],data['productB'],marker = '.',color = 'k')
    plt.plot(xtest,ytest,color = 'r')
    plt.grid(linestyle = "--")
    plt.title('A-B产品销量回归拟合')
    plt.savefig('C:\\Users\\86177\\Desktop\\'+ 'A-B产品销量回归拟合.png',dpi=400)
    return(model.predict([[num]]))#这里加入两个中括号

line_predict(1200)

–> 输出的结果为:(注意程序不要直接运行,否则会导致两个图在一个画布上,建议使用notebook或者spyder进行代码分步式运行)
在这里插入图片描述

7. 全部代码

当然把这几个函数封装为一个类也可以方便调用,但是个人觉得需要用的时候之间函数复制过去即可,也不是很浪费时间

# -*- coding: utf-8 -*-
"""
Created on Wed Mar 19 00:40:59 2020

@author: xianl
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#第一种方式
# import os
# path_dir = r"D:\projects"
# os.chdir(path_dir)
# for dirpaths,dirnames,filenames in os.walk('./'):
#     print(filenames)

# 第二种方式
# import pathlib
# path_root = pathlib.Path(path_dir)
# print(path_root,type(path_root))#这种路径 是windowspath并不是我们可以直接操作的路径
# path_list = []
# for item in path_root.iterdir():#对里面所有的文件进行迭代
#     path_list.append(item)
# all_file_paths = [str(path) for path in path_list] #列表推导式直接将所有路径给放在列表里面
# print("通过pathlib生成绝对路径:")
# all_file_paths[:3] #这种返回的是绝对路径

#第三种方式
# import os
# os.chdir(r"D:\projects")
# import glob
# path_ob = glob.glob("*")
# print("通过glob生成绝对路径:\n{}".format(path_ob))

def Data_glimpse():
    import glob
    path_files = glob.glob("D:\\projects\\*")
    n = 1
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        data_counts = len(data)   # 计算数据量
        columns = data.columns.tolist()  # 输出数据columns
        #indexs = data.index.tolist()  #输出索引列
        nan_counts = len(data[data.isnull().values == True])   # 计算缺失值数量
        #nan_counts = data.isna().sum()#这种方式会把数据在每一列的数据缺失值给统计出来
        print("第{}个文件数据量为:{}\n列表数据字段:{}\n其中缺失数据量:{}".format(n,data_counts,columns,nan_counts))
        print('------')
        n += 1

def Missing_value_processing():
    import glob
    path_dir = glob.glob("D:\\projects\\*")
    path_files = [path_dir][0]
    data_files = []
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        columns = data.columns.tolist()
        data.index.to_period()
        for column in columns:
            data[column].fillna(data[column].mean(),inplace = True)
        data_files.append(data)#这个添加的方式不可以写错位置,不然输出的就是6个数据了
    return(data_files)


def Data_analysis(*data_files):
    A_sales = []
    B_sales = []
    for data in data_files:
        columns = data.columns
        A_sales.append(data[columns[0]].sum())
        B_sales.append(data[columns[1]].sum())
    df = pd.DataFrame({"A_sales_sum":A_sales,"B_sales_sum":B_sales},
                      index = pd.period_range('2018-01','201803',freq = "M"))#标签需要重新设定了
    df.plot(kind="bar",style= "--o",color =['r','g'],alpha = 0.7, figsize = (12,8),rot= 0, edgecolor ="k")#edge这个单词我竟然拼错了
    plt.grid(linestyle = "--",axis='y',alpha = 0.7)
    plt.title("1-3月A,B产品总销量")
    plt.savefig('C:\\Users\\86177\\Desktop\\' + 'A,B产品1-3月总销量柱状图.png',dpi=400)


def Pareto_analysis(*data_files):
    key_dates =[]
    for data in data_files:
        columns = data.columns #虽然在前面已经知道里面的内容,但是代码要具有泛化性能,所以这样表达是没有问题的
        data['A_sales_sum%'] = data[columns[0]].cumsum() / data[columns[0]].sum()
        key_date = data[data['A_sales_sum%']>0.8].index[0]#会返回超过0.8的全部的dataframe,这时候索引第一个索引就是对应的天数
        #print(key_date)
        key_dates.append(str(key_date).split(" ")[0]) #这里结果的话只需要日期就行,不要后面的时分秒
    return(key_dates)

def data_concat():
    import glob
    path_files = glob.glob("D:\\projects\\*")
    data_files = []
    for path in path_files:
        data = pd.read_excel(path,index_col = 0)
        columns = data.columns.tolist()
        data.index.to_period()
        data.dropna(inplace=True)
        data_files.append(data)
    data = pd.concat([data_files[0], data_files[1], data_files[2]])
    return(data)


def line_predict(num):
    from sklearn.linear_model import LinearRegression
    model = LinearRegression() #加载模型
    data = data_concat() #直接加载函数就行
    x,y = data['productA'][:,np.newaxis],data["productB"] #配置数据,注意对x数据的处理
    model.fit(x,y)#模型拟合
    xtest = np.linspace(0,1000,1000)[:,np.newaxis] #尽量在使用之前将x数据处理好
    ytest = model.predict(xtest) #设置好检验数据
    plt.scatter(data['productA'],data['productB'],marker = '.',color = 'k')
    plt.plot(xtest,ytest,color = 'r')
    plt.grid(linestyle = "--")
    plt.title('A-B产品销量回归拟合')
    plt.savefig('C:\\Users\\86177\\Desktop\\'+ 'A-B产品销量回归拟合.png',dpi=400)
    return(model.predict([[num]]))#这里加入两个中括号


if __name__ == '__main__':
    Data_glimpse()
    data = Missing_value_processing()
    data1,data2,data3 = data[0],data[1],data[2]
    print(data1,data2,data3)
    Data_analysis(data1,data2,data3)
    Pareto_analysis(data1,data2,data3)
    data_count = len(data_concat())
    print('数据总量为:\n{}'.format(data_count)) 
    #line_predict(1200)
8. 溜了溜了,深夜容易猝死

在这里插入图片描述

原创文章 159 获赞 93 访问量 4万+

猜你喜欢

转载自blog.csdn.net/lys_828/article/details/104957062