2014-01-18 19 views
16

私は2つのデータフレームを持ち、どちらも不規則な間隔のミリ秒のタイムスタンプ列を含んでいます。ここでの目標は、一致する行ごとに、1)最初のタイムスタンプが常に2番目のタイムスタンプより小さいか等しいこと、2)一致したタイムスタンプが1)を満たすタイムスタンプのすべてのペアで最も近いことです。pandas.merge:最も近いタイムスタンプと一致する> =タイムスタンプのシリーズ

pandas.mergeでこれを行う方法はありますか?

答えて

25

merge()が参加し、この種の操作を行うことはできませんが、searchsorted()使用することができます。t1t2は、昇順にあります:

import pandas as pd 
import numpy as np 
np.random.seed(0) 

base = np.array(["2013-01-01 00:00:00"], "datetime64[ns]") 

a = (np.random.rand(30)*1000000*1000).astype(np.int64)*1000000 
t1 = base + a 
t1.sort() 

b = (np.random.rand(10)*1000000*1000).astype(np.int64)*1000000 
t2 = base + b 
t2.sort() 

コールsearchsorted()見つけること

は、いくつかのランダムなタイムスタンプを作成します。 t2の各値のt1のインデックス:

idx = np.searchsorted(t1, t2) - 1 
mask = idx >= 0 

df = pd.DataFrame({"t1":t1[idx][mask], "t2":t2[mask]}) 
ここで

が出力される。

      t1       t2 
0 2013-01-02 06:49:13.287000 2013-01-03 16:29:15.612000 
1 2013-01-05 16:33:07.211000 2013-01-05 21:42:30.332000 
2 2013-01-07 04:47:24.561000 2013-01-07 04:53:53.948000 
3 2013-01-07 14:26:03.376000 2013-01-07 17:01:35.722000 
4 2013-01-07 14:26:03.376000 2013-01-07 18:22:13.996000 
5 2013-01-07 14:26:03.376000 2013-01-07 18:33:55.497000 
6 2013-01-08 02:24:54.113000 2013-01-08 12:23:40.299000 
7 2013-01-08 21:39:49.366000 2013-01-09 14:03:53.689000 
8 2013-01-11 08:06:36.638000 2013-01-11 13:09:08.078000 

グラフにより、この結果を表示する:

import pylab as pl 
pl.figure(figsize=(18, 4)) 
pl.vlines(pd.Series(t1), 0, 1, colors="g", lw=1) 
pl.vlines(df.t1, 0.3, 0.7, colors="r", lw=2) 
pl.vlines(df.t2, 0.3, 0.7, colors="b", lw=2) 
pl.margins(0.02) 

出力:

enter image description here

緑の線はt1あり、青い線は、t2あります赤い線はt2ごとにt1から選択されます。

3

私はHYRYとは異なる方法を使用:

  1. は、外側(方法=「外」)に参加して定期的にマージを行います。
  2. 日付でソートします。
  3. fillna(method = 'pad')を使用して必要な列だけを入力し、前の行を入力する場合は 'pad'を使用します。
  4. 外部結合から不要な行をすべて削除します。

このすべては数行で記述することができます:ここでは

df=pd.merge(df0, df1, on='Date', how='outer') 
df=df.sort(['Date'], ascending=[1]) 
headertofill=list(df1.columns.values) 
df[headertofill]=df[headertofill].fillna(method='pad') 
df=df[pd.isnull(df[var_from_df0_only])==False] 
+0

あなたは – Pigeon

+0

が何であるかをvar_from_df0_only定義していないハイピジョン、あなたは元のデータフレーム(DF0)に維持し、それを豊かにしたい倍の大半別のもの(df1)。外部結合を使用すると、df1からいくつかの余分な行があるので、それらを削除するには、df0にある1つの列を使用しますが、df1( "var_from_df0_only"外部結合には余分な行のためのヌル値があります。 – Yaron

+0

Pandas sort()は推奨されていません。代わりにsort_values()を使用する必要があります –

2

は、より簡単で一般的な方法です。

# data and signal are want we want to merge 
keys = ['channel', 'timestamp'] # Could be simply ['timestamp'] 
index = data.loc[keys].set_index(keys).index # Make index from columns to merge on 
padded = signal.reindex(index, method='pad') # Key step -- reindex with filling 
joined = data.join(padded, on=keys) # Join to data if needed 
0

パンダは今まさにやっ機能merge_asofを持っているこの

関連する問題