いくつかのSQL操作を実行したい2つの異なるデータフレームがあります。残念ながら、私が使用しているデータの場合と同様に、スペルが異なることがよくあります。
以下の例として、useridがdf1に属し、usernameがdf2に属する構文がどのようになるかを示します。誰か助けてくれませんか?
# not working - I assume some syntax issue?
pd.merge(df1, df2, on = [['userid'=='username', 'column1']], how = 'left')
名前が異なる場合は、xxx_on
の代わりにon=
パラメーターを使用してください。
pd.merge(df1, df2, left_on= ['userid', 'column1'],
right_on= ['username', 'column1'],
how = 'left')
別のアプローチは、join
を使用して、右側のDataFrame
のインデックスを列_['username', 'column1']
_に設定することです。
_df1.join(df2.set_index(['username', 'column1']), on=['userid', 'column1'], how='left')
_
このjoin
merges 2つの異なる名前のキー列、userid
とusername
からの一致したキーの、のキー列にちなんで名付けられた単一の列への出力_df1
_、userid
;一方、merge
の出力は、2つを別々の列として維持します。説明のために、次の例を検討してください。
_import numpy as np
import pandas as pd
df1 = pd.DataFrame({'ID': [1,2,3,4,5,6], 'pID' : [21,22,23,24,25,26], 'Values' : [435,33,45,np.nan,np.nan,12]})
## ID Values pID
## 0 1 435.0 21
## 1 2 33.0 22
## 2 3 45.0 23
## 3 4 NaN 24
## 4 5 NaN 25
## 5 6 12.0 26
df2 = pd.DataFrame({'ID' : [4,4,5], 'pid' : [24,25,25], 'Values' : [544, 545, 676]})
## ID Values pid
## 0 4 544 24
## 1 4 545 25
## 2 5 676 25
pd.merge(df1, df2, how='left', left_on=['ID', 'pID'], right_on=['ID', 'pid']))
## ID Values_x pID Values_y pid
## 0 1 435.0 21 NaN NaN
## 1 2 33.0 22 NaN NaN
## 2 3 45.0 23 NaN NaN
## 3 4 NaN 24 544.0 24.0
## 4 5 NaN 25 676.0 25.0
## 5 6 12.0 26 NaN NaN
df1.join(df2.set_index(['ID','pid']), how='left', on=['ID','pID'], lsuffix='_x', rsuffix='_y'))
## ID Values_x pID Values_y
## 0 1 435.0 21 NaN
## 1 2 33.0 22 NaN
## 2 3 45.0 23 NaN
## 3 4 NaN 24 544.0
## 4 5 NaN 25 676.0
## 5 6 12.0 26 NaN
_
ここでは、出力で重複する列lsuffix
を区別するために、rsuffix
でjoin
とValue
も指定する必要があります。ご覧のとおり、merge
の出力には、右側のpid
からの追加のDataFrame
列が含まれています。これは、マージのコンテキストを考えると、IMHOは不要です。 dtype
列のpid
が_float64
_に変更されたことにも注意してください。これは、一致しない行から導入されたNaN
sによるアップキャストの結果です。
この美的出力は、右側の_set_index
_の呼び出しがDataFrame
にいくらかのオーバーヘッドをもたらすため、パフォーマンスを犠牲にして得られます。ただし、すばやく汚いプロファイルは、これがそれほどひどいものではないことを示しています。おおよそ_30%
_であり、それだけの価値があるかもしれません。
_sz = 1000000 # one million rows
df1 = pd.DataFrame({'ID': np.arange(sz), 'pID' : np.arange(0,2*sz,2), 'Values' : np.random.random(sz)})
df2 = pd.DataFrame({'ID': np.concatenate([np.arange(sz/2),np.arange(sz/2)]), 'pid' : np.arange(0,2*sz,2), 'Values' : np.random.random(sz)})
%timeit pd.merge(df1, df2, how='left', left_on=['ID', 'pID'], right_on=['ID', 'pid'])
## 818 ms ± 33.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df1.join(df2.set_index(['ID','pid']), how='left', on=['ID','pID'], lsuffix='_x', rsuffix='_y')
## 1.04 s ± 18.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
_