2017-03-06 4 views
-1

私は2つのシステムのデータで2つのテーブルを結合しています。単純なPandas merge 2つのdfの間では、(私が間違って使用しない限り、プロセスのマージが実装されていることを理解していない - 非常に可能)より複雑なルールを尊重しません。DataFramesの行を条件ごとに行単位でマージする方が効率的です。

df1:   df2: 
    A X   B Y 
0 1 10  0 2 10 
1 5 15  1 4 15 
       2 6 15 

私は一緒に私は、itertuples 2つのDFさんを解凍値に基づいてマッチを検証し、その後、1つのデータフレームに再梱包することができますおもちゃソリューションは石畳ました。

df1 = pd.DataFrame(data1,columns=['A','X']) 
df2 = pd.DataFrame(data2,columns=['B','Y']) 
df3 = pd.DataFrame(index=['A','X','B','Y']) 
i = -1 

for rowA in df1.itertuples(index=False): 
    i += 1 
    for rowB in df2.itertuples(index=False): 
     A,X = rowA 
     B,Y = rowB 
     if (B > A) & (X==Y): 
      df3[i] = list(rowA+rowb) 
     else: 
      continue 

print(df3.transpose()) 

A X B Y 
0 1 10 2 10 
1 5 15 6 15 

私の単純なアプローチは、私はDATA1の各エントリのDATA2/DF2を反復処理していますので、ネストされたfor()ループが非効率的である

非効率的です。 data2/df2との一致が良くなると、行を削除する必要があります。

// UPDATE(私の質問の起源を表示)

私はマージ任意のキーまたは他のシリアル化されたIDを共有しない2つの独立したシステムと働いているデータのタイプの例。私は完全に一致することができないので、私は論理演算/算術演算と排除のプロセスに頼らなければなりません。

次の例では、単純なpandas.mergeがLine3で失敗します。これは、Time1 < Time2です。私は答えに推奨merge_asof()join()のいくつかの順列に働いてきた

Time1,    Total1 ... Time2,    Total2, error 
1, 2017-02-19 08:03:00, 15.00 ... 2017-02-19 08:02:00, 15.00, 0 
2, 2017-02-19 08:28:00, 33.00 ... 2017-02-19 08:27:00, 33.00, 0 
3, 2017-02-19 08:40:00, 20.00 ... NaN,     NaN, NaN 
4, 2017-02-19 10:08:00, 20.00 ... 2017-02-19 10:06:00, 20.00, 0 
[...] 

//アップデート2 :どうするか

Time1,    Total1 ... Time2,    Total2, error 
1, 2017-02-19 08:03:00, 15.00 ... 2017-02-19 08:02:00, 15.00, 0 
2, 2017-02-19 08:28:00, 33.00 ... 2017-02-19 08:27:00, 33.00, 0 
3, 2017-02-19 08:40:00, 20.00 ... 2017-02-19 10:06:00, 20.00, 1 
4, 2017-02-19 10:08:00, 20.00 ... 2017-02-19 10:16:00, 20.00, 1 
[...] 

はこのようなものです。各メソッドはドキュメントの指示に従ってソートされました。

:私が正しく、それぞれを実施してきたと仮定すると、以下の 割合は、3つの方法のそれぞれを使用して、私のテストセットで(53件のレコードのうち(時刻1> = TIME2)&(TOTAL1 == TOTAL2))ルールのTrue試合です
| type     | 'date' | 'total' | both | 
|-----------------------|----------|-----------|--------| 
| merg_asof sort (time) | .7924 | .9245  | .7169 | 
| merg_asof (time,total)| .7735 | .6981  | .6226 | 
| intertup (time,total) | .8301 | .8301  | .8301 | 
| join ind (time)  | na  | na  | na  | 

参加には共有キーが必要ですか?ドキュメント内のon句には、"他のインデックスに参加する呼び出し元の列、そうでない場合はindex-on-indexを結合します。複数の列が指定されている場合、渡されたDataFrameにはMultiIndexが必要です。

私はjoinを(時間、合計)と(時間)のマルチインデックスで試してみました。問題は、あなたが参加しているすべてのものに参加することです。それらのインデックスが1つに統合されているため、エラー解析を実行する余地はありません。

私の純粋なintertuple解決策(上記)は完璧な一致のみを生成しましたが、ソリューションでは見逃し一致のコレクタが必要です。

+0

私はこの質問を何度も読んだし、私はまだどこに理解しようとしています「トータル」のようなものが出てきます。あなたの元の(更新前の)質問があれば、私は 'pd.merge_asof(df1、df2、left_on = 'A'、right_on = 'B'、left_by = 'X'、right_by = 'Y'、allow_exact_matches = False、direction = 'forward') '。 'direction'パラメータはpandas 0.20.0になるまで出てこないので、ソースからパンダを構築するか、今のところ緊密に座る必要があります。 – chrisaycock

+0

@chrisaycock、私の素朴なアルゴリズムと上記の言い回しの元のデータとの関係を理解するには、あなたの想像力をちょっと使ってください。合計はそれだけでした - 統合されていないトランザクションシステム間で伝播する単一のトランザクションの合計。私のコードを順応しやすくするために、私はA/Bを注文し、X/Yをマッチとして選んだ。 'merge_asof()'は以前の検索では検索されませんでした。 'direction'パラメータは非常に重要で、私は' tolerance'パラメータに気づき、 'merge_asof'を解決策の大きな候補にします。より多くのテスト。 – xtian

答えて

0

df3 = df1.join(df2)はあなたが望むことをしていませんか?

+0

Nope。上記の例では、単純な結合によって(5,15)と(4,15)が与えられますが、これはルール5 <4には失敗します。 – xtian

0

私が正しくあなたのロジックを理解していた場合、これはそれを行う必要があります。

time1 = pd.to_datetime(['2/19/17 8:03:00', '2/19/17 8:28:00', '2/19/17 8:40:00', '2/19/17 10:08:00']) 
time2 = pd.to_datetime(['2/19/17 8:02:00', '2/19/17 8:27:00', '2/19/17 10:06:00', '2/19/17 10:16:00']) 

df1 = pd.DataFrame({'Time1':time1, 'Total1':[15.00, 33.00, 20.00, 20.00]}) 
df2 = pd.DataFrame({'Time2':time2, 'Total2':[15.00, 33.00, 20.00, 20.00], 'error':[0,0,1,1]}) 

df3 = pd.merge_asof(df1, df2, left_on = 'Time1', right_on = 'Time2') 
df3.loc[df3['Time2'].duplicated(), ['Time2', 'Total2', 'error']] = None 

出力:

   Time1 Total1    Time2 Total2 error 
0 2017-02-19 08:03:00 15.0 2017-02-19 08:02:00 15.0 0.0 
1 2017-02-19 08:28:00 33.0 2017-02-19 08:27:00 33.0 0.0 
2 2017-02-19 08:40:00 20.0     NaT  NaN NaN 
3 2017-02-19 10:08:00 20.0 2017-02-19 10:06:00 20.0 1.0 
+0

TLDR:審査はまだ審議中です。上記のエラーチェック結果をいくつか追加しました。 'merge_asof()'がたくさんの良いマッチをたくさん作ったのはちょっと奇妙ですが、 'time'マッチングのエラーは全体的なマッチを落としました。今日私は、各マージタイプを実行するという重い作業をしました。後でプロジェクトに戻って自分の方法を見直す必要があります。間違いがないことを確認してください。 – xtian

関連する問題