【发布时间】:2020-12-24 07:20:47
【问题描述】:
所以我在一个目录下有大约 5000 个 csv 文件,其中包含股票的分钟数据。每个文件都以其符号命名。像股票 AAPL 被命名为 AAPL.csv。
我尝试对它们中的每一个进行一些清理和编辑。在这种情况下,我尝试将包含 unix epoch datatime 的一列转换为可读的日期和时间。我也想更改一列的标签。
我尝试使用多处理来加快处理速度。但首先尝试杀死我的 Macbook。
我在 VScode 的 jupyter notebook 中运行它。如果这很重要。
我想知道我做错了什么以及如何改进。以及如何在 python 和 pandas 中处理类似的任务。
谢谢!
这是我的代码。
# Define operations will be used in multiprocessing handling
def clean_up(file,fail_list):
print('Working on {}'.format(file))
stock = pd.read_csv('./Data/minutes_data/' + file)
try:
#Convert datetime columns into readable date and time column
stock['Date'] = stock.apply(lambda row: epoch_converter.get_date_from_mill_epoch(row['datetime']), axis=1)
stock['Time'] = stock.apply(lambda row: epoch_converter.get_time_from_mill_epoch(row['datetime']), axis=1)
#Rename 'Unnamed: 0' column into 'Minute'
stock.rename(columns={'Unnamed: 0':'Minute'}, inplace=True)
#Write it back to new file
stock.to_csv('./Data/working_data/' + file)
except:
print('{} not successful'.format(file))
fail_list = fail_list.append(file)
fail_list.to_csv('./failed_list.csv')
#Get file list to working on.
file_list = os.listdir('./Data/minutes_data/')
#prepare failed_list
fail_list = pd.DataFrame([])
#Loop through each file
processes = []
for file in file_list:
p = multiprocessing.Process(target=clean_up, args=(file,fail_list,))
processes.append(p)
p.start()
for process in processes:
process.join()
更新:CSV_FILE_SAMPLE
,开,高,低,关,音量,日期时间 0,21.9,21.9,21.9,21.9,200,1596722940000 0,20.0,20.0,19.9937,19.9937,200,1595266500000 1,20.0,20.0,19.9937,19.9937,500,1595266800000 2,20.0,20.0,19.9937,19.9937,1094,1595267040000 3,20.0,20.0,20.0,20.0,200,1595268240000
最终更新:
结合来自 @furas 和 @jsmart 的答案,该脚本设法将 5000 个 csv 的处理时间从几小时减少到 1 分钟以下(Macbook pro 上的 i9 内核低于 6)。我很高兴。你们真棒。谢谢!
最终脚本在这里:
import pandas as pd
import numpy as np
import os
import multiprocessing
import logging
logging.basicConfig(filename='./log.log',level=logging.DEBUG)
file_list = os.listdir('./Data/minutes_data/')
def cleanup(file):
print('Working on ' + file)
stock = pd.read_csv('./Data/minutes_data/' + file)
try:
#Convert datetime columns into readable date and time column
stock['Date'] = pd.to_datetime(stock['datetime'],unit='ms',utc=True).dt.tz_convert('America/New_York').dt.date
stock['Time'] = pd.to_datetime(stock['datetime'],unit='ms',utc=True).dt.tz_convert('America/New_York').dt.time
#Rename 'Unnamed: 0' column into 'Minute'
stock.rename(columns={'Unnamed: 0':'Minute'}, inplace=True)
#Write it back to new file
stock.to_csv('./Data/working_data/' + file)
except:
print(file + ' Not successful')
logging.warning(file + ' Not complete.')
pool = multiprocessing.Pool()
pool.map(cleanup, file_list)
【问题讨论】:
-
您收到错误消息了吗?那是什么?
-
使用
multiprocessing.Process可以同时创建5000进程。更好地使用即。multiprocessing.Pool(10)同时只运行10进程。当某个进程结束工作时,它将与列表中的下一个文件一起使用。 -
首先进行分析非常有帮助 - 这会让您知道减速在哪里。如果只是等待文件 IO,线程池可能是更好的选择。
-
multiprocessing 的文档甚至在第一个示例中显示
Pool。 -
与
Pool你也可以使用return将失败的文件发送到主进程,然后它可以保存它。在不同的进程中保存在同一个文件failed_list.csv中可能会产生错误的结果。除了进程不共享变量,每个进程都有自己的空failed_file副本,它只会保存一个值并删除文件'./failed_list.csv'中的先前值。
标签: python pandas python-multiprocessing python-multithreading