2016-12-21 10 views
4

私は2つのデータフレームを持っています。パンダ:2つのデータフレーム間で情報を接続

Id Name  StartTime   EndTime 
0 201 Car1 2016-01-01 00:00:00 2016-01-01 00:43:05 
1 205 Car2 2016-01-01 00:10:00 2016-01-01 00:45:05 
2 345 Car3 2016-01-01 00:01:00 2016-01-01 00:47:05 
3 456 Car2 2016-01-02 00:00:00 2016-01-02 02:45:05 
4 432 Car1 2016-01-02 00:00:00 2016-01-02 02:47:05 

(GPSなど)旅行中のタイムスタンプが含まれていBデータフレーム:データフレームAは、旅行に関する情報が含まれています。

Name Timestamp 
0 Car1 2016-01-01 00:05:00 
1 Car1 2016-01-01 00:05:24 
2 Car2 2016-01-01 00:10:04 
3 Car3 2016-01-01 00:01:04 
4 Car2 2016-01-01 00:10:34 
5 Car1 2016-01-01 00:05:54 

私は名前とフレームAで開始と終了時間に基づいてデータフレームAからIDをピックアップId呼ばDATAFRAME Bに列を追加する必要があります。これらの両方のデータフレームは非常に大きいので、効率的な方法が必要です。

答えて

1

これは最近merge_asofを追加しましたため、状況のように見えます。すなわち、左側のデータフレーム(ここではデータフレームB)を受け取り、以下行い左データフレームの行ごとに

は、我々は、そのキー「オン」以下である 正しいデータフレームの最後の行を選択します左の キー。両方のDataFramesをキーでソートする必要があります。

は、我々は、タイムスタンプデータを持っていることを確認し

dfa['StartTime'] = pd.to_datetime(dfa.StartTime) 
dfa['EndTime'] = pd.to_datetime(dfa.EndTime) 
dfb['Timestamp'] = pd.to_datetime(dfb.Timestamp) 

次にソート結合列

dfb = dfb.sort_values('Timestamp') 
dfa = dfa.sort_values('StartTime') 
Perfomがasof '名前'

pd.merge_asof(dfb, dfa, left_on='Timestamp', right_on='StartTime', by='Name') 

出力によってマージ

Name   Timestamp Id   StartTime    EndTime 
0 Car3 2016-01-01 00:01:04 345 2016-01-01 00:01:00 2016-01-01 00:47:05 
1 Car1 2016-01-01 00:05:00 201 2016-01-01 00:00:00 2016-01-01 00:43:05 
2 Car1 2016-01-01 00:05:24 201 2016-01-01 00:00:00 2016-01-01 00:43:05 
3 Car1 2016-01-01 00:05:54 201 2016-01-01 00:00:00 2016-01-01 00:43:05 
4 Car2 2016-01-01 00:10:04 205 2016-01-01 00:10:00 2016-01-01 00:45:05 
5 Car2 2016-01-01 00:10:34 205 2016-01-01 00:10:00 2016-01-01 00:45:05 
+0

返事をありがとう。私は最新のバージョンを持っていないようで、それを更新するのは簡単ではありません。 merge_asofを使用せずにこれを行う別の方法がありますか? – Amit

+0

pandasには条件付き結合がありません。あなたは@ jezraelの答えを使用しなければならないでしょうが、多くの場合実現不可能です。これはあなたのような状況のためにmerge_asofが構築された理由です。これは、マージよりもはるかに速く、そしてフィルタリングします。私はあなたの最善の策はパンダを更新することだと思います。あなたが簡単にpandasを更新できない場合は、pydataツールのように速く動く開発では非常に重要なので、これを可能にする環境を見つける必要があります。 –

1

私はあなたが外でmergedropによってboolean indexing、最後の削除列でフィルタリングした後、列Nameに参加する必要があると思う:

df = pd.merge(df1, df2, on='Name', how='outer') 
df = df[(df.StartTime <= df.Timestamp) & (df.EndTime >= df.Timestamp)] 
df = df.drop(['StartTime','EndTime'], axis=1) 
print (df) 
    Id Name   Timestamp 
0 201 Car1 2016-01-01 00:05:00 
1 201 Car1 2016-01-01 00:05:24 
2 201 Car1 2016-01-01 00:05:54 
6 205 Car2 2016-01-01 00:10:04 
7 205 Car2 2016-01-01 00:10:34 
10 345 Car3 2016-01-01 00:01:04 
+0

この回答は本当に目的を果たしています。しかし、それをベンチマークしましたか?どれくらい早いですか?それは効率性の必要性があることが明らかに元の記事で明確に言及されています。どう思いますか? – SRC

+0

残念ながら、それほど速くはありません。速ければ別の答えをテストしてください。 – jezrael

関連する問題