【问题标题】:In dataframe, how to recognize rows with more than 3 consecutive zeros?在数据框中,如何识别连续三个以上零的行?
【发布时间】:2022-11-15 17:46:18
【问题描述】:

我有一个这样的数据框。

而且我想识别一些行,以便任何识别的行都在一个具有超过 3 个(>=4)连续零的块中。 (标记为 can_trade)

我试过的是:

df['cannot_trade'] = (
(df['volume'] == 0) & (df['volume'].shift(1) == 0) & (df['volume'].shift(2) == 0) & (df['volume'].shift(3) == 0) ) | (
(df['volume'] == 0) & (df['volume'].shift(-1) == 0) & (df['volume'].shift(-2) == 0) & (df['volume'].shift(-3) == 0)) 

它确实可以识别长连续的零,但我们可以在数据框中看到在 'closetime'=='2022-10-17 23:13:00' 和 'closetime'=='2022-10-17 23:14:00' ,识别失败,其中 'cannot_trade' 应该设置为 'True'。

你知道如何解决这个问题吗?

这是数据框的文本格式:

 close  volume         symbol           closetime  cannot_trade
63292514  0.2544     910  ZRX-USDT-SWAP 2022-10-17 23:01:00         False
63292515  0.2544       0  ZRX-USDT-SWAP 2022-10-17 23:02:00         False
63292516  0.2544       0  ZRX-USDT-SWAP 2022-10-17 23:03:00         False
63292517  0.2544       0  ZRX-USDT-SWAP 2022-10-17 23:04:00         False
63292518  0.2543     222  ZRX-USDT-SWAP 2022-10-17 23:05:00         False
63292519  0.2543       0  ZRX-USDT-SWAP 2022-10-17 23:06:00         False
63292520  0.2546    1119  ZRX-USDT-SWAP 2022-10-17 23:07:00         False
63292521  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:08:00         False
63292522  0.2549      84  ZRX-USDT-SWAP 2022-10-17 23:09:00         False
63292523  0.2549       0  ZRX-USDT-SWAP 2022-10-17 23:10:00         False
63292524  0.2548     181  ZRX-USDT-SWAP 2022-10-17 23:11:00         False
63292525  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:12:00          True
63292526  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:13:00         False
63292527  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:14:00         False
63292528  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:15:00          True
63292529  0.2546     222  ZRX-USDT-SWAP 2022-10-17 23:16:00         False
63292530  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:17:00          True
63292531  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:18:00          True
63292532  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:19:00          True
63292533  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:20:00          True
63292534  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:21:00          True
63292535  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:22:00          True
63292536  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:23:00          True
63292537  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:24:00          True
63292538  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:25:00          True
63292539  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:26:00          True
63292540  0.2546       0  ZRX-USDT-SWAP 2022-10-17 23:27:00          True
63292541  0.2545     100  ZRX-USDT-SWAP 2022-10-17 23:28:00         False
63292542  0.2545       0  ZRX-USDT-SWAP 2022-10-17 23:29:00         False
63292543  0.2545       0  ZRX-USDT-SWAP 2022-10-17 23:30:00         False
63292544  0.2547     141  ZRX-USDT-SWAP 2022-10-17 23:31:00         False
63292545  0.2548       3  ZRX-USDT-SWAP 2022-10-17 23:32:00         False
63292546  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:33:00         False
63292547  0.2548       0  ZRX-USDT-SWAP 2022-10-17 23:34:00         False
63292548  0.2552     130  ZRX-USDT-SWAP 2022-10-17 23:35:00         False
63292549  0.2555     214  ZRX-USDT-SWAP 2022-10-17 23:36:00         False
63292550  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:37:00          True
63292551  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:38:00          True
63292552  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:39:00         False
63292553  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:40:00          True
63292554  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:41:00          True
63292555  0.2557     103  ZRX-USDT-SWAP 2022-10-17 23:42:00         False
63292556  0.2557       0  ZRX-USDT-SWAP 2022-10-17 23:43:00         False
63292557  0.2557     127  ZRX-USDT-SWAP 2022-10-17 23:44:00         False
63292558  0.2557       0  ZRX-USDT-SWAP 2022-10-17 23:45:00         False
63292559  0.2559      91  ZRX-USDT-SWAP 2022-10-17 23:46:00         False
63292560  0.2558     100  ZRX-USDT-SWAP 2022-10-17 23:47:00         False
63292561  0.2558       0  ZRX-USDT-SWAP 2022-10-17 23:48:00         False
63292562  0.2558      39  ZRX-USDT-SWAP 2022-10-17 23:49:00         False
63292563  0.2558       0  ZRX-USDT-SWAP 2022-10-17 23:50:00         False
63292564  0.2558       0  ZRX-USDT-SWAP 2022-10-17 23:51:00         False
63292565  0.2558       0  ZRX-USDT-SWAP 2022-10-17 23:52:00         False
63292566  0.2555     260  ZRX-USDT-SWAP 2022-10-17 23:53:00         False
63292567  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:54:00         False
63292568  0.2555       0  ZRX-USDT-SWAP 2022-10-17 23:55:00         False
63292569  0.2550     375  ZRX-USDT-SWAP 2022-10-17 23:56:00         False
63292570  0.2549      43  ZRX-USDT-SWAP 2022-10-17 23:57:00         False
63292571  0.2549     195  ZRX-USDT-SWAP 2022-10-17 23:58:00         False
63292572  0.2550     141  ZRX-USDT-SWAP 2022-10-17 23:59:00         False
63292573  0.2550     209  ZRX-USDT-SWAP 2022-10-18 00:00:00         False

【问题讨论】:

    标签: python pandas dataframe data-cleaning


    【解决方案1】:

    您可以使用groupby.transform('count'):

    N = 4
    
    m = df['volume'].ne(0)
                   
    df['cannot_trade'] = (df.groupby(m.cumsum())['volume']
                            .transform('count').gt(N)
                          & (~m)
                         )
    

    例子:

        volume  cannot_trade
    0        0         False
    1        0         False
    2        0         False
    3        1         False
    4        0          True
    5        0          True
    6        0          True
    7        0          True
    8        2         False
    9        1         False
    10       0         False
    11       1         False
    

    【讨论】:

    • 惊人。谢谢莫兹威。你真快。
    • @OldChi 不客气,希望对你有帮助
    • 您能否将您的示例作为文本提供,以便我可以添加预期的输出以清楚起见?
    • 当然。您可以查看我最后编辑的内容中的文本。
    • @OldChi 谢谢,我待会儿看一下。另外,如果性能很重要,让我尝试为您提供更快的更新
    【解决方案2】:

    通过比较不等于 0 和累积总和广告创建组,将 NaN 替换为 m 值,将最后一个计数值替换为 Series.value_counts,将 Series.map 替换为新列,最后比较大于或等于 N:

    df = pd.DataFrame({'volume':[0,0,1,1,0,0,0,0]})
    
    N = 4
    m = df['volume'].ne(0)
    
    s = m.cumsum().mask(m)
    df['cannot_trade'] = s.map(s.value_counts()).ge(N)
    print (df)
       volume  cannot_trade
    0       0         False
    1       0         False
    2       1         False
    3       1         False
    4       0          True
    5       0          True
    6       0          True
    7       0          True
    

    解决方案详情:

    N = 4
    m = df['volume'].ne(0)
    s = m.cumsum().mask(m)
    
    print (df.assign(m = df['volume'].ne(0),
                     s = m.cumsum().mask(m),
                     count = s.map(s.value_counts()),
                     cannot_trade = s.map(s.value_counts()).ge(N)))
       volume      m    s  count  cannot_trade
    0       0  False  0.0    2.0         False
    1       0  False  0.0    2.0         False
    2       1   True  NaN    NaN         False
    3       1   True  NaN    NaN         False
    4       0  False  2.0    4.0          True
    5       0  False  2.0    4.0          True
    6       0  False  2.0    4.0          True
    7       0  False  2.0    4.0          True
    

    【讨论】:

    • 谢谢杰斯瑞尔。您的解决方案运行速度非常快。
    • @OldChi - 嗯,它像groupby 解决方案一样快吗?我认为是的,是否可以在您的真实数据中进行测试?
    • 就我而言,我的数据框的形状为 2786343 × 5。Mozway 的“groupby”解决方案需要 8.5 秒,而您的解决方案需要 3 秒。
    【解决方案3】:

    如果我理解正确,您可以应用滚动窗口求和方法来检查 3 个连续事件是否等于 0,然后应用香草 python 过滤器。假设您的 df 的名称也是如此,“a”是您要检查的列,“b”是布尔列:

    so["sum"] = so["a"].rolling(3).sum()
    

    现在过滤:

    so.loc[(so["sum"] == 0) & (so["b"] == True), :]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-19
      • 2022-12-21
      • 1970-01-01
      • 2020-07-25
      • 2020-05-11
      • 2020-02-25
      • 2019-07-29
      • 1970-01-01
      相关资源
      最近更新 更多