Python 在一个大循环中优化时间

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

我正在使用一个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_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