读取及合并minio上csv文件,处理数据结构,保存至本地

背景及目标

所有文件以csv格式存储在minio上,需要将其:

  1. 本地读取指定文件或所有文件
  2. 下载指定文件
  3. 合并所有文件为一个文件
  4. 将文件修改为pandas.dataframe格式
  5. 将文件名中的时间作为新的一列加入到合并后的文件中
  6. 获取指定周期内的数据
  7. 以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)

 相关资料

  1. Minio SDKs - Python Client API文档 - 《Minio Cookbook 中文版》

  2.  python string和bytes互相转换,去除str(bytes)输出的b‘字眼
  3. 用.get_object()获取minio上指定路径的文件:Python minio上传和下载文件python操作Minio 
  4. 获取指定后缀名为csv的文件:Python:获取目录下指定后缀的文件python遍历指定后缀名的文件
  5. 用pandas库和csv库读取csv文件:python读取csv文件的几种方式(含实例说明
  6. csv文件读取为字典、列表等:用Python读取CSV文件的5种方式
  7. BufferedWritter:二进制字符缓冲流,特点是高效读写,支持换行符。io --- 处理流的核心工具 — Python 3.11.0 文档
  8. numpy中如何遍历输出np.array类型的数组:Python中Numpy常见用法
  9. split函数的常用方法:用于通过指定分隔符对字符串进行切片,切片后生成列表。Python中的split()函数的使用方法Python split()方法 | 菜鸟教程 (runoob.com)
  10. 将list转为str型,以用于.split函数进行分隔:Python list 与 str 互转
  11. 将byte转为str型,以用于.split函数进行分隔:python byte和str转换
  12. dataframe中loc和iloc的区别:df.loc[行索引,列名] ,df.iloc[行位置,列位置] 。dataframe选取特定行和列
  13. 通过set_index的方式设置其它列为索引:Pandas-数据结构-DataFrame(二):设置索引【①创建DataFrame时添加行、列索引;②修改行/列索引值;③重设新下标索引;④以某列值设置为新的索引】
  14. 通过rename和map的方式,对dataframe数据的行列索引进行重命名:Python dataframe如何设置index_python_脚本之家 (jb51.net)
  15. 删除空行:python 去除dataframe中的空行
  16. 用.tail()删除最后一行:删除python DataFrame 最后一行或者几行 DataFrame.drop()
  17. 用data = data.iloc[:, 0].str.split('/t',expand=True) 拆分dataframe列:将dataframe列拆分为多个列Python一列拆分成多列怎么做
  18. 用rename重命名列名:pandasDataFrame数据重命名列名的几种方式
  19. 重置索引从0开始:Python笔记:索引设置
  20. 读取csv文件时跳过:关于python:编写csv时跳过第一行(pandas.DataFrame.to_csv) 
  21. python string和bytes互相转换,去除str(bytes)输出的b‘字眼

  22. 取7天内的数据:

    1. 获得当前日期和当前日期后的n天:Python和Pandas 时间处理(加、减、转换)
    2. 提取日期:python中使用pandas提取日期信息如何从DataFrame中提取年、月、日、时、分
    3. 取某行某列的记录:pandas取dataframe特定行/列
  23. 以字典的方式进行聚合:Pandas中的宝藏函数-agg()groupby函数详解
  24. 用ArgumentParser()解析器在命令行中进行输入的方式实现:Python命令行运行脚本时传入参数的方式 - 张小丹 - 博客园

  25. 可视化各种图像的写法:数据可视化是什么_很详细Matplotlib 教程 | 菜鸟教程

  26. vscode无法直接输出图像,需要先保存图像后打开:Linux/Ubuntu远程服务器使用plt.show()没有反应

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要好好撸AI

你的鼓励就是我最大的创作动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值