2017-08-27 9 views
0

私は、データの有効期間を示すdate_fromdate_toという2つのデータフレームと、どのデータが一緒に属しているのかを示すidを持っています。Pythonで日付間隔のデータをマージしました

from datetime import datetime 
import pandas as pd 
import numpy as np 

df_a = pd.DataFrame({'id' : [1, 1, 1, 1, 2], 
        'date_from' : [datetime(2012, 1, 1), datetime(2012, 6, 1), 
            datetime(2013, 1, 1), datetime(2013, 6, 1), 
            datetime(2012, 1, 1)], 
        'date_to' : [datetime(2012, 6, 1), datetime(2013, 1, 1), 
            datetime(2013, 6, 1), datetime(2014, 1, 1), 
            datetime(2013, 1, 1)], 
        'data_a' : [1, 2, 3, 4, 5]}) 

df_b = pd.DataFrame({'id' : [1, 1], 
        'date_from' : [datetime(2012, 8, 1), datetime(2013, 4,1)], 
        'date_to' : [datetime(2013, 4,1), datetime(2013, 8, 1)], 
        'data_b' :['A','B']}) 

私はインナーを行う場合 が新しいdate_toとしてS「のdate_toの新しいdate_fromとminとS」のdate_fromの最大を使用して、これら2つの表の結合、およびkeppingエントリのみどこdate_from < date_to、私は正しい間隔で欲しい結果を得る。

df = pd.merge(df_a, df_b, suffixes=['_a','_b'],on='id', how='inner') 
df['date_from'] = df[['date_from_a', 'date_from_b']].max(axis=1) 
df['date_to'] = df[['date_to_a', 'date_to_b']].min(axis=1) 
df[['id', 'date_from', 'date_to', 'data_a','data_b']][(df['date_from']<df['date_to'])] 

Out[2]: 
    id date_from date_to data_a data_b 
2 1 2012-08-01 2013-01-01  2  A 
4 1 2013-01-01 2013-04-01  3  A 
5 1 2013-04-01 2013-06-01  3  B 
7 1 2013-06-01 2013-08-01  4  B 

ハレイ!

しかし、今では難しい部分が出てきます。私は実際に内部結合を望んでいません。左結合が欲しいです。あなたがよく事は、私は何の重複区間が存在しない場合にもdf_aからのデータを持っていたいです...何と言うこの絵と間違っている私は

df = pd.merge(df_a, df_b, suffixes=['_a','_b'],on='id', how='left') 
df['date_from'] = df[['date_from_a', 'date_from_b']].max(axis=1) 
df['date_to'] = df[['date_to_a', 'date_to_b']].min(axis=1) 
df[['id', 'date_from', 'date_to', 'data_a','data_b']][(df['date_from']<df['date_to'])] 
Out[3]: 
    id date_from date_to data_a data_b 
2 1 2012-08-01 2013-01-01  2  A 
4 1 2013-01-01 2013-04-01  3  A 
5 1 2013-04-01 2013-06-01  3  B 
7 1 2013-06-01 2013-08-01  4  B 
8 2 2012-01-01 2013-01-01  5 NaN 

を得る左マージして上記の手順を繰り返します。基本的に私はこの結果が欲しい

id date_from date_to data_a data_b 
0 1 2012-01-01 2012-06-01  1 NaN 
1 1 2012-06-01 2012-08-01  2 NaN 
2 1 2012-08-01 2013-01-01  2  A 
3 1 2013-01-01 2013-04-01  3  A 
4 1 2013-04-01 2013-06-01  3  B 
5 1 2013-06-01 2013-08-01  4  B 
6 1 2013-08-01 2014-01-01  4 NaN 
7 2 2012-01-01 2013-01-01  5 NaN 

私はこの結果をplain SQLを使って生成できません。私が知っている可能性のある解決策の1つは、データの前後に空白の間隔を入れて「パディング」することです(df_b)。しかし、それ自体の問題がありますので、私はdf_bを改ざんしないようにしたいと思います。

すべてのご協力をいただきありがとうございます。ありがとうございました。参加しDATE_FROM DATE_TO変数、所望の効果を持った後、あなたがしている参加の種類「をシミュレートする」シンプルなラインで追加した後

+1

こんにちは、私はあなたのための解決策があると思いますが、投稿する前に "結果"データフレームが正しいことを確認できますか?私はid == 1の余分な行がなくなっていると思うし、data_bの場合、AとBの位置はインデックスが3,4,5,6の位置にあり、インデックスが[0,1、 3,6]。基本的に、最初の2つのデータフレームでは、AとBは2,4,5,7の行にありますが、結果のデータフレームに3,4,5,6があります。 – tompiler

+0

こんにちは!あなたは素晴らしいだろう解決策がある場合! :)インデックスについて心配しないでください。私はちょうど実際にそれを考えずにそこに何かを置く。 – mortysporty

答えて

0

:それは言っている

df.loc[(df['date_from']<df['date_to']), 'data_b'] = np.NaN 

"date_fromdate_toより小さい場合は、data_bをnullに設定してください。"

次に、idがdf_bの共通キーを持たない行を削除する最後の行の制約を削除します。これは、2つのデータセットを初期化した後の最終コードです。

df = pd.merge(df_a, df_b, suffixes=['_a','_b'],on='id', how='left') 
df['date_from'] = df[['date_from_a', 'date_from_b']].max(axis=1) 
df['date_to'] = df[['date_to_a', 'date_to_b']].min(axis=1) 
df.loc[(df['date_from']<df['date_to']), 'data_b'] = np.NaN 
df[['id', 'date_from', 'date_to', 'data_a','data_b']] 

希望の結果が得られない場合はお知らせください。

+0

Hmmm。私はそれを動作させるように見えることはできません...あなたのコードで 'df_a'と' df_b'を初期化する以外は、すべてのコードを置き換えました。私が望んでいるものを私に与えているわけではありません。どういうわけか私たちは正しい軌道に乗っていると思っていますが、ある種のバグがあります。 – mortysporty

+0

運がいいですか?あなたは残りの問題についてより具体的になりますか? – tompiler

+0

ええええええええ、運がいいです。あなたのソリューションが単に私が望む結果を生み出さないと言って申し訳ありません:|これはあなたのコードを貼り付けるコピーです。[8]: id date_from date_to data_a data_b 0 1 2012-08-01 2012-06-01 1 A 1 1 2013-04-01 2012-06-01 1 B 2 1 2012-08-01 2013-01-01 2 NaN 3 1 2013-04-01 2013-01-01 2 B 4 1 2013-01-01 2013-04-01 3 NaN 5 1 2013 -04-01 2013-06-01 3 NaN 6 1 2013-06-01 2013-04-01 4 A 7 1 2013-06-01 2013-08-01 4 NaN 8 2 2012-01-01 2013 -01-01 5 NaN' – mortysporty

関連する問題