我發現,當您將大量數據集與大量列在同一列合併時,我發現與熊貓庫直接合並鏈是非常低效的。在熊貓中高效的鏈合併
問題的根源是一樣的,當我們加入了很多的STR的愚蠢方式: 加入=減少(拉姆達A + B,爲str_list) 相反的: 加入=「」。加入(爲str_list)
做連鎖合併,我們在一次或爲了
有一些有效的方法(通過在數字複製的數據集多次(在我的情況差不多100倍),而不是從幾個數據集,只是填充柱=與線性複雜度的集合)通過同一列鏈合併大量的數據集?
我發現,當您將大量數據集與大量列在同一列合併時,我發現與熊貓庫直接合並鏈是非常低效的。在熊貓中高效的鏈合併
問題的根源是一樣的,當我們加入了很多的STR的愚蠢方式: 加入=減少(拉姆達A + B,爲str_list) 相反的: 加入=「」。加入(爲str_list)
做連鎖合併,我們在一次或爲了
有一些有效的方法(通過在數字複製的數據集多次(在我的情況差不多100倍),而不是從幾個數據集,只是填充柱=與線性複雜度的集合)通過同一列鏈合併大量的數據集?
如果您有dataframes dfs
的列表:
dfs = [df1, df2, df3, ... , dfn]
您可以用熊貓的concat
功能,據我可以告訴比鏈接合併快加入他們的行列。 concat
只能根據索引(不是列)加入數據幀,但只需稍加預處理即可模擬merge
操作。
首先用您要合併的列替換dfs
中每個數據框的索引。比方說,你想在"A"
列合併:
dfs = [df.set_index("A", drop=True) for df in dfs]
注意,這將覆蓋以前的指標(合併會這樣呢),所以你可能要保存在某個地方,這些指標(如果你要需要他們後來出於某種原因)。
現在我們可以使用CONCAT這將在實質上指數合併(這是實際上你列 !!)
merged = pd.concat(dfs, axis=1, keys=range(len(dfs)), join='outer', copy=False)
的join=
參數可以是'inner'
或'outer'
(默認)。 copy=
參數使concat
不會產生不必要的數據幀副本。
然後,您可以離開"A"
作爲索引,或者你可以通過執行,使其恢復到列:
merged.reset_index(drop=False, inplace=True)
的keys=
參數是可選的鍵值分配給每個數據幀(在這種情況下,我給它一個整數範圍,但你可以給他們其他標籤,如果你想)。這使您可以訪問原始數據框中的列。所以,如果你想獲得對應於dfs
20數據框列,您可以撥打:
merged[20]
沒有keys=
自變量,它可能會比較混亂,其行是從dataframes,特別是如果他們有相同的列名。
我還不能完全肯定,如果concat
運行線性時間,但它絕對不是鏈接merge
快:採用隨機產生的dataframes名單IPython中的%timeit
(10,100和1000 dataframes名單) :
def merge_with_concat(dfs, col):
dfs = [df.set_index(col, drop=True) for df in dfs]
merged = pd.concat(dfs, axis=1, keys=range(len(dfs)), join='outer', copy=False)
return merged
dfs10 = [pd.util.testing.makeDataFrame() for i in range(10)]
dfs100 = [pd.util.testing.makeDataFrame() for i in range(100)]
dfs1000 = [pd.util.testing.makeDataFrame() for i in range(1000)]
%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs10)
10 loops, best of 3: 45.8 ms per loop
%timeit merge_with_concat(dfs10,"A")
100 loops, best of 3: 11.7 ms per loop
%timeit merge_with_concat(dfs100,"A")
10 loops, best of 3: 139 ms per loop
%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs100)
1 loop, best of 3: 1.55 s per loop
%timeit merge_with_concat(dfs1000,"A")
1 loop, best of 3: 9.67 s per loop
%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs1000)
# I killed it after about 5 minutes so the other one is definitely faster
謝謝,這是我一直在尋找 – morph
不會'DFS =(df.set_index(COL,滴= TRUE)在DFS DF)'是更多的內存效率的,因爲它是一臺發電機 – muon
@嗯,很棒!在將其更改爲發生器後,我使用'dfs1000'設置了幾個基準測試,似乎在我的系統上運行速度提高了約2.5秒(從9.6降低了7.1秒)。注意,如果你想做這個改變,你應該調用生成器而不是'dfs',因爲你仍然需要在'pd.concat'中爲'keys'參數獲得'dfs'的長度(要合併的數據幀的數量) '和發電機沒有長度。 – bunji