簡體   English   中英

重建數據框字典的有效方法

[英]Efficient way to rebuild a dictionary of dataframes

我有一本充滿多個數據框的字典。 現在我正在尋找一種更改密鑰結構的有效方法,但是當涉及更多數據幀/更大的數據幀時,我發現的解決方案相當慢。 這就是為什么我想問是否有人知道比我更方便/高效/更快的方法或方法。 所以首先,我創建了這個例子來展示我最初開始的地方:

import pandas as pd
import numpy as np

# assign keys to dic
teams = ["Arsenal", "Chelsea", "Manchester United"]
dic_teams = {}

# fill dic with random entries
for t1 in teams:

    dic_teams[t1] = pd.DataFrame({'date': pd.date_range("20180101", periods=30), 
                                  'Goals': pd.Series(np.random.randint(0,5, size = 30)),
                                  'Chances': pd.Series(np.random.randint(0,15, size = 30)),
                                  'Fouls': pd.Series(np.random.randint(0, 20, size = 30)),
                                  'Offside': pd.Series(np.random.randint(0, 10, size = 30))})

    dic_teams[t1] = dic_teams[t1].set_index('date')
    dic_teams[t1].index.name = None

現在我基本上有一個字典,其中每個鍵都是一個團隊,這意味着我有一個 dataframe 用於每個團隊,其中包含他們隨時間推移的游戲表現信息。 現在我更願意更改這個特定的字典,以便我得到一個結構,其中鍵是日期,而不是團隊。 這意味着我每個日期都有一個 dataframe,其中包含每個團隊在該日期的表現。 我設法使用以下代碼做到了這一點,該代碼有效但在我添加更多團隊和性能因素后確實很慢:

# prepare lists for looping
dates = dic_teams["Arsenal"].index.to_list()
perf = dic_teams["Arsenal"].columns.to_list()
dic_dates = {}

# new structure where key = date
for d in dates:
    dic_dates[d] = pd.DataFrame(index = teams, columns = perf)

    for t2 in teams:
        dic_dates[d].loc[t2] = dic_teams[t2].loc[d]

因為我使用的是嵌套循環,所以我的字典重組很慢。 有誰知道我如何改進第二段代碼? 我不一定只是在尋找解決方案,也在尋找如何做得更好的邏輯或想法。

在此先感謝,非常感謝任何幫助

以您的方式創建 Pandas 數據幀(奇怪地)非常慢,直接索引也是如此

復制 dataframe 出奇地快。 因此,您可以使用多次復制的空引用 dataframe。 這是代碼:

dates = dic_teams["Arsenal"].index.to_list()
perf = dic_teams["Arsenal"].columns.to_list()
zygote = pd.DataFrame(index = teams, columns = perf)
dic_dates = {}

# new structure where key = date
for d in dates:
    dic_dates[d] = zygote.copy()

    for t2 in teams:
        dic_dates[d].loc[t2] = dic_teams[t2].loc[d]

這比我機器上的參考快 2 倍。

克服緩慢的 dataframe 直接索引是棘手的。 我們可以使用 numpy 來做到這一點。 的確,我們可以將dataframe轉換為3D numpy數組,使用numpy進行轉置,最后再次將切片轉換為dataframes。 請注意,此方法假定所有值都是整數,並且輸入 dataframe 結構良好

這是最終的實現:

dates = dic_teams["Arsenal"].index.to_list()
perf = dic_teams["Arsenal"].columns.to_list()
dic_dates = {}

# Create a numpy array from Pandas dataframes
# Assume the order of the `dates` and `perf` indices are the same in all dataframe (and their order)
full = np.empty(shape=(len(teams), len(dates), len(perf)), dtype=int)
for tId,tName in enumerate(teams):
    full[tId,:,:] = dic_teams[tName].to_numpy()

# New structure where key = date, created from the numpy array
for dId,dName in enumerate(dates):
    dic_dates[dName] = pd.DataFrame({pName: full[:,dId,pId] for pId,pName in enumerate(perf)}, index = teams)

這個實現比我機器上的參考快 6.4 倍 請注意,大約 75% 的時間不幸地花在了pd.DataFrame調用上。 因此,如果您想要更快的代碼,請使用基本的 3D numpy 數組

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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