使用正则表达式过滤 pandas 数据框列,但出现异常
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
我想要包含列 drugA_use
或 drugB_use
中的值且与 status_drug_use
中的值匹配的所有行。根据示例,这将 return 两行:
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
有一些列名称约定需要遵守:
status_drug_use
一直都在。
- 匹配列(
drugA_use
和 drugB_use
)始终遵循模板 <ANYTHING>_use
。
改动
还有第二种情况,在这种情况下,我想在用户定义的字符串(例如 analgesic
和两列 drugA_use
和 drugB_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()
到 select 仅 status_drug_use
与 all_use
中的值匹配的行
- 使用
drop_duplicates
消除行,以防原始数据框中的任何行有多个匹配项(例如,如果 drugA_use
和 drugB_use
都包含“镇痛药”等做了 status_drug_use
)
- 删除列
all_use
,因为我们不再需要它。
更新:在评论中解决 OP 的问题:'Rather than using the values in column status_drug_use, how do I achieve the same output but by using a single user defined string e.g., "analgesic"?'
您可以通过将用户定义的查询字符串(称为 user_defined_str
)作为变量并通过将列名 status_drug_use
替换为带有 @
前缀的变量名称:@user_defined_str
(有关详细信息,请参阅 query()
文档 here)。
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')
我正在尝试通过使用 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
我想要包含列 drugA_use
或 drugB_use
中的值且与 status_drug_use
中的值匹配的所有行。根据示例,这将 return 两行:
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
有一些列名称约定需要遵守:
status_drug_use
一直都在。- 匹配列(
drugA_use
和drugB_use
)始终遵循模板<ANYTHING>_use
。
改动
还有第二种情况,在这种情况下,我想在用户定义的字符串(例如 analgesic
和两列 drugA_use
和 drugB_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()
到 select 仅status_drug_use
与all_use
中的值匹配的行
- 使用
drop_duplicates
消除行,以防原始数据框中的任何行有多个匹配项(例如,如果drugA_use
和drugB_use
都包含“镇痛药”等做了status_drug_use
) - 删除列
all_use
,因为我们不再需要它。
更新:在评论中解决 OP 的问题:'Rather than using the values in column status_drug_use, how do I achieve the same output but by using a single user defined string e.g., "analgesic"?'
您可以通过将用户定义的查询字符串(称为 user_defined_str
)作为变量并通过将列名 status_drug_use
替换为带有 @
前缀的变量名称:@user_defined_str
(有关详细信息,请参阅 query()
文档 here)。
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')