Python 在一个大循环中优化时间
我正在使用一个400.000行的数据帧(实际上,更大,但出于测试目的,我使用这个维度) 我需要根据两个条件将多个文件导出为txt/csv:#RIC和Date 围绕这些条件循环是一个非常缓慢的过程,因此我正在寻找一些更快的方法来实现这一点 这是我最初的想法:Python 在一个大循环中优化时间,python,pandas,Python,Pandas,我正在使用一个400.000行的数据帧(实际上,更大,但出于测试目的,我使用这个维度) 我需要根据两个条件将多个文件导出为txt/csv:#RIC和Date 围绕这些条件循环是一个非常缓慢的过程,因此我正在寻找一些更快的方法来实现这一点 这是我最初的想法: def SaveTxt(df, output_folder=None): # Start time start_time = time.time() # Data Frame with date df['Date'] = pd.to_dat
def SaveTxt(df, output_folder=None):
# Start time
start_time = time.time()
# Data Frame with date
df['Date'] = pd.to_datetime(df['Date-Time']).dt.date
dates = df['Date'].unique()
ticks = df['#RIC'].unique()
for tick in ticks:
for date in dates:
# print(date, tick)
# Filtering by instrument and date
temp_df = df[(df['#RIC'] == tick) & (df['Date'] == date)]
if temp_df.empty:
pass
else:
# Saving files
if output_folder in [None, ""]:
temp_df.to_csv("%s_%s.txt" % (date, tick))
else:
temp_df.to_csv("%s\\%s_%s.txt" % (output_folder, date, tick))
# Elapsed time
elapsed_time = time.time() - start_time
elapsed_time = time.strftime("%H:%M:%S", time.gmtime(elapsed_time))
# Priting elapsed time
print('Elapsed time: %s' % elapsed_time)
对于400.000行(相当于5天的数据),运行此脚本需要3分钟。一年需要6个小时,我10年都没有试过,但我想这不是个好主意
解决方案理念
我试图从df中删除每个循环中使用的数据,但这种情况不起作用(可能这会删除数据帧的大小,并加快代码的速度):
我相信这应该会从数据框中删除每个勾号和日期,但它可以分离地应用这个条件
如果你们能解决这个问题,我将不胜感激
谢谢
编辑
不知道这是否是共享数据样本的最佳方式(我无法在代理下上传)
#RIC日期价格卷
DIJF21 16/10/2019 4.64 15
DIJF21 2019年10月16日4.64 40
DIJF21 2019年10月16日4.64 100
DIJF21 2019年10月16日4.64 5
DIJF21 2019年10月16日4.64 1765
DIJF21 2019年10月16日4.64 10
DIJF21 2019年10月16日4.64 100
DIJF21 2019年10月16日4.64 1000
DIJF21 2019年10月16日4.64 5
DIJF21 16/10/2019 4.64 20
DIJF21 2019年10月16日4.64 80
DIJF21 2019年10月16日4.64 25
DIJF21 2019年10月16日4.64 25
DIJF21 2019年10月16日4.64 150
DIJF20 2019年10月15日4.905 2000
DIJF20 2019年10月15日4.905 2000
DIJF20 2019年10月15日4.903 10
我建议你考虑一下协同程序。 诸如此类:
import asyncio
df['Date'] = pd.to_datetime(df['Date-Time']).dt.date
dates = df['Date'].unique()
ticks = df['#RIC'].unique()
async def tick_func(tick):
for date in dates:
temp_df = df[(df['#RIC'] == tick) & (df['Date'] == date)]
if temp_df.empty:
pass
else:
if output_folder in [None, ""]:
temp_df.to_csv("%s_%s.txt" % (date, tick))
else:
temp_df.to_csv("%s\\%s_%s.txt" % (output_folder, date, tick))
asyncio.new_event_loop()
asyncio.set_event_loop(asyncio.new_event_loop())
loop = asyncio.get_event_loop()
tasks = [tick_func(tick) for tick in ticks]
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
我快速浏览了一下这个问题,似乎瓶颈是双重嵌套的
for
循环,您使用该循环按勾选
和日期
对数据进行分组
<>也许您可以考虑使用一个函数调用来执行<代码> GROPPE/<代码>操作。代码如下所示:
grouped_df = df.groupby(['#RIC', 'Date'])
打印grouped_df
,确保它看起来像您期望的样子。然后,您可以在这个分组的数据帧上迭代一次,并将不同的组保存到文件系统(根据需要)
请让我知道这是否有效,或者您是否面临任何其他问题
编辑:为了跟进@Thales评论,有些人讨论了如何将大型数据帧保存到csv文件。从这些资源中,我喜欢使用numpy的建议
以下是一个示例(取自上面共享的链接之一):
事先提供一份数据样本来测试答案会很有帮助。像这样,我只希望它不会出错;) 您应该能够将groupby与一个自定义函数一起使用,该函数应用于每个组,如下所示:
grouped_df = df.groupby(['#RIC', 'Date'])
def custom_to_csv(temp_df,output_文件夹):
日期,勾选=temp_df.name
#保存文件
如果在[None,“]”中输出_文件夹:
临时文档到csv(“%s\u%s.txt”%(日期,勾号))
其他:
临时文件夹到csv(“%s\\%s\%s.txt”%(输出文件夹,日期,勾号))
df.groupby(['Date','#RIC'])。应用(自定义_到_csv,(输出_文件夹))
编辑:已更改
df
到temp\u df
和(输出文件夹)
到(输出文件夹)
嘿@lestat\u kim。您能描述一下如何使用协同程序来解决这项任务吗。仅将链接发布到库中可能无法帮助用户解决问题:)@ShagunSodhani编辑了示例的答案=)感谢添加示例@lestat_kim。您可以检查我的编辑吗?你的解决方案比我的快得多,但它只生成一个文件。我的代码中确实有两个bug。现在对你有用吗?@rpanai我编辑了编辑描述。还有别的事吗?我相信你也可以编辑它。跳过嵌套循环似乎是个好主意。有没有关于更快保存csv文件的建议?@ThalesMarques我已经更新了答案。我希望它有用。你的例子对我很有用。如果您不确定,请查看:)
grouped_df = df.groupby(['#RIC', 'Date'])
aa.to_csv('pandas_to_csv', index=False)
# 6.47 s
df2csv(aa,'code_from_question', myformats=['%d','%.1f','%.1f','%.1f'])
# 4.59 s
from numpy import savetxt
savetxt(
'numpy_savetxt', aa.values, fmt='%d,%.1f,%.1f,%.1f',
header=','.join(aa.columns), comments=''
)
# 3.5 s