【问题标题】:Optimizing time in a large loop Pandas to_csv在大循环中优化时间 Pandas to_csv
【发布时间】:2020-03-18 12:51:29
【问题描述】:

我正在使用 400.000 行数据框(实际上更大,但出于测试目的,我使用了这个维度)。

我需要根据两个条件将多个文件导出为 txt/csv:#RIC 和日期。

在这些条件下循环是一个非常缓慢的过程,所以我正在寻找一些更快的方法来做到这一点。

这是我最初的想法:

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 中删除每个循环中使用的数据,但这种情况不起作用(也许这会删除数据框的大小并加快代码转换速度):

df = df[(df['#RIC'] != tick) & (df['Date'] != date)]

我相信这应该从数据框中删除每个刻度和日期,但它会单独应用此条件。

如果你们有解决这个问题的办法,我将不胜感激。

谢谢

编辑

不知道这是否是分享数据样本的最佳方式(我无法通过代理上传)


#RIC 日期价格量
DIJF21 2019 年 10 月 16 日 4.64 15
DIJF21 2019 年 10 月 16 日 4.64 40
DIJF21 2019 年 10 月 16 日 4.64 100
DIJF21 16/10/2019 4.64 5
DIJF21 16/10/2019 4.64 1765
DIJF21 16/10/2019 4.64 10
DIJF21 2019 年 10 月 16 日 4.64 100
DIJF21 2019 年 10 月 16 日 4.64 1000
DIJF21 16/10/2019 4.64 5
DIJF21 2019 年 10 月 16 日 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 15/10/2019 4.905 2000
DIJF20 15/10/2019 4.905 2000
DIJF20 2019 年 15 月 10 日 4.903 10

【问题讨论】:

标签: python pandas


【解决方案1】:

我建议你考虑协程 https://docs.python.org/3/library/asyncio-task.html

类似的东西:

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()

【讨论】:

  • 嘿@lestat_kim。您能否描述一下协程如何用于解决此任务。仅仅发布图书馆的链接可能无法帮助用户解决他们的问题:)
  • @ShagunSodhani 我编辑了一个例子的答案 =)
  • 感谢您添加示例@lestat_kim。
【解决方案2】:

提供数据样本以预先测试答案会很有帮助。像这样,我只希望它能正常工作;)

您应该能够将 groupby 与应用到每个组的自定义函数一起使用,如下所示:

def custom_to_csv(temp_df, output_folder):
    date, tick = temp_df.name
    # 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))

df.groupby(['Date', '#RIC']).apply(custom_to_csv, (output_folder))

编辑:已更改 dftemp_df(output_folder,)(output_folder)

【讨论】:

  • 你能检查我的编辑吗?你的解决方案比我的要快得多,但它只生成一个文件。
  • 我的代码中确实有两个错误。它现在对你有用吗?
  • @rpanai 我编辑了编辑描述。还有别的吗?我相信你也可以编辑它。
【解决方案3】:

我快速解决了这个问题,似乎瓶颈是双重嵌套的for 循环,您使用它来按tickdate 对数据进行分组。

也许您可以考虑使用groupby function 在单个函数调用中执行groupby 操作。代码看起来像这样:

grouped_df = df.groupby(['#RIC', 'Date'])

打印grouped_df 以确保它看起来像您期望的样子。然后,您可以遍历这个分组的数据帧一次并将不同的组保存到文件系统(根据需要)。

请让我知道这是否有效或您是否遇到任何其他问题。

编辑:为了跟进@Thales 的评论,有一些online resources 讨论了如何将大型数据帧保存到csv 文件中。从这些资源中,我喜欢使用 numpy 的建议。

以下是一个示例(取自上面共享的链接之一):

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

【讨论】:

  • 跳过嵌套循环似乎是个好主意。关于更快地保存 csv 文件的任何建议?
  • @ThalesMarques 我已经更新了答案。我希望它有用。
猜你喜欢
  • 2019-01-01
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多