2017-06-22 10 views
1

パンダ両方データフレームに重複範囲によってマージ

import pandas as pd 
a=pd.DataFrame({' ID':[1,1,2,2],'a.A':[1,5,10,15],'a.B':[3,8,13,18]}) 
b=pd.DataFrame({' ID':[1,1,2,2],'b.A':[2,2,14,18],'b.B':[3,2,15,20]}) 
a 
    ID a.A  a.B 
0 1  1  3 
1 1  5  8 
2 2  10 13 
3 2  15 18 

b 
    ID b.A  b.B 
0 1  2  3 
1 1  2  2 
2 2  14 15 
3 2  18 20 

Iはa.Bにaの化合物。表の範囲は、与えられたID番号のb.Bにb.Aのそれと重なる場所にBを結合左する必要があります。論理は次のようにも説明できます: IDがaとbの間で一致する場合、(a.A < = b.Aとa.B> = b.A)または(a.A < = b.Bとa.B> = b.B)の場合は一致します。

最終的な結果は次のようになります。

ID a.A  a.B b.A b.B 
0 1  1  3  2  3 
1 1  1  3  2  2 
2 1  5  8   
3 2  10  13   
4 2  15  18 18  20 
5 2  15  18 18  20 

感謝を事前に!

+0

をそれが正しい出力ですか?私はライン4については分かりません。私の答えを見てください。 –

答えて

1
import pandas as pd 
import numpy as np 
a=pd.DataFrame({' ID':[1,1,2,2],'a.A':[1,5,10,15],'a.B':[3,8,13,18]}) 
b=pd.DataFrame({' ID':[1,1,2,2],'b.A':[2,2,14,18],'b.B':[3,2,15,20]}) 

c = a.merge(b, on=' ID', how='left') 
range_overlaps = (
    ((c['a.A'] <= c['b.A']) & (c['a.B'] >= c['b.A'])) | 
    ((c['a.A'] <= c['b.B']) & (c['a.B'] >= c['b.B'])) 
) 
c.loc[~range_overlaps, ['b.A', 'b.B']] = np.nan 
c = c.drop_duplicates() 
c = c.reset_index(drop=True) 

print(c) 

ができます:

ID a.A a.B b.A b.B 
0 1 1 3 2.0 3.0 
1 1 1 3 2.0 2.0 
2 1 5 8 NaN NaN 
3 2 10 13 NaN NaN 
4 2 15 18 14.0 15.0 
5 2 15 18 18.0 20.0 
+0

どちらも素晴らしい回答です。私はb.Aをドロップする可能性があります。ここでは、両方の列で同じ数値を持つ複数の一致がある場合にNaNを使って重複を削除します。あなたのおかげです。 –

2

ない、これが最善の解決策ですが、それは良いスタートできることを確認:cため

import pandas as pd 
a=pd.DataFrame({' ID':[1,1,2,2],'a.A':[1,5,10,15],'a.B':[3,8,13,18]}) 
b=pd.DataFrame({' ID':[1,1,2,2],'b.A':[2,2,14,18],'b.B':[3,2,15,20]}) 

c = a.merge(b) 
cbAB = (c["a.A"] <= c["b.A"]) & (c["a.B"] >= c["b.A"]) | (c["a.A"] <= c["b.B"]) & (c["a.B"] >= c["b.B"]) 
cb = c[["b.A","b.B"]] 
cb = cb[cbAB] 
c[["b.A","b.B"]] = cb 

c = c.drop_duplicates() 

出力は次のとおりです。

>>> c 
    ID a.A a.B b.A b.B 
0 1 1 3 2 3 
1 1 1 3 2 2 
2 1 5 8 NaN NaN 
4 2 10 13 NaN NaN 
6 2 15 18 14 15 
7 2 15 18 18 20 
関連する問題