2017-01-15 5 views
2

Dateによってインデックス化された2つのDataFrameがあり、1つのDataFrame上で、変更された別の1つの時間枠は毎時変更されます(5分ごとに変更されることもあります)。Pandasは適切な時間に値を追加します

>>> print df2['value'] 
date 
2015-10-06 09:00:00 0.612303 
2015-10-06 10:00:00 0.482605 
2015-10-06 11:00:00 0.604132 

>>> print df1['value'] 
date 
2015-10-06 09:05:00 0.412303 
2015-10-06 09:08:00 0.112303 
2015-10-06 09:28:00 0.
2015-10-06 10:15:00 0.000005 
2015-10-06 11:00:00 0.133132 

Iは時間hとH + 1の間であるdf1値が対応df2値を持ちたいです。

募集結果:

>>> print df1['value'] 
date 
2015-10-06 09:05:00 0.612303 
2015-10-06 09:08:00 0.612303 
2015-10-06 09:28:00 0.612303 
2015-10-06 10:15:00 0.482605 
2015-10-06 11:00:00 0.604132 

どのように私はこれを達成することができますか?

+1

['merge_asof'](http://pandas.pydata.org/pandas-docs/stable/merging.html#merging-asof)がこの目的のために存在します。 –

+0

@ajcr私の問題を解決しました。ありがとう、私が受け入れる答えを書いてみたいですか? –

+0

以下の 'merge_asof'を使って答えを追加しました。詳細を知りたい場合はお知らせください。 –

答えて

4

あなたはDatetimeIndexとあなたの例の値の正しい列を生成するmerge_asofを使用することができます。

pd.merge_asof(df1.reset_index(), # see note about reset_index below 
       df2.reset_index(), 
       on='date', 
       tolerance=pd.Timedelta('1H')) 

の公差パラメータを使用すると、特定の時間の後にどのくらいまで指定することができますマージは有効である必要があります。たとえば、tolerance=pd.Timedelta('10m')(10分)を指定した場合、すべての値がマージされるわけではなく、一部の場所にはNaNと表示されます。


マージする前に2つのフレームのインデックスをリセットしなければならなかったことに注意してください。 left_index=Trueright_index=Trueを使って結合しようとしましたが、pandasは許容範囲のパラメータを渡すときにこれを許可しません(これはバグかもしれません - 変更された場合はここでmerge_asofを使ってください)。

+1

FWIW私は[GitHub](https://github.com/pandas/dev/pandas/issues/15135) –

+2

...と[バグ修正](https://github.com/)で問題を開いたpandas-dev/pandas/pull/15139)がマスターにマージされました。パンダの次のリリースで修正する必要があります。 –

0

インデックスで の新しい列「hourly」を作成します。次に、この新しい作成された列のdf1とdf2を結合して、df2から値を追加します。

はできるだけ早くコードを掲載します:)

EDITを:約束どおり、ここではコードパンダバージョン0.19.0以上の場合

import pandas as pd 
from datetime import datetime 

df1 = pd.read_csv("df1.csv",index_col="date", parse_dates=True) 
df2 = pd.read_csv("df2.csv",index_col="date", parse_dates=True) 


def fromTimeStampToHour(date): 
    datetimeObj = date.to_datetime() 
    hourlyObj = datetime(year=datetimeObj.year,month= datetimeObj.month, day = datetimeObj.day, hour=datetimeObj.hour) 
    return hourlyObj 

df1["Hours"] = df1.index.map(lambda x: fromTimeStampToHour(x)) 

print pd.merge(left=df1, right=df2, left_on="Hours", right_index=True, suffixes=("_df1", "_df2")) 
1

ajcr's answerを参照してくださいです。


パンダバージョンの場合

< 0.19.0:

:あなたは将来を埋めるためにはNaNが所望の値と値、およびそれらの値と、その後 update df1 ffillを使用し、 concatで、2つのデータフレームを組み合わせることができ
import pandas as pd 
df2 = pd.DataFrame({'value':[0.612303,0.482605,0.604132]}, index=pd.DatetimeIndex(['2015-10-06 09:00:00', '2015-10-06 10:00:00', '2015-10-06 11:00:00'])) 
df1 = pd.DataFrame({'value':[0.412303, 0.112303, 0., 0.000005, 0.133132]}, index=pd.DatetimeIndex(['2015-10-06 09:05:00', '2015-10-06 09:08:00', '2015-10-06 09:28:00', '2015-10-06 10:15:00', '2015-10-06 11:00:00'])) 

df1.update(pd.concat([df1, df2], axis=1).ffill().iloc[:, 1]) 
print(df1) 

利回り

     value 
2015-10-06 09:05:00 0.612303 
2015-10-06 09:08:00 0.612303 
2015-10-06 09:28:00 0.612303 
2015-10-06 10:15:00 0.482605 
2015-10-06 11:00:00 0.604132 

df2.indexがソート順にすでにあることを前提としていることを

import pandas as pd 
df2 = pd.DataFrame({'value':[0.612303,0.482605,0.604132]}, index=pd.DatetimeIndex(['2015-10-06 09:00:00', '2015-10-06 10:00:00', '2015-10-06 11:00:00'])) 
df1 = pd.DataFrame({'value':[0.412303, 0.112303, 0., 0.000005, 0.133132]}, index=pd.DatetimeIndex(['2015-10-06 09:05:00', '2015-10-06 09:08:00', '2015-10-06 09:28:00', '2015-10-06 10:15:00', '2015-10-06 11:00:00'])) 

df1['value'] = df2.iloc[df2.index.searchsorted(df1.index, side='right')-1].values 
print(df1) 

利回り

     value 
2015-10-06 09:05:00 0.612303 
2015-10-06 09:08:00 0.612303 
2015-10-06 09:28:00 0.612303 
2015-10-06 10:15:00 0.482605 
2015-10-06 11:00:00 0.604132 

注:

また、あなたはdf1.indexdf2.indexに収まる場所を示す指標値を見つけるためにsearchsortedを使用することができます。そうでない場合は、最初にdf2 = df2.sort_index()を使用してください。 DatatimeIndexでソート ために、df1.index及び/又はdf2.indexがソート順でない場合でも、データフレームを返しpd.concat対照的に、

。したがって、最初のメソッドはsort_indexを呼び出す必要はありません。


searchsortedの方が高速です。たとえば、この設定では、

import numpy as np 
import pandas as pd 
N = 1000 
df1 = pd.DataFrame(np.random.random(N), index=pd.date_range('2000-1-1', periods=N, freq='14T')) 
df2 = pd.DataFrame(np.random.random(int(N/60*14)), index=pd.date_range('2000-1-1', periods=int(N/60*14), freq='1H')) 
df3, df4 = df1.copy(), df1.copy() 

df3.update(pd.concat([df3, df2], axis=1).ffill().iloc[:, 1]) 
df4[0] = df2.iloc[df2.index.searchsorted(df4.index, side='right')-1].values 
assert df3.equals(df4) 

searchsortedは〜2です。8倍高速化:

In [88]: %timeit df3.update(pd.concat([df3, df2], axis=1).ffill().iloc[:, 1]) 
100 loops, best of 3: 2.13 ms per loop 

In [89]: %timeit df4[0] = df2.iloc[df2.index.searchsorted(df4.index, side='right')-1].values 
1000 loops, best of 3: 744 µs per loop 

In [90]: len(df1), len(df2) 
Out[90]: (1000, 233) 
関連する問題