Python 检查数据帧单元格是否包含特定字符串

Python 检查数据帧单元格是否包含特定字符串,python,pandas,Python,Pandas,假设我有以下数据帧: a b 0 NAN BABA UN EQUITY 1 NAN 2018 2 NAN 2017 3 NAN 2016 4 NAN NAN 5 NAN 700 HK EQUITY 6 NAN 2018 7 NAN 2017

假设我有以下数据帧:

         a        b             
0        NAN      BABA UN EQUITY
1        NAN      2018  
2        NAN      2017
3        NAN      2016
4        NAN      NAN
5        NAN      700 HK EQUITY
6        NAN      2018  
7        NAN      2017
8        NAN      2016
9        NAN      NAN 
我想检查列
b
中的每个单元格,看看它是否包含字符串
EQUITY
。如果是的话,我想替换列
a
中的单元格,下一行直到所有
NAN
的行都是前一个字符串,以获得编辑的数据帧,如下所示:

         a                 b             
0        NAN               BABA UN EQUITY
1        BABA UN EQUITY    2018  
2        BABA UN EQUITY    2017
3        BABA UN EQUITY    2016
4        NAN               NAN
5        NAN               700 HK EQUITY
6        700 HK EQUITY     2018  
7        700 HK EQUITY     2017
8        700 HK EQUITY     2016
9        NAN               NAN         
我的实际数据帧比上面的要大得多,但格式类似。我对熊猫很陌生,但我想我可以通过使用
sheet.loc
并替换循环中的单元格值

但是,我很难确定如何检查单元格是否包含
权益
。似乎
str.contains
是我应该使用的,但我不清楚如何使用它

谢谢

import numpy as np
import pandas as pd

df = pd.DataFrame({'a': ['NAN', 'NAN', 'NAN', 'NAN', 'NAN', 'NAN', 'NAN', 'NAN', 'NAN', 'NAN'],
 'b': ['BABA UN EQUITY', '2018', '2017', '2016', 'NAN', '700 HK EQUITY', '2018', '2017', '2016', 'NAN']})

# Make sure that all NaN values are `np.nan` not `'NAN'` (strings)
df = df.replace('NAN', np.nan)
mask = df['b'].str.contains(r'EQUITY', na=True)
df.loc[mask, 'a'] = df['b']
df['a'] = df['a'].ffill()
df.loc[mask, 'a'] = np.nan
屈服

                a               b
0             NaN  BABA UN EQUITY
1  BABA UN EQUITY            2018
2  BABA UN EQUITY            2017
3  BABA UN EQUITY            2016
4             NaN             NaN
5             NaN   700 HK EQUITY
6   700 HK EQUITY            2018
7   700 HK EQUITY            2017
8   700 HK EQUITY            2016
9             NaN             NaN

上面有一点棘手的是如何定义
掩码。请注意,
str.contains
返回一个序列,该序列不仅包含
True
False
值,而且还包含
NaN

In [114]: df['b'].str.contains(r'EQUITY')
Out[114]: 
0     True
1    False
2    False
3    False
4      NaN
5     True
6    False
7    False
8    False
9      NaN
Name: b, dtype: object
str.contains(…,na=True)
用于将
NaN
s视为
True

In [116]: df['b'].str.contains(r'EQUITY', na=True)
Out[116]: 
0     True
1    False
2    False
3    False
4     True
5     True
6    False
7    False
8    False
9     True
Name: b, dtype: bool

有了
mask
后,想法很简单:只要
mask
为真,就将
b
中的值复制到
a
中:

df.loc[mask, 'a'] = df['b']
df.loc[mask, 'a'] = np.nan
正向填充
a
中的NaN值:

df['a'] = df['a'].ffill()
如果
mask
为真,则将
a
中的值替换为NaN:

df.loc[mask, 'a'] = df['b']
df.loc[mask, 'a'] = np.nan

你能用
na=True
参数来代替
!=错误
?(或者根据需要
na=False
)@jpp:你说得绝对正确。我忘记了参数的存在。非常感谢您的详细解释!我在检查字符串中是否包含一个或其他模式时遇到问题。见此:
pattern='wiring | media | elect | tape'
v=pd.Series(['electronic fault'])
s=v.str.contains(pattern,flags=re.IGNORECASE,regex=True)
print(s)
0 False
dtype:bool
为什么?如果你能帮我解决这个问题,我将不胜感激。但不知道为什么?可能是因为图案中有空格吗?见此:
pattern='wiring | media | elect | tape'
v=pd.Series(['electronic fault'])s=v.str.contains(pattern,flags=re.IGNORECASE,regex=True)
Output
0 True