2017-12-06 1 views
2

に基づいてパンダに参加。問題は、列の値の1つを補間したいということです。私は2列に基づいて2つのデータフレームに参加しようとしている列補間

df1 = pd.DataFrame(data=[['ABC', 'USD', 2.31], ['DEF', 'MXN', 4.72], ['XYZ', 'EUR', 5.83]], columns=['A', 'B', 'C']) 
>>df1 
    A B  C 
0 ABC USD 2.31 
1 DEF MXN 4.72 
2 XYZ EUR 5.83 

df2 = pd.DataFrame(data=[['USD', 1, 0.5], ['USD', 2, 0.8], ['USD', 3, 1.5], ['MXN', 2, 0.6], ['MXN', 3, 0.71], ['MXN', 4, 0.88], ['EUR', 6, 0.12], ['EUR', 7, 0.5], ['EUR', 8, 0.7]], columns=['B', 'C', 'V']) 
>>df2 
    B C  V 
0 USD 1 0.50 
1 USD 2 0.80 
2 USD 3 1.50 
3 MXN 2 0.60 
4 MXN 3 0.71 
5 MXN 4 0.88 
6 EUR 6 0.12 
7 EUR 7 0.50 
8 EUR 8 0.70 

I、列BおよびCに基づいて、2つのデータフレームを結合したいような私は、次の結果を得ること

 A B  C  V 
0 ABC USD 2.31 1.017 
1 DEF MXN 4.72 0.880 
2 XYZ EUR 5.83 0.120 

補間は線形であり、場合範囲外の最も近いポイントを使用し。

最初の値

1.017=0.8+(2.31-2)*(1.5-0.8) 

MXNはDF2に有する最大値が0.6

あるため、第2の値は第3の値は、同様に0.12

あるEURの最大値であり、あります

目的は、データフレームが非常に大きいので、これをできるだけ効率的に行うことです。

は、今のところ、私はBによってグループ化し、scipyのダウンロード補間機能を使用しています。

+0

これは私の現在のアプローチである - 'ccy_dict = {CCY:interp1d(DF [ 'C']、[ 'V'] DF、bounds_error = Falseを、 fill_value =([ 'V'] DF。 ccy_df.groupby( 'B')}のccy、dfの場合は の後に- のdf1 ['V'] = df1が続きます(iloc [0]、df ['V'] iloc [-1]))。ありがとう、これは素晴らしい解決策です!lambda x:ccy_dict [x ['B']](x ['C'])、axis = 1) –

答えて

1

ここで私はあなたがおそらく補間ステップのためにscipy.interpolateで適用を使用することによって、これを改善することができると思いますけれども、私が思いついた解決策です。まず、df1の床、天井、およびデルタの列を作成します。

enter df1['C_floor'] = df1.C.apply(np.floor) 
df1['C_ceil'] = df1.C.apply(np.ceil) 
df1['C_delta'] = df1.C - df1.C_floor 

は、二重左がdf2からCの床と天井に対応V得るために参加してください。私はあなたが高速なコードを作ることができると思うところ

df1 = df1.merge(df2, how ='left', left_on = ['B', 'C_floor'], right_on = ['B', 'C']) 
df1 = df1.merge(df2, how ='left', left_on = ['B', 'C_ceil'], right_on = ['B', 'C']) 

はここですが、私はCdf2で利用可能な範囲外の場合の加重平均と、アカウントを見つけるために、簡単な関数を書きました。

def weighted_mean(x): 
    if np.isnan(x.V_x): 
     return x.V_y 
    elif np.isnan(x.V_y): 
     return x.V_x 
    else: 
     return x.V_y + (x.V_x - x.V_y) * x.C_delta 

df1['V'] = df1[['V_x', 'V_y', 'C_delta']].apply(weighted_mean, axis = 1) 

最後にクリーンアップ。

df1 = df1[['A', 'B', 'C_x', 'V']] 
df1.columns = ['A', 'B', 'C', 'V'] 

となる。

 A B  C  V 
0 ABC USD 2.31 1.283 
1 DEF MXN 4.72 0.880 
2 XYZ EUR 5.83 0.120 
+0

この時私のために働く。唯一の問題は、列** C **が浮動小数点数の場合でも機能しないことです。 –

+0

等間隔のフロートで、間隔が一定の場合はgです。 10.1,10.2などのように 'C'列に' 10 '(または任意の数)を掛けて 'int'としてキャストし、' ceil'と 'floor'関数を丸めて適切な間隔に設定します。間隔が均等に間隔を置かれていない場合は、挑戦的で何か別の問題がありますか? – doktakay

関連する問題