Pandas:按分组应用函数并生成符合条件的新列Combined
问题描述
现有如下DataFrame:
import pandas as pd import numpy as np item_df = pd.DataFrame({'BarCode': ['12345678AAAA', '12345678BBBB', '12345678CCCC', '12345678ABCD', '12345678EFGH', '12345678IJKL', '67890123XXXX', '67890123YYYY', '67890123ZZZZ', '67890123ABCD', '67890123EFGH', '67890123IJKL'], 'Extracted_Code': ['12345678','12345678', '12345678','12345678','12345678','12345678', '67890123','67890123', '67890123','67890123', '67890123','67890123'], 'Description': ['Fruits', 'Fruits', 'Fruits', 'Apples', 'Oranges', 'Mangoes', 'Snacks', 'Snacks', 'Snacks', 'Yoghurt', 'Cookies', 'Oats'], 'Category': ['H', 'H', 'H', 'M', 'T', 'S', 'H', 'H', 'H', 'M', 'M', 'F'], 'Code': ['0', '2', '3', '1', '2', '4', '0', '2', '3', '3', '4', '2'], 'Quantity': [99, 77, 10, 52, 11, 90, 99, 77, 10, 52, 11, 90], 'Price': [12.0, 10.5, 11.0, 15.6, 12.9, 67.0, 12.0, 10.5, 11.0, 15.6, 12.9, 67.0]}) item_df = item_df.sort_values(by=['Extracted_Code', 'Category', 'Code']) item_df['Combined'] = np.NaN
需要按Extracted_Code分组,为每组生成新列Combined,规则如下:
- Category为'H'的行,
Combined列值为NaN; - Category不为'H'的行,
Combined列值为同分组内Category='H'且Code小于等于当前行Code的行的JSON格式列表。
目前已实现生成行JSON列表的代码,但困惑于如何在不丢失原有列的前提下,对每个组应用上述条件:
item_df.groupby(['Extracted_Code', 'Category', 'Code']).apply(lambda x: x.to_dict('records')).reset_index(name='Combined')
解决方案
可以通过分组后对非H类行匹配同组H类数据的方式实现,核心思路是:
- 先将
Code转为数值类型,避免字符串比较的逻辑错误; - 按
Extracted_Code分组,在每组内分离出H类数据作为匹配池; - 遍历每组内的非H类行,筛选出匹配池里Code≤当前行Code的记录,转为JSON格式列表;
- 把结果映射回原DataFrame,保留所有原有列。
完整代码如下:
import pandas as pd import numpy as np import json # 如需标准JSON格式则导入 # 先转换Code为数值类型,避免字符串比较的问题 item_df['Code'] = item_df['Code'].astype(int) def process_group(group): # 提取当前组内Category为H的行,作为匹配池 h_records = group[group['Category'] == 'H'] # 遍历组内每一行,生成Combined值 for idx, row in group.iterrows(): if row['Category'] == 'H': group.loc[idx, 'Combined'] = np.nan else: # 筛选H类中Code≤当前行Code的记录,转为字典列表 matched = h_records[h_records['Code'] <= row['Code']].to_dict('records') # 若要标准JSON字符串,替换为json.dumps(matched) group.loc[idx, 'Combined'] = str(matched) return group # 按Extracted_Code分组处理,合并结果 result_df = item_df.groupby('Extracted_Code', group_keys=False).apply(process_group) # 查看最终结果 print(result_df)
关键说明:
- 转换
Code类型:原数据中Code是字符串,直接比较会出现'10' < '2'的错误,转为int类型后才能正确比较大小; - 分组内独立处理:每个分组单独提取H类数据,避免跨组匹配错误;
- 保留原列:使用
group_keys=False避免分组键添加到索引,处理后直接返回完整的组数据,合并后保留所有原有列; - JSON格式选择:如果需要标准JSON字符串,可替换
str(matched)为json.dumps(matched),需提前导入json模块。
内容的提问来源于stack exchange,提问作者Animeartist
相关产品推荐
相关产品推荐

