【问题标题】:Calculating the duration an event in a time series data frame (python 2.7)计算时间序列数据框中事件的持续时间(python 2.7)
【发布时间】:2013-11-27 13:16:51
【问题描述】:

我有一个相当大的 pandas 数据框,它是一个时间序列,每个时间戳都有很多不同的信息(眼动追踪数据)。

部分数据看起来有点像:

In [58]: df
Out[58]:
    time    event
49  44295   NaN
50  44311   NaN
51  44328   NaN
52  44345   2
53  44361   2
54  44378   2
55  44395   2
56  44411   2
57  44428   3
58  44445   3
59  44461   3
60  44478   3 
61  44495   NaN
62  44511   NaN
63  44528   NaN
64  44544   NaN  
65  44561   NaN
66  44578   NaN
67  44594   NaN
68  44611   4
69  44628   4
70  44644   4
71  44661   NaN
72  44678   NaN

我想将每个事件的(时间)持续时间计算为给定事件的最大(时间)-最小(时间),例如对于事件 2:44411-44345 = 66

这个持续时间我想在一个新列中,以便数据最终如下:

In [60]: df
Out[60]:
    time    event    duration
49  44295   NaN      NaN
50  44311   NaN      NaN
51  44328   NaN      NaN
52  44345   2        66
53  44361   2        66
54  44378   2        66
55  44395   2        66
56  44411   2        66
57  44428   3        50
58  44445   3        50
59  44461   3        50
60  44478   3        50
61  44495   NaN      NaN
62  44511   NaN      NaN
63  44528   NaN      NaN
64  44544   NaN      NaN
65  44561   NaN      NaN
66  44578   NaN      NaN
67  44594   NaN      NaN
68  44611   4        33
69  44628   4        33
70  44644   4        33
71  44661   NaN      NaN
72  44678   NaN      NaN

我该怎么做?

【问题讨论】:

    标签: python events time-series duration dataframe


    【解决方案1】:

    一种方法是使用groupbytransformmax - min也叫peak-to-peak,或者简称ptp,所以这里的ptp基本上就是lambda x: x.max() - x.min()的意思。

    >>> df = pd.read_csv("eye.csv",sep="\s+")
    >>> df["duration"] = df.dropna().groupby("event")["time"].transform("ptp")
    >>> df
         time  event  duration
    49  44295    NaN       NaN
    50  44311    NaN       NaN
    51  44328    NaN       NaN
    52  44345      2        66
    53  44361      2        66
    54  44378      2        66
    55  44395      2        66
    56  44411      2        66
    57  44428      3        50
    58  44445      3        50
    59  44461      3        50
    60  44478      3        50
    61  44495    NaN       NaN
    62  44511    NaN       NaN
    63  44528    NaN       NaN
    64  44544    NaN       NaN
    65  44561    NaN       NaN
    66  44578    NaN       NaN
    67  44594    NaN       NaN
    68  44611      4        33
    69  44628      4        33
    70  44644      4        33
    71  44661    NaN       NaN
    72  44678    NaN       NaN
    

    dropna 是为了防止 event 列中的每个 NaN 值被视为自己的事件。 (当密钥也是 NaN 时,ptp 的工作方式也很奇怪,但这是一个单独的问题。)

    【讨论】:

    • 我每次都得到 NaN
    • @MartinPetriBagger:这很奇怪。 df.dropna().groupby("event")["time"].transform("max")"min" 工作吗?
    • 同样的问题!它适用于上面使用的一小部分,但不适用于我的整个数据框。我放弃了 dropna() 部分。然后每个 NaN 都有自己的值,并且 i 循环遍历新列,指定什么应该是 NaN,什么不是......这行得通。
    【解决方案2】:

    使用来自itertoolsgroupby 迭代记录。组标准应为事件编号。由于您的数据已正确排序(与同一事件相关的所有事件代码都不会被其他事件打断),因此无需对偶数代码进行排序。

    groupby 将迭代返回元组 (key, group),其中 key 是偶数码,group 是所有记录的列表。

    从记录中获取最小和最大时间并计算持续时间。

    然后,将工期作为新字段添加到您的记录中。

    可能有更有效的方法使用 pandas,我不知道。所描述的解决方案不需要 pandas。

    【讨论】:

      【解决方案3】:

      我最终对@DSM 发布的答案做了以下工作:

      df["dur"] = datalist[i][j].groupby("event")["time"].transform("ptp")
      dur = []
      for i in datalist.index:
          if np.isnan(df["event"][i]): 
              dur.append(df["event"][i])
          else:
              dur.append(df["dur"][i])
      df["Duration"] = dur
      

      这至少对我有用。

      【讨论】:

        猜你喜欢
        • 2018-08-27
        • 1970-01-01
        • 2019-07-21
        • 2019-10-09
        • 2018-07-22
        • 2021-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多