【问题标题】:Get start and end times from datetime stamps从日期时间戳获取开始和结束时间
【发布时间】:2020-02-22 14:47:22
【问题描述】:

我有一个 CSV 文件,其中包含时间戳以及关于它是指开始 (I) 还是结束 (F) 的信息。 我想计算开始时间和结束时间之间的持续时间。

我正在尝试将它加载到 pandas,按引用分组,'acao'(说明它是开始还是结束标记),将其拆开,然后使用 fillna() 来获取一张表格我可以计算持续时间。

我正在使用的代码:

data = pd.read_csv(file_path, parse_dates=['time_stamp'])
y = data.sort_values(['referencia','time_stamp'])
        y = y.set_index(['referencia','acao'], append=True).time_stamp.unstack('acao')
        y = y[['I','F']]

预期结果如下(希望我能够正确格式化表格):

+------------+----------------------------+----------------------------+
| referencia |             I              |             F              |
+------------+----------------------------+----------------------------+
|        111 | 2019-10-23 23:26:18.325750 |                            |
|        111 |                            | 2019-10-23 23:42:45.719985 |
|        123 | 2019-10-23 22:38:10.434322 |                            |
|        123 |                            | 2019-10-23 22:38:19.986666 |
|        123 | 2019-10-23 22:39:08.760218 |                            |
|        123 |                            | 2019-10-23 22:39:42.762875 |
|        123 | 2019-10-23 22:40:02.301749 |                            |
|        123 |                            | 2019-10-23 22:40:24.000795 |
|        123 | 2019-10-23 23:24:59.687386 |                            |
|        123 |                            | 2019-10-26 11:48:07.831072 |
|        133 | 2019-10-23 22:42:14.712779 |                            |
|        133 |                            | 2019-10-23 22:42:20.159414 |
|        156 | 2019-10-26 11:47:13.848750 |                            |
|        156 |                            | 2019-10-26 11:47:21.289268 |
|        199 | 2019-10-23 22:44:30.502311 |                            |
|        199 |                            | 2019-10-23 22:44:38.154283 |
|        555 | 2019-10-23 23:34:35.322073 |                            |
|        555 |                            | 2019-10-26 11:48:13.330636 |
+------------+----------------------------+----------------------------+

但不幸的是,我能得到的只有:

+------------+----------------------------+----------------------------+
| referencia |             I              |             F              |
+------------+----------------------------+----------------------------+
|        123 | 2019-10-23 22:38:10.434322 |                            |
|        123 |                            | 2019-10-23 22:38:19.986666 |
|        123 | 2019-10-23 22:39:08.760218 |                            |
|        123 |                            | 2019-10-23 22:39:42.762875 |
|        123 | 2019-10-23 22:40:02.301749 |                            |
|        123 |                            | 2019-10-23 22:40:24.000795 |
|        133 | 2019-10-23 22:42:14.712779 |                            |
|        133 |                            | 2019-10-23 22:42:20.159414 |
|        199 | 2019-10-23 22:44:30.502311 |                            |
|        199 |                            | 2019-10-23 22:44:38.154283 |
|        123 | 2019-10-23 23:24:59.687386 |                            |
|        111 | 2019-10-23 23:26:18.325750 |                            |
|        555 | 2019-10-23 23:34:35.322073 |                            |
|        111 |                            | 2019-10-23 23:42:45.719985 |
|        156 | 2019-10-26 11:47:13.848750 |                            |
|        156 |                            | 2019-10-26 11:47:21.289268 |
|        123 |                            | 2019-10-26 11:48:07.831072 |
|        555 |                            | 2019-10-26 11:48:13.330636 |
+------------+----------------------------+----------------------------+

我不能 groupby,因为我尝试它时会出现以下错误: “ValueError:索引包含重复条目,无法重塑”

忘记附上源数据了,不在下面:

utilizador,referencia,time_stamp,acao
AG,123,2019-10-23 22:38:10.434322,I
AG,123,2019-10-23 22:38:19.986666,F
AG,123,2019-10-23 22:39:08.760218,I
AG,123,2019-10-23 22:39:42.762875,F
AG,123,2019-10-23 22:40:02.301749,I
AG,123,2019-10-23 22:40:24.000795,F
AG,133,2019-10-23 22:42:14.712779,I
AG,133,2019-10-23 22:42:20.159414,F
AG,199,2019-10-23 22:44:30.502311,I
AG,199,2019-10-23 22:44:38.154283,F
AG,123,2019-10-23 23:24:59.687386,I
AG,111,2019-10-23 23:26:18.325750,I
AG,555,2019-10-23 23:34:35.322073,I
AG,111,2019-10-23 23:42:45.719985,F
AA,156,2019-10-26 11:47:13.848750,I
AG,156,2019-10-26 11:47:21.289268,F
AG,123,2019-10-26 11:48:07.831072,F
AG,555,2019-10-26 11:48:13.330636,F

【问题讨论】:

  • 您还应该显示输入。您的 csv 的子样本应该会导致预期的结果。没有它,几乎不可能帮助你。
  • @Valentino 你说得对,我打算粘贴源数据,但很担心表格的格式,最后忘记粘贴了。立即编辑帖子。

标签: python pandas datetime data-science


【解决方案1】:

我假设:

  • IF 列都是 datetime 类型,
  • referencia 是“普通”列(不是索引)。

为了使打印输出保持合理的水平尺寸, 我从您的数据中删除了几分之一秒,所以我的结果 和你的有点不一样。

从移动 F 列 1 单元格中的数据开始:

df.F = df.F.shift(-1)

然后用 NaT 删除行:

df.dropna(inplace=True)

结果是:

    referencia                   I                   F
0          111 2019-10-23 23:26:18 2019-10-23 23:42:45
2          123 2019-10-23 22:38:10 2019-10-23 22:38:19
4          123 2019-10-23 22:39:08 2019-10-23 22:39:42
6          123 2019-10-23 22:40:02 2019-10-23 22:40:24
8          123 2019-10-23 23:24:59 2019-10-26 11:48:07
10         133 2019-10-23 22:42:14 2019-10-23 22:42:20
12         156 2019-10-26 11:47:13 2019-10-26 11:47:21
14         199 2019-10-23 22:44:30 2019-10-23 22:44:38
16         555 2019-10-23 23:34:35 2019-10-26 11:48:13

然后,将两个时间值放在同一行中,计算 duration 列,运行:

df['duration'] = df.F - df.I

对于我的源数据,结果是:

    referencia                   I                   F        duration
0          111 2019-10-23 23:26:18 2019-10-23 23:42:45 0 days 00:16:27
2          123 2019-10-23 22:38:10 2019-10-23 22:38:19 0 days 00:00:09
4          123 2019-10-23 22:39:08 2019-10-23 22:39:42 0 days 00:00:34
6          123 2019-10-23 22:40:02 2019-10-23 22:40:24 0 days 00:00:22
8          123 2019-10-23 23:24:59 2019-10-26 11:48:07 2 days 12:23:08
10         133 2019-10-23 22:42:14 2019-10-23 22:42:20 0 days 00:00:06
12         156 2019-10-26 11:47:13 2019-10-26 11:47:21 0 days 00:00:08
14         199 2019-10-23 22:44:30 2019-10-23 22:44:38 0 days 00:00:08
16         555 2019-10-23 23:34:35 2019-10-26 11:48:13 2 days 12:13:38

在源数据发布后编辑

要将 time_stamp 列作为“真实”时间戳(不是字符串),请将 parse_dates=[2] 参数传递给 read_csv

然后,要重新格式化您的 DataFrame,请采用以下方法:

定义一个重新格式化函数,它将应用于每个组(连续的一对行):

def reformat(grp):
    tStart = grp.iloc[0, 2]
    tEnd = grp.iloc[1, 2]
    return pd.Series(grp.iloc[0, 0:3].tolist() + [tEnd, tEnd - tStart],
        index=['utilizador', 'referencia', 'start', 'end', 'duration'])

然后应用它:

df = df.groupby(np.arange(len(df.index)) // 2).apply(reformat)

对于您的源数据,删除了秒的小数部分,结果是:

  utilizador  referencia               start                 end duration
0         AG         123 2019-10-23 22:38:10 2019-10-23 22:38:19 00:00:09
1         AG         123 2019-10-23 22:39:08 2019-10-23 22:39:42 00:00:34
2         AG         123 2019-10-23 22:40:02 2019-10-23 22:40:24 00:00:22
3         AG         133 2019-10-23 22:42:14 2019-10-23 22:42:20 00:00:06
4         AG         199 2019-10-23 22:44:30 2019-10-23 22:44:38 00:00:08
5         AG         123 2019-10-23 23:24:59 2019-10-23 23:26:18 00:01:19
6         AG         555 2019-10-23 23:34:35 2019-10-23 23:42:45 00:08:10
7         AA         156 2019-10-26 11:47:13 2019-10-26 11:47:21 00:00:08
8         AG         123 2019-10-26 11:48:07 2019-10-26 11:48:13 00:00:06

再说一句:我注意到您的数据有些混乱,例如你有 只有一行

  • utilizador == 'AA',
  • utilizador == 'AG'referencia == 156

使用我的方案:

  • 输入文件应包含有关的连续行对 相同的utilizadorreferencia
  • 每一对都应该有 acao =='I' 的第一行和第二行 对于 acao =='F'

或者至少应该可以按此顺序对数据进行排序。

或者可能指示的 2 行应该是相同的 utilizador (而且它们是“成对的”)?

编辑 2

我将您数据中的 AG,156 更改为 AA,156(将上一行和这一行成对放置)。

然后我为您的数据添加排序,然后应用重新格式化

df = df.sort_values(['utilizador', 'referencia', 'time_stamp'])\
    .groupby(np.arange(len(df.index)) // 2).apply(reformat)

对于这样变化的数据,结果是:

  utilizador  referencia               start                 end        duration
0         AA         156 2019-10-26 11:47:13 2019-10-26 11:47:21 0 days 00:00:08
1         AG         111 2019-10-23 23:26:18 2019-10-23 23:42:45 0 days 00:16:27
2         AG         123 2019-10-23 22:38:10 2019-10-23 22:38:19 0 days 00:00:09
3         AG         123 2019-10-23 22:39:08 2019-10-23 22:39:42 0 days 00:00:34
4         AG         123 2019-10-23 22:40:02 2019-10-23 22:40:24 0 days 00:00:22
5         AG         123 2019-10-23 23:24:59 2019-10-26 11:48:07 2 days 12:23:08
6         AG         133 2019-10-23 22:42:14 2019-10-23 22:42:20 0 days 00:00:06
7         AG         199 2019-10-23 22:44:30 2019-10-23 22:44:38 0 days 00:00:08
8         AG         555 2019-10-23 23:34:35 2019-10-26 11:48:13 2 days 12:13:38

你可能想要什么。

【讨论】:

  • 谢谢,你的回答教会了我一些新东西。不幸的是,我忘记附加 csv 数据,所以我的主要问题仍未解决。
  • 我扩展了我的答案。我希望现在问题已经解决了。
猜你喜欢
  • 2020-11-19
  • 2021-09-06
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多