如何将参数与Pandas数据帧的每一行中的单独列进行比较?

时间:2017-02-09 21:01:12

标签: python pandas dataframe

我有一个DataFrame,其中包含事件ID,开始时间和结束时间:

In []: dwells[['Event ID','Start Time','Stop Time']].head()
Out[]: 
    Event ID          Start Time           Stop Time
0  367067960 2016-09-01 00:05:00 2016-10-05 14:00:00
1  311288000 2016-09-01 00:05:00 2016-09-01 23:30:00
2  636016999 2016-09-01 00:05:00 2016-09-01 01:50:00
3  247304600 2016-09-01 01:20:00 2016-09-01 21:25:00
4  636016590 2016-09-01 06:55:00 2016-09-01 23:35:00

In []: dwells[['Event ID','Start Time','Stop Time']].dtypes
Out[]: 
Event ID               int64
Start Time    datetime64[ns]
Stop Time     datetime64[ns]
dtype: object

我试图确定每5分钟频率的DateTimeIndex增量发生的事件数。最后我想知道事件的数量和事件发生的累积时间(通过乘以事件的数量和时间步长并取得积累):

In []: start = datetime(2016,9,1)
  ...: end = datetime(2016,12,31)
  ...: rng = pd.date_range(start, end, freq='5min')
  ...: rng[:5]

Out[]: 
DatetimeIndex(['2016-09-01 00:00:00', '2016-09-01 00:05:00',
               '2016-09-01 00:10:00', '2016-09-01 00:15:00',
               '2016-09-01 00:20:00'],
              dtype='datetime64[ns]', freq='5T')

我想遍历DateTimeIndex并将每个条目与开始时间和停止时间进行比较以查看它是否在它们之间,在新的FLAG字段中设置适当的变量。然后我可以将FLAG字段求和并将其设置为以rng作为索引的系列的值,如:

series = pd.Series(index=rng)
for x in rng:
    dwells['FLAG'] = dwells[['Start Time', 'Stop Time']].apply(lambda i,j: 1 if i.value <= x.value <= j.value else 0)
    series.loc[x] = dwells['FLAG'].sum()

这个应用功能不起作用。我还没有能够提出一个功能,让我可以检查x值与每一行的时间范围。

我很感激帮助定义一个函数,它给我一个输出:

In []: series[:5]
Out[]:
2016-09-01 00:00:00   37
2016-09-01 00:05:00   39
2016-09-01 00:10:00   40
2016-09-01 00:15:00   39
2016-09-01 00:20:00   35

如果有更有效的方法来解决这个问题,我也会很感激。

1 个答案:

答案 0 :(得分:0)

我在这篇文章中找到了一个很好的起点:python pandas: apply a function with arguments to a series

这让我看到了关于定义一个自定义函数的文档,其中关键字参数应用于系列,在这里:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.apply.html#pandas.Series.apply

由于DF行是一个系列,我写了以下内容:

def flag_events(row, **kwargs):
    '''Applied row-wise to a DF, checks if kwargs['t_step'] is between 'Start Time' and 'Stop Time', returning 1 if yes and 0 if no'''
    if row['Start Time'].value <= kwargs['t_step'] <= row['Stop Time'].value:
         return 1
    else:
        return 0

DwellTable = pd.DataFrame(index=rng)

DwellTable['VesselCount'] = DwellTable.index.map(lambda x: dwells.apply(flag_events, t_step=x.value, axis=1).sum())

DwellTable['DwellMin'] = DwellTable['EventCount']*5
DwellTable['DwellMinCum'] = DwellTable['DwellMin'].cumsum()

这很有用,但运行需要很长时间。我仍然赞赏有关更有效方法的建议。