[英]Python Pandas: Search rows with consecutive condition
我有一个如下数据框:
Text Label
a NaN
b NaN
c NaN
1 NaN
2 NaN
b NaN
c NaN
a NaN
b NaN
c NaN
每当模式“ a,b,c”向下出现时,我都希望将该部分标记为字符串,例如“ Check”。 最终数据框应如下所示:
Text Label
a Check
b Check
c Check
1 NaN
2 NaN
b NaN
c NaN
a Check
b Check
c Check
做这个的最好方式是什么。 谢谢=)
这是利用广播的基于NumPy
的方法:
import numpy as np
w = df.Text.cumsum().str[-3:].eq('abc') # inefficient for large dfs
m = (w[w].index.values[:,None] + np.arange(-2,1)).ravel()
df.loc[m, 'Label'] = 'Check'
Text Label
0 a Check
1 b Check
2 c Check
3 1 NaN
4 2 NaN
5 b NaN
6 c NaN
7 a Check
8 b Check
9 c Check
将此解决方案与numpy.where
一起使用,作为一般解决方案:
arr = df['Text']
pat = list('abc')
N = len(pat)
def rolling_window(a, window):
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
c = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
return c
b = np.all(rolling_window(arr, N) == pat, axis=1)
c = np.mgrid[0:len(b)][b]
d = [i for x in c for i in range(x, x+N)]
df['label'] = np.where(np.in1d(np.arange(len(arr)), d), 'Check', np.nan)
print (df)
Text Label label
0 a NaN Check
1 b NaN Check
2 c NaN Check
3 1 NaN nan
4 2 NaN nan
5 b NaN nan
6 c NaN nan
7 a NaN Check
8 b NaN Check
9 c NaN Check
良好的旧shift
和bfill
工作(步骤少):
s = df.Text.eq('c') & df.Text.shift().eq('b') & df.Text.shift(2).eq('a')
df.loc[s, 'Label'] = 'Check'
df.Label.bfill(limit=2, inplace=True)
输出:
Text Label
0 a Check
1 b Check
2 c Check
3 1 NaN
4 2 NaN
5 b NaN
6 c NaN
7 a Check
8 b Check
9 c Check
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.