私は、データの有効期間を示すdate_from
とdate_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変数、所望の効果を持った後、あなたがしている参加の種類「をシミュレートする」シンプルなラインで追加した後
こんにちは、私はあなたのための解決策があると思いますが、投稿する前に "結果"データフレームが正しいことを確認できますか?私は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
こんにちは!あなたは素晴らしいだろう解決策がある場合! :)インデックスについて心配しないでください。私はちょうど実際にそれを考えずにそこに何かを置く。 – mortysporty