如何在Python中像SAS一样按字符串内容填充分类字段?
保险类型字符串分类与空字段填充问题
我有大量保险类型字符串需要分类,其中少数为标准类型,但长尾部分需根据字符串包含的特定术语进行分类:
- 若字符串包含"HMO"或"PPO",分类为
private(私人保险) - 若包含"Medicaid"或"Medicare",分类为
public(公共保险) - 若包含"No Insurance"或"Charity",分类为
self pay(自费)
部分分类字段已填充值,其余为空,示例数据如下:
data = {'category': ['public', 'private', 'self pay', '', '', ''], 'raw': ['Medicaid', 'Blue Cross Blue Shield', 'No Insurance', 'blah blah PPO or something', 'HMO with a lot of weird stuff', 'blah blah charity'] } df = pd.DataFrame(data) print(df)
在SAS中可通过如下代码实现该逻辑(findw函数查找指定术语的起始位置,位置大于0则表示术语存在):
IF category is NULL then do; IF raw = 'Medicaid' THEN category = 'public' ; ELSE IF raw = 'Blue Cross Blue Shield' THEN category = 'private'; ELSE IF findw(raw, 'Sliding Scale') > 0 THEN category = 'self pay'; ELSE IF findw(raw, 'PPO') > 0 THEN category = 'private' ; ELSE IF findw(raw, 'HMO') > 0 THEN category = 'private' ; end ;
请问如何在Python中使用str.contains实现类似SAS的逻辑,填充空分类字段?或者有没有更Pythonic的实现方式?
方法一:使用str.contains结合条件判断填充
先筛选出category为空的行,再按优先级依次判断raw字段内容并赋值,设置case=False可忽略大小写匹配:
import pandas as pd # 筛选分类为空的行 mask = df['category'] == '' # 按优先级依次赋值 df.loc[mask & df['raw'].str.contains('Medicaid|Medicare', case=False), 'category'] = 'public' df.loc[mask & (df['raw'] == 'Blue Cross Blue Shield'), 'category'] = 'private' df.loc[mask & df['raw'].str.contains('Sliding Scale', case=False), 'category'] = 'self pay' df.loc[mask & df['raw'].str.contains('PPO|HMO', case=False), 'category'] = 'private' df.loc[mask & df['raw'].str.contains('No Insurance|Charity', case=False), 'category'] = 'self pay'
方法二:更Pythonic的实现——np.select
将条件与对应结果整理成列表,逻辑清晰且便于维护,顺序对应SAS中的判断优先级:
import pandas as pd import numpy as np # 定义条件列表与对应结果 conditions = [ df['category'] != '', # 已填充的分类保持不变 df['raw'].str.contains('Medicaid|Medicare', case=False), df['raw'] == 'Blue Cross Blue Shield', df['raw'].str.contains('Sliding Scale', case=False), df['raw'].str.contains('PPO|HMO', case=False), df['raw'].str.contains('No Insurance|Charity', case=False) ] results = [ df['category'], 'public', 'private', 'self pay', 'private', 'self pay' ] # 应用条件赋值 df['category'] = np.select(conditions, results, default='')
方法三:自定义函数+apply
如果后续逻辑需要扩展,可编写自定义函数逐行处理:
def classify_insurance(row): if row['category'] != '': return row['category'] raw_content = row['raw'].lower() if 'medicaid' in raw_content or 'medicare' in raw_content: return 'public' if row['raw'] == 'Blue Cross Blue Shield': return 'private' if 'sliding scale' in raw_content: return 'self pay' if 'ppo' in raw_content or 'hmo' in raw_content: return 'private' if 'no insurance' in raw_content or 'charity' in raw_content: return 'self pay' return '' df['category'] = df.apply(classify_insurance, axis=1)
内容的提问来源于stack exchange,提问作者Sandra T
相关产品推荐
相关产品推荐

