【问题标题】:Pandas - Resample/GroupBy DateTime Index and perform calculationsPandas - Resample/GroupBy DateTime Index 并执行计算
【发布时间】:2018-10-19 03:25:43
【问题描述】:

我会尽力解释我需要帮助的地方。我有以下 df(如果不是数百万行,则有数千行),其日期时间索引如下例所示:

INDEX                   COL A       COL B
2018-05-07 21:53:13.731 0.365127    9391.800000
2018-05-07 21:53:16.201 0.666127    9391.800000
2018-05-07 21:53:18.038 0.143104    9391.800000
2018-05-07 21:53:18.243 0.025643    9391.800000
2018-05-07 21:53:18.265 0.640484    9391.800000
2018-05-07 21:53:18.906 -0.100000   9391.793421
2018-05-07 21:53:19.829 0.559516    9391.800000
2018-05-07 21:53:19.846 0.100000    9391.800000
2018-05-07 21:53:19.870 0.006560    9391.800000
2018-05-07 21:53:20.734 0.666076    9391.800000
2018-05-07 21:53:20.775 0.666076    9391.800000
2018-05-07 21:53:28.607 0.100000    9391.800000
2018-05-07 21:53:28.610 0.041991    9391.800000
2018-05-07 21:53:29.283 -0.053518   9391.793421
2018-05-07 21:53:47.322 -0.046302   9391.793421
2018-05-07 21:53:49.182 0.100000    9391.800000

我想做的是以 5 秒的间隔对行进行分组,并在每 5 秒的间隔/子集上执行(有时是复杂的)计算。

例如,假设我想计算每 5 秒块内 A 列中正值与负值的百分比。

2018-05-07 21:53:102018-05-07 21:53:15 仅包含一行,A 列是正数,因此我将使用 100% 创建一个新 C 列。

同样2018-05-07 21:53:152018-05-07 21:53:20 在 A 列有 8 行,其中 7 行是正数,其中 1 行是负数。所以 C 列是87.5%

我会发布示例代码,但我真的不确定执行此操作的最佳方式。示例输出(新 df)可能类似于以下内容,其中 COL D 只是 5 秒分组的 COL B 中的最小数字:

INDEX               COL C     COL D (MIN)
2018-05-07 21:53:10 100%     9391.800000
2018-05-07 21:53:15 12.5%    9391.793421
2018-05-07 21:53:20 100%     9391.800000
2018-05-07 21:53:25 66.7%    9391.793421
2018-05-07 21:53:30 nan      nan
2018-05-07 21:53:35 nan      nan
2018-05-07 21:53:40 nan      nan
2018-05-07 21:53:45 100%     9391.793421

请记住,我想对每个分组进行许多不同的计算。因此使用内置的.sum().mean().agg() 等不足以进行更复杂的计算。

感谢任何帮助,如果需要,我很乐意澄清问题。

【问题讨论】:

  • 我对第一列有点困惑,你能解释一下吗?
  • 我相信您在说明中引用了错误的列。 B 列始终为正。此外,对于 pos 与 neg,我认为在您的第二个示例中正确的值是 87.5% (7/8) 而不是 12.5%。
  • 亚历山大有,我的错。

标签: python pandas datetime time-series


【解决方案1】:

我认为需要正值的百分比需要值的平均值>0

df = df.resample('5S').agg({'COL A': lambda x: (x > 0).mean() * 100, 'COL B': 'min'})
print (df)
                          COL A        COL B
INDEX                                       
2018-05-07 21:53:10  100.000000  9391.800000
2018-05-07 21:53:15   87.500000  9391.793421
2018-05-07 21:53:20  100.000000  9391.800000
2018-05-07 21:53:25   66.666667  9391.793421
2018-05-07 21:53:30         NaN          NaN
2018-05-07 21:53:35         NaN          NaN
2018-05-07 21:53:40         NaN          NaN
2018-05-07 21:53:45   50.000000  9391.793421

对于负值的百分比需要<0 的平均值:

df = df.resample('5S').agg({'COL A': lambda x: (x < 0).mean() * 100, 'COL B': 'min'})
print (df)
                         COL A        COL B
INDEX                                      
2018-05-07 21:53:10   0.000000  9391.800000
2018-05-07 21:53:15  12.500000  9391.793421
2018-05-07 21:53:20   0.000000  9391.800000
2018-05-07 21:53:25  33.333333  9391.793421
2018-05-07 21:53:30        NaN          NaN
2018-05-07 21:53:35        NaN          NaN
2018-05-07 21:53:40        NaN          NaN
2018-05-07 21:53:45  50.000000  9391.793421

正如@Alexander 指出的那样,0 既不是积极的也不是消极的。所以最好在计数之前将其删除:

df = df.resample('5S').agg({'COL A': lambda x: (x[x.ne(0)] > 0).mean() * 100, 'COL B': 'min'})

【讨论】:

  • lambda x: x.ne(0).mean() * 100? (否则您将零值视为正值)
  • @Alexander - 谢谢,我在想0 应该是negative 还是positive
  • 我相信您首先要过滤组以删除任何零值,因为它既不是正数也不是负数。然后使用.gt(0) 返回一个由正数组成的数组,并取平均值以获得正数非零值的百分比。 lambda x: x[x.ne(0)].gt(0).mean() * 100
  • 它会告诉你组中正值的数量,但因为你的组包含零,我认为百分比是不正确的。用 [0.7, 0.4, 0, -0.2] 试试。结果应该是 0.666(三个非零值中有 2 个正数)。
  • 顺便说一句,这是来自经验......我已经分析了很多零的数据(实际上应该是 NaN 值)。将它们过滤掉既是正确的,也可以防止在“坏”数据的情况下出现向上偏差。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
  • 2017-01-07
  • 2018-12-20
相关资源
最近更新 更多