[英]pandas update a dataframe with values from another dataframe on the match of column values
我有一個數據框,其中股票代碼名稱和日期為兩列,我想用另一個與這兩列匹配的更大數據框的價格值來更新這個數據框
例如:df1:
ticker Date
AAPL 2022-01-03
GE 2022-04-18
df2:
ticker Date Close
AAPL 2022-01-02 120
AAPL 2022-01-03 122
AAPL 2022-01-04 125
AAPL 2022-01-05 121
.
.
.
GE 2022-04-16 20
GE 2022-04-17 22
GE 2022-04-18 25
GE 2022-04-19 21
輸出應該是:
ticker Date Close
AAPL 2022-01-03 122
GE 2022-04-18 25
我可以做一個循環並逐行更新,但我想檢查是否有使用整個系列/向量的pythonic方式......
TL;DR :如果您可以提前索引您的數據幀,那么對於兩個數據幀的每個單獨連接(一個有 500 行,一個有 2500 萬行),您可以比merge()
好大約 10,000 倍; 如果您只對此類數據幀進行一次連接,則 merge() 與其他方法一樣快。
你的問題說:
我有一個數據框,其中股票代碼名稱和日期為兩列,我想用另一個與這兩列匹配的更大數據框的價格值來更新這個數據框
...你問:
我想檢查是否有使用整個系列/向量的pythonic方式
如果您的問題是在這個單一數據框查詢的上下文中提出的,那么您可能無法獲得比merge()
更好的性能。
但是,如果您可以選擇初始化數據框以使用ticker, Date
作為它們的索引,或者如果您至少可以將它們的索引設置為ticker, Date
,然后需要運行問題中描述的多個查詢,那么您可以擊敗merge()
。
以下是 df1 500 行和 df2 2500 萬行的 6 種不同策略的基准:
Timeit results:
foo_1 (merge) ran in 23.043055499998445 seconds
foo_2 (indexed join) ran in 51.69773360000181 seconds
foo_3 (pre-indexed join) ran in 0.0027679000013449695 seconds
foo_4 (pre-indexed df1 join) ran in 24.431038499998976 seconds
foo_5 (merge right) ran in 22.99117219999971 seconds
foo_6 (pre-indexed assign) ran in 0.007970200000272598 seconds
請注意, pre-indexed join
比merge
快約 10,000 倍(並且pre-indexed assign
也快約 3,000 倍),主要是因為預索引數據幀通過索引訪問哈希表,其關鍵字搜索時間為 O(1 ) 與非索引鍵的最壞情況 O(n) 時間。 但是, indexed join
的速度是merge
的兩倍多,因為indexed join
包括初始索引工作(對於多個查詢,例如您的問題中的查詢,只需執行一次,並且不包括在pre-indexed join
之外)。
各種策略的解釋:
merge
策略不使用索引。indexed join
策略包括索引兩個數據幀的時間。pre-indexed join
策略不包括索引兩個數據幀的初始開銷。pre-indexed df1 join
策略不包括索引 df1 的初始開銷,但適用於未索引的 df2。merge right
策略將 df1 和 df2 交換為merge()
的對象和參數。pre-indexed assign
策略不使用merge()
或join()
,而是從 df2 到 df1 中的新列執行索引對齊分配。以下是每種策略的代碼:
df1_orig = pd.DataFrame([('A'+str(i) , f'{2020+i//365}-{(i//28)%12 + 1}-{i%28 + 1}') for i in range(500)], columns=['ticker', 'Date'])
print(df1_orig)
df2_orig = pd.DataFrame([('A'+str(i) , f'{2020+(i%500)//365}-{((i%500)//28)%12 + 1}-{(i%500)%28 + 1}', (10 * i + 1) % 300) for i in range(25_000_000)], columns=['ticker', 'Date', 'Close'])
print(df2_orig)
df1_indexed_orig = df1_orig.set_index(['ticker', 'Date'])
df2_indexed_orig = df2_orig.set_index(['ticker', 'Date'])
# merge
def foo_1(df1, df2):
df1 = df1.merge(df2, on = ['ticker', 'Date'], how = 'left')
return df1
# indexed join
def foo_2(df1, df2):
df1.set_index(['ticker', 'Date'], inplace=True)
df2.set_index(['ticker', 'Date'], inplace=True)
df1 = df1.join(df2)
return df1
# pre-indexed join
def foo_3(df1, df2):
# called with df1_indexed_orig and df2_indexed_orig
df1 = df1.join(df2)
return df1
# pre-indexed df1 join
def foo_4(df1, df2):
# called with df1_indexed_orig
df1 = df2.join(df1, on = ['ticker', 'Date'], how = 'right')
return df1
# merge right
def foo_5(df1, df2):
df1 = df2.merge(df1, on = ['ticker', 'Date'], how = 'right')
return df1
# pre-indexed assign
def foo_6(df1, df2):
# called with df1_indexed_orig and df2_indexed_orig
df1 = df1.assign(Close=df2.Close)
return df1
嘗試合並這兩列:
df1.merge(df2, on = ['ticker', 'Date'], how = 'left')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.