簡體   English   中英

在大循環中優化時間 Pandas to_csv

[英]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循環,您使用它來按tickdate對數據進行分組。

也許您可以考慮使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM