Python Pandas:搜索具有连续条件的行

时间:2019-06-11 08:58:05

标签: python pandas

我有一个如下数据框:

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”向下出现时,我都希望将该部分标记为字符串,例如“检查”。最终数据框应如下所示:

Text  Label 
 a     Check
 b     Check
 c     Check
 1     NaN
 2     NaN
 b     NaN
 c     NaN 
 a     Check
 b     Check
 c     Check

什么是最好的方法。谢谢=)

3 个答案:

答案 0 :(得分:2)

这是一种利用广播的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

答案 1 :(得分:1)

this解决方案与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

答案 2 :(得分:0)

良好的旧shiftbfill也可以工作(只需少量步骤):

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