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)