繁体   English   中英

使用正则表达式过滤熊猫数据框列有异常

[英]Using regex to filter pandas dataframe columns with an exception

我正在尝试通过使用 pd.filter 和正则表达式字符串来子集(检索一组行)python pandas 数据框,以在根据这些列中的值执行子集之前识别感兴趣的列。

例如,这是我的模拟数据框:

id status status_drug_use drugA drugA_use    drugB  drugB_use
0  1      analgesic       0     None         1      hypertensive
1  0      analgesic       1     analgesic    1      hypertensive
2  0      analgesic       1     hypertensive 0      None
3  1      analgesic       0     None         1      analgesic

我想要包含与status_drug_use中的值匹配的drugA_usedrugB_use列中的值的所有行。 根据示例,这将返回两行:

id status status_drug_use drugA drugA_use    drugB  drugB_use
1  0      analgesic       1     analgesic    1      hypertensive
3  1      analgesic       0     None         1      analgesic

有一些列名约定要坚持:

  1. status_drug_use始终存在。
  2. 匹配列( drugA_usedrugB_use )始终遵循模板<ANYTHING>_use

变更还有第二种情况,我想在用户定义的字符串(例如analgesic )和两列drugA_usedrugB_use之间进行比较。 这与使用status_drug_use的内容不同。

这是一种执行您所要求的方法:

df2 = df.assign(all_use=df.apply(
    lambda x: list(x[[col for col in df.columns if col.endswith('_use') and col != 'status_drug_use']]), 
    axis=1)).explode(
    'all_use').query('status_drug_use == all_use').drop_duplicates().drop(columns='all_use')

输入:

  id status status_drug_use drugA     drugA_use drugB     drugB_use
0  0      1       analgesic     0          None     1  hypertensive
1  1      0       analgesic     1     analgesic     1  hypertensive
2  2      0       analgesic     1  hypertensive     0          None
3  3      1       analgesic     0          None     1     analgesic

输出:

  id status status_drug_use drugA  drugA_use drugB     drugB_use
1  1      0       analgesic     1  analgesic     1  hypertensive
3  3      1       analgesic     0       None     1     analgesic

解释:

  • 查找以_use结尾的所有列的子集(不包括status_drug_use
  • 添加一个名为all_use的列,其给定行的值是以_use结尾的列中的值的列表
  • 使用explode()添加行,使得对于每个原始行,现在有多个行,一个用于原始行的all_use中的每个值
  • 使用query()仅选择status_drug_useall_use中的值匹配的行
  • 如果原始数据框中的任何行有多个匹配项,请使用drop_duplicates消除行(例如,如果drugA_usedrugB_use都包含“analgesic”,而status_drug_use也是如此)
  • 删除列all_use因为我们不再需要它。

更新:在评论中解决 OP 的问题:“而不是使用列 status_drug_use 中的值,我如何通过使用单个用户定义的字符串(例如“analgesic”)来实现相同的输出?

您可以通过将用户定义的查询字符串(称为user_defined_str )作为变量并通过将列名status_drug_use替换为带有@前缀的变量名来更改query()的内容来做到这一点: @user_defined_str (请参阅query()文档此处了解更多详细信息)。

user_defined_str = 'analgesic'
df3 = df.assign(all_use=df.apply(
    lambda x: list(x[[col for col in df.columns if col.endswith('_use') and col != 'status_drug_use']]), 
    axis=1)).explode(
    'all_use').query('@user_defined_str == all_use').drop_duplicates().drop(columns='all_use')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM