如何使用Pandas基于两个条件列表对字符串列表交叉分组?
Pandas实现双条件交叉分组解决方案
问题背景
现有三个列表:
a = ['AFM_123_H2O_56', '345_FM_CO2', 'H6C6_AFM_test', 'dio_CO2_FM', 'check_H2O_FM', 'sample_FM_H6C6', 'AFM_67_H2O'] condition1 = ['H2O', 'CO2', 'H6C6'] condition2 = ['FM', 'AFM']
需要基于condition1和condition2的交叉组合对列表a中的元素分组,最终输出支持两种格式:
- 嵌套列表格式:
c = [['AFM_123_H2O_56', 'AFM_67_H2O'], #包含H2O和AFM的所有字符串 ['check_H2O_FM'], #包含H2O和FM的所有字符串 ['345_FM_CO2', 'dio_CO2_FM'], #包含CO2和FM的所有字符串 ['H6C6_AFM_test'], #包含H6C6和AFM的所有字符串 ['sample_FM_H6C6']] #包含H6C6和FM的所有字符串
- Pandas DataFrame格式:
H2O_AFM ['AFM_123_H2O_56', 'AFM_67_H2O'] H2O_FM ['check_H2O_FM'] CO2_FM ['345_FM_CO2', 'dio_CO2_FM'] H6C6_AFM ['H6C6_AFM_test'] H6C6_FM ['sample_FM_H6C6']
目前已掌握单条件分组的Pandas实现:
pattern = '(%s)' % '|'.join(map(re.escape, condition1)) series_files = pd.Series(a) df_grouped_files = series_files.groupby(series_files.str.extract(pattern, expand=False), sort=False).agg(list)
但不清楚如何实现双条件的交叉分组。
解决方案
通过两次提取匹配的条件值,拼接成唯一分组键后完成分组,具体代码如下:
import pandas as pd import re a = ['AFM_123_H2O_56', '345_FM_CO2', 'H6C6_AFM_test', 'dio_CO2_FM', 'check_H2O_FM', 'sample_FM_H6C6', 'AFM_67_H2O'] condition1 = ['H2O', 'CO2', 'H6C6'] condition2 = ['FM', 'AFM'] # 生成两个条件的正则匹配模式,转义特殊字符避免匹配出错 pattern1 = '(%s)' % '|'.join(map(re.escape, condition1)) pattern2 = '(%s)' % '|'.join(map(re.escape, condition2)) # 将列表转为Series,分别提取每个元素匹配的condition1和condition2值 s = pd.Series(a) match_cond1 = s.str.extract(pattern1, expand=False) match_cond2 = s.str.extract(pattern2, expand=False) # 拼接两个匹配结果作为分组键 group_key = match_cond1 + '_' + match_cond2 # 按分组键分组,聚合为列表,sort=False保留首次出现的顺序 result = s.groupby(group_key, sort=False).agg(list) # 输出DataFrame格式结果 print(result) # 转换为嵌套列表格式 nested_list_result = result.tolist() print(nested_list_result)
输出结果
- DataFrame格式输出:
H2O_AFM [AFM_123_H2O_56, AFM_67_H2O] CO2_FM [345_FM_CO2, dio_CO2_FM] H6C6_AFM [H6C6_AFM_test] H2O_FM [check_H2O_FM] H6C6_FM [sample_FM_H6C6] dtype: object
- 嵌套列表格式输出:
[['AFM_123_H2O_56', 'AFM_67_H2O'], ['345_FM_CO2', 'dio_CO2_FM'], ['H6C6_AFM_test'], ['check_H2O_FM'], ['sample_FM_H6C6']]
关键说明
re.escape用于转义条件字符串中的特殊字符,确保正则匹配准确- 假设每个字符串仅对应一组
condition1+condition2的组合,若存在多组匹配,str.extract会提取第一个匹配值 sort=False参数保证分组顺序与元素首次匹配到对应条件组合的顺序一致
内容的提问来源于stack exchange,提问作者user16613865
相关产品推荐
相关产品推荐

