Python 如何操作pandas中的行块

Python 如何操作pandas中的行块,python,pandas,performance,numpy,Python,Pandas,Performance,Numpy,我有一个大的db(2.4亿行)被划分为块,块标记的开始(sob)作为列之一,130万个块 我创建了一个block_开始系列: block_start = pd.series(df[df.sob == True].index) 并计算块长度系列: block_len = block_start.shift(-1) - block_start. 现在,我需要确定每个块在布尔列中是否至少包含一个信号(true): signals = [] for i in range(len(block_sta

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

我创建了一个block_开始系列:

block_start = pd.series(df[df.sob == True].index)
并计算块长度系列:

block_len = block_start.shift(-1) - block_start.
现在,我需要确定每个块在布尔列中是否至少包含一个信号(true):

signals = []

for i in range(len(block_start)):
 signals.append(df.signal[block_start[i]:block_start[i]+block_len[i]].any())
上述循环需要20分钟。 你知道怎么缩短吗

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
对于blazing1性能,您可能希望让NumPy接管。
(数据来源于@jpp的回答)

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



谢谢,太棒了,20秒而不是20分钟!
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
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)