2016-07-20 4 views
1

に基づいて、私は次のようになりますデータフレームを持っています。合計日時の違いは、列値

field 1およびfield 2は、タプル(field1,field2)が世界のどこかの特定のセンサーに対応するように項目を識別するために使用されます。 field 3は、その時点のそのセンサーの値であり、値0または1のいずれかをとります。

私はグループにデータフレームを(field1、field2)とし、各センサーが各値だから、フィールド3から、t1='2016-07-20 00:00:00'場合とt2='2016-07-20 00:01:00'、現在の時刻が'2016-07-20 00:03:00'で、私がどのように見える新しいデータフレームだろう:

  field3=0 field3=1 
(1,1)   2 min  1 min 
(2,3)   ...   ... 
(3,3)   ...   ... 
(1,2)   ...   ... 

を私は、t1からt2に、field3の値が1であると仮定しますt2以降は、(1,1)がデータフレームに再び表示されないため、0になります。 1 mint2 - t1からのものであり、2 minは、以下のいずれかの形式(何も合計分/秒で、timedelta、またはことが)

私が試したことができcurrent_time - t2

2 min1 minからです。

import pandas as pd 
from collections import defaultdict, namedtuple 

# so i can create a defaultdict(Field3) and save some logic 
class Field3(object): 
    def __init__(self): 
      self.zero= pd.Timedelta('0 days') 
      self.one = pd.Timedelta('0 days') 

# used to map to field3 in a dictionary 
Sensor = namedtuple('Sensor','field1 field2') 

# the dataframe mentioned above 
df = pd.DataFrame(...) 

# iterate through each row of the dataframe and map from (field1,field2) to 
# field3, adding time based on the value of field3 in the frame and the 
# time difference between this row and the next 
rows = list(df.iterrows()) 
sensor_to_field3 = defaultdict(Field3) 
for i in xrange(len(rows)-1): 
     sensor = Sensor(field1=rows[i][1][0],field2=rows[i][1][1]) 
     if rows[i][1][2]: sensor_to_field3[spot].one += rows[i+1][0]-rows[i][0] 
     else: spot_to_status[spot].zero += rows[i+1][0]-rows[i][0] 
spot_to_status = {k:[v] for k,v in sensor_to_field3.iteritems()} 
result = pd.DataFrame(sensor_to_field3,index=[0]) 

私は基本的には私を得ていますが(現在のところ、この問題を解決するより良い方法があれば、本当に対処しなければならないテーブル全体に単一のセンサーが表示されている場合にのみ動作します) 。

これについてもっと良い方法があるように感じます。何かのグループウェアをfield1,field2にしてから、field3timeというインデックスに基づいてtimedeltasを集計しますが、その方法についてはわかりません。

答えて

0

他の誰かが遠隔的に同様のものに遭遇した場合に備えて、それを手に入れてください。それが最適かどうかまだ分かりませんが、私がやっていたことよりも良い感じです。

元のデータフレームを変更して時刻を列として含め、整数インデックスを使用しました。

def create_time_deltas(dataframe): 
    # add a timedelta column 
    dataframe['timedelta'] = pd.Timedelta(minutes=0) 
    # iterate over each row and set the timedelta to the difference of the next one and this one 
    for i in dataframe.index[:-1]: 
      dataframe.set_value(i,'timedelta',dataframe.loc[i+1,'time']dataframe.loc[i,'time']) 
    # set the last time value, which couldn't be set earlier because index out of bounds 
    dataframe.set_value(i+1,'timedelta',pd.to_datetime(datetime.now())-dataframe.loc[i,'time']) 
    return dataframe 

def group_by_field3_time(dataframe, start=None, stop=None): 
    # optionally set time bounds on what to care about 
    stop = stop or pd.to_datetime(datetime.now()) 
    recent = dataframe.loc[logical_and(start < df['time'] , df['time'] < stop)] 
    # groupby and apply to create a new dataframe with the time_deltas column 
    by_td = df.groupby(['field1','field2']).apply(create_time_deltas) 
    # sum the timedeltas for each triple, which can be used later 
    by_oc = by_td.groupby(['field1','field2','field3']).sum() 
    return by_oc 

誰もがこれを行うには良い方法を考えることができれば、私はすべての耳だけど、これはあらゆる場所に辞書を作成するよりもずっと良い感じません。

関連する問題