[英]Optimizing time in a large loop Pandas to_csv
我正在使用 400.000 行 dataframe (實際上,更大,但出於測試目的,我使用了這個維度)。
我需要根據兩個條件導出到 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 Date Price Volume DIJF21 16/10/2019 4.64 15 DIJF21 16/10/2019 4.64 40 DIJF21 16/10/2019 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 16/10/2019 4.64 100 DIJF21 16/10/2019 4.64 1000 DIJF21 16/10/2019 4.64 5 DIJF21 16/10/2019 4.64 20 DIJF21 16/10/2019 4.64 80 DIJF21 16/10/2019 4.64 25 DIJF21 16/10/2019 4.64 25 DIJF21 16/10/2019 4.64 150 DIJF20 15/10/2019 4.905 2000 DIJF20 15/10/2019 4.905 2000 DIJF20 15/10/2019 4.903 10
我建議你考慮協程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()
我快速通過了這個問題,似乎瓶頸是雙重嵌套for
循環,您使用它來按tick
和date
對數據進行分組。
也許您可以考慮使用groupby
function在單個 function 調用中執行groupby
操作。 代碼看起來像這樣:
grouped_df = df.groupby(['#RIC', 'Date'])
打印grouped_df
以確保它看起來像您期望的樣子。 然后您可以遍歷這個分組的 dataframe 一次並將不同的組保存到文件系統(根據需要)。
請讓我知道這是否有效或您是否遇到任何其他問題。
編輯:為了跟進@Thales 的評論,有一些在線資源討論了如何將大型數據幀保存到 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
提供數據樣本以預先測試答案會很有幫助。 像這樣,我只希望它可以正常工作;)
您應該能夠將 groupby 與自定義 function 一起應用於每個組,如下所示:
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))
編輯:將df
更改為temp_df
並將(output_folder,)
更改為(output_folder)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.