背景及目标
所有文件以csv格式存储在minio上,需要将其:
- 本地读取指定文件或所有文件
- 下载指定文件
- 合并所有文件为一个文件
- 将文件修改为pandas.dataframe格式
- 将文件名中的时间作为新的一列加入到合并后的文件中
- 获取指定周期内的数据
- 以csv的格式保存文件至本地
import os
import utils.minio_operation as minio_operation # 导入之前写好的minio操作库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import time
import schedule
from datetime import timedelta
def download_file(remote_file, local_file, bucket="(指定的bucket)"):
'''download Minio file and save to local 下载minio的文件到本地'''
return minio_operation.download_file(remote_file, local_file)
def get_file_list(bucket="(指定的bucket)"):
'''get all Minio files in (指定的路径) 获取minio的文件列表清单'''
client = minio_operation.get_minio_client()
objects = client.list_objects('(指定的bucket)', prefix='(指定bucket下存放csv文件的路径)', recursive=True)
obj_list = []
for obj in objects:
print('***** remote file: ', obj.bucket_name, obj.object_name.encode('utf-8'), ' last modified=', obj.last_modified, ' size=', obj.size, 'B *****') # <bytes> print file details
obj_list.append(str(obj.object_name.encode('utf-8'), encoding='utf-8'))
# print(obj_list)
return obj_list # <list>
def get_file(remote_file, bucket="(指定的bucket)"):
'''get the Minio file 获取minio的文件'''
client = minio_operation.get_minio_client()
print('***** get remote file:', os.path.join(bucket, remote_file), ' *****') # print file name
data = client.get_object(bucket, remote_file)
return data # <class 'urllib3.response.HTTPResponse'>
def operate_file(file):
'''operate files, modify data structure, set index, etc 操作文件,修改数据类型,设置索引等'''
f = str(get_file(file).data,encoding = "utf-8").split('\n')
f1 = pd.DataFrame(f)
f1 = f1.iloc[:,0].str.split(',', expand = True)
f1.drop([0], inplace = True)
f1.reset_index(level = 0, drop = True, inplace = True)
f1.drop([0], axis = 1, inplace = True)
f1 = f1.dropna()
f1.rename(columns = {0:'index', 1:'(各字段名)', 2:'(各字段名)', 3:'(各字段名)', 4:'throughput'}, inplace = True)
return f1 # <class 'pandas.core.frame.DataFrame'>
def concat_file(file):
'''merge all files, modify data type 根据指定的字段合并所有minio文件,并提取文件名中的日期,作为新文件的一列'''
f_merged = pd.DataFrame(columns = ['date', '(各字段名)', '(各字段名)', '(各字段名)', '(各字段名)'])
for f in file:
new_file = operate_file(f)
if new_file.empty:
print('WARNING!',os.path.join(f),'is empty! \n')
else:
new_file.insert(0, 'date', f[-14:-4])
print(new_file) # print each file
f_merged = pd.concat([f_merged, new_file], sort=False)
# display all data 取消显示限制,显示所有数据
# pd.set_option('display.width', 1000)
# pd.set_option('display.max_rows', None)
f_merged.reset_index(level = 0, drop = True, inplace = True)
f_merged.date = pd.to_datetime(f_merged.date)
f_merged = f_merged.astype({'(各字段名)':'str', '(各字段名)':'int', '(各字段名)':'float', '(各字段名)':'float'})
f_merged.replace(float(0), np.nan) # f_merged.fillna(0)
return f_merged
def get_period_result(file, time_frequency = -7):
'''get the data within cycle(default=last 7 days) 获取周期内的数据'''
end_date = datetime.date.today()
start_date = end_date + timedelta(days = time_frequency)
print('***** data from', start_date, 'to', end_date,' *****')
cycle_file = file.loc[(file['date'] >= pd.Timestamp(start_date)) & (file['date'] <= pd.Timestamp(end_date))]
grouped_cycle_file = cycle_file.groupby(by = ['(要分组的字段名)', '(要分组的字段名)']) # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f84f34d1700>
best_perf_file = grouped_cycle_file.aggregate({'(分组后其它字段名)':np.min, '(分组后其它字段名)':np.max})
best_perf_file.rename(columns = {'(分组后其它字段名)':'(更改分组后其它字段名)', '(分组后其它字段名)':'(更改分组后其它字段名)'}, inplace = True)
return best_perf_file
def task_trigger():
print('scheduled task is running... ...')
if __name__ == "__main__":
remote_files = get_file_list()
merged_file = concat_file(remote_files)
print('***** concat all tables at ', datetime.datetime.now(), ' *****')
print(merged_file)
'''get dataset infos 获取数据集的信息'''
# print('***** dataset infos *****')
# print('shape of dataset:', merged_file.shape)
# print('datatype of variables:\n', merged_file.dtypes)
# print('***** values by rows and cols *****')
# print(merged_file.iloc[15:30, 0:2])
'''visualize dataset 可视化数据集'''
# print('***** visualize dataset *****')
# img = merged_file.plot(x='date', y='latency', kind='line', grid=True) # 折线图
# img = merged_file.plot.bar(x='date', y='latency')
# plt.show()
# plt.savefig('./Pic2.png')
'''save all data in one file as csv 保存合并后的文件到本地'''
print('***** save all perf in one file as csv *****')
merged_file.to_csv('merged_file.csv')
'''get data for specified period and save it as csv 保存指定周期内的文件到本地'''
best_perf = get_period_result(merged_file, -30)
if best_perf.empty:
print('no data on Minio!')
else:
print(best_perf)
print('***** save the best perf for specified period as csv *****')
best_perf.to_csv('best_perf.csv')
'''download the specified remote file 下载指定文件'''
# remote_file = "(指定远程路径)/(指定远程文件名).csv"
# local_file = "(指定本地路径)/(指定本地文件名).csv"
# download_file(remote_file, local_file)
'''run daily at 10:00 每天10点定时运行'''
# schedule.every().day.at("10:00").do(task_trigger)
# while True:
# schedule.run_pending()
# time.sleep(1)
相关资料
- python string和bytes互相转换,去除str(bytes)输出的b‘字眼
- 用.get_object()获取minio上指定路径的文件:Python minio上传和下载文件,python操作Minio
- 获取指定后缀名为csv的文件:Python:获取目录下指定后缀的文件,python遍历指定后缀名的文件
- 用pandas库和csv库读取csv文件:python读取csv文件的几种方式(含实例说明
- csv文件读取为字典、列表等:用Python读取CSV文件的5种方式
- BufferedWritter:二进制字符缓冲流,特点是高效读写,支持换行符。io --- 处理流的核心工具 — Python 3.11.0 文档
- numpy中如何遍历输出np.array类型的数组:Python中Numpy常见用法
- split函数的常用方法:用于通过指定分隔符对字符串进行切片,切片后生成列表。Python中的split()函数的使用方法,Python split()方法 | 菜鸟教程 (runoob.com)
- 将list转为str型,以用于.split函数进行分隔:Python list 与 str 互转
- 将byte转为str型,以用于.split函数进行分隔:python byte和str转换
- dataframe中loc和iloc的区别:df.loc[行索引,列名] ,df.iloc[行位置,列位置] 。dataframe选取特定行和列
- 通过set_index的方式设置其它列为索引:Pandas-数据结构-DataFrame(二):设置索引【①创建DataFrame时添加行、列索引;②修改行/列索引值;③重设新下标索引;④以某列值设置为新的索引】
- 通过rename和map的方式,对dataframe数据的行列索引进行重命名:Python dataframe如何设置index_python_脚本之家 (jb51.net)
- 删除空行:python 去除dataframe中的空行
- 用.tail()删除最后一行:删除python DataFrame 最后一行或者几行 DataFrame.drop()
- 用data = data.iloc[:, 0].str.split('/t',expand=True) 拆分dataframe列:将dataframe列拆分为多个列,Python一列拆分成多列怎么做
- 用rename重命名列名:pandasDataFrame数据重命名列名的几种方式
- 重置索引从0开始:Python笔记:索引设置
- 读取csv文件时跳过:关于python:编写csv时跳过第一行(pandas.DataFrame.to_csv)
-
取7天内的数据:
- 获得当前日期和当前日期后的n天:Python和Pandas 时间处理(加、减、转换)
- 提取日期:python中使用pandas提取日期信息,如何从DataFrame中提取年、月、日、时、分
- 取某行某列的记录:pandas取dataframe特定行/列
- 以字典的方式进行聚合:Pandas中的宝藏函数-agg(),groupby函数详解
-
用ArgumentParser()解析器在命令行中进行输入的方式实现:Python命令行运行脚本时传入参数的方式 - 张小丹 - 博客园
-
可视化各种图像的写法:数据可视化是什么_很详细,Matplotlib 教程 | 菜鸟教程
-
vscode无法直接输出图像,需要先保存图像后打开:Linux/Ubuntu远程服务器使用plt.show()没有反应