【问题标题】:How to manipulate blocks of rows in pandas如何操作熊猫中的行块
【发布时间】:2019-04-14 08:08:20
【问题描述】:

我有一个大 db(2.4 亿行)分成块,块开始标记 (sob) 作为列之一,130 万块。

我创建了一个 block_start 系列:

block_start = pd.series(df[df.sob == True].index)

并计算块长度系列:

block_len = block_start.shift(-1) - block_start.

现在我需要在布尔列中查找每个块是否包含至少一个信号(真):

signals = []

for i in range(len(block_start)):
 signals.append(df.signal[block_start[i]:block_start[i]+block_len[i]].any())

上述循环需要 20 分钟。 任何想法如何缩短它?

【问题讨论】:

    标签: python pandas performance numpy


    【解决方案1】:

    groupby + cumsum + any

    你可以groupby你的sob系列的累计总和:

    df = pd.DataFrame({'signal': [True, False, True, False, False,
                                  False, True, False, False, False],
                       'sob': [True, False, False, False, True,
                               False, False, True, False, False]})
    
    df['any_flag'] = df.groupby(df['sob'].cumsum())['signal'].transform('any')
    
    print(df)
    
       signal    sob  any_flag
    0    True   True      True
    1   False  False      True
    2    True  False      True
    3   False  False      True
    4   False   True      True
    5   False  False      True
    6    True  False      True
    7   False   True     False
    8   False  False     False
    9   False  False     False
    

    【讨论】:

    • 谢谢,20 秒而不是 20 分钟!
    【解决方案2】:

    为了获得出色的1 性能,您可能希望让 NumPy 接管。
    (数据来自@jpp的回答)

    v = np.cumsum(df['sob'])
    df['any_flag'] = v.isin(v[df.signal].unique())
    
    print(df)
       signal    sob  any_flag
    0    True   True      True
    1   False  False      True
    2    True  False      True
    3   False  False      True
    4   False   True      True
    5   False  False      True
    6    True  False      True
    7   False   True     False
    8   False  False     False
    9   False  False     False
    

    1。您的里程可能会有所不同。


    df = pd.concat([df] * 10000, ignore_index=True)
    
    %timeit df['any_flag'] = (
        df.groupby(df['sob'].cumsum())['signal'].transform('any'))
    %%timeit 
    v = np.cumsum(df['sob'])
    df['any_flag'] = v.isin(v[df.signal].unique())
    
    10.9 ms ± 610 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    4.5 ms ± 19.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      相关资源
      最近更新 更多