在Pandas GroupBy中基于子组匹配值生成1食1饮组合
问题描述
现有记录用户多日多条日志的DataFrame,结构如下:
DATE USER TYPE MORNING AFTN NIGHT FOOD BVG 01/11/2019 A Bvg 1 0 1 - Water 01/11/2019 A Bvg 1 0 0 - Juice 01/11/2019 A Food 0 1 1 Rice - 01/11/2019 A Food 1 0 0 Noodle - 02/11/2019 A Bvg 1 0 0 - Coffee 02/11/2019 A Food 0 0 1 Bread - 02/11/2019 A Bvg 0 0 1 - Tea 01/11/2019 B Bvg 1 0 0 - Water 01/11/2019 B Bvg 0 1 0 - Tea 01/11/2019 B Food 1 0 0 Rice -
需求:找出同一天、同一时段(时段由MORNING/AFTN/NIGHT二进制列标识)下的1种食物(Food)+1种饮料(Bvg)的所有组合,生成包含时段(TIME)和组合(COMBINATION)的结果DataFrame,预期输出如下:
TIME COMBINATION MORNING Water, Noodle MORNING Juice, Noodle NIGHT Water, Rice NIGHT Tea, Bread MORNING Water, Rice
尝试将时段列合并为字符串列后按日期、用户、时段分组,但无法限制组合仅为1食1饮,寻求可行的解决方法或思路。
解决思路与代码实现
步骤1:拆分时段列,展开记录
原始数据里一条记录可能对应多个时段(比如第一条Water同时属于MORNING和NIGHT),先把二进制的时段列转成明确的TIME字段,同时把每条记录拆成对应时段的独立行:
import pandas as pd # 假设原始数据已加载为df,比如通过pd.read_csv()读取 # df = pd.read_csv("your_data.csv") # 定义时段列列表 time_columns = ['MORNING', 'AFTN', 'NIGHT'] # 用melt方法拆分时段列 df_expanded = df.melt( id_vars=['DATE', 'USER', 'TYPE', 'FOOD', 'BVG'], value_vars=time_columns, var_name='TIME', value_name='is_active' ) # 只保留实际属于该时段的记录 df_expanded = df_expanded[df_expanded['is_active'] == 1].drop('is_active', axis=1)
步骤2:拆分食物与饮料数据,做关联生成组合
把展开后的数据分成食物组和饮料组,再按DATE、USER、TIME做内关联,这样就能得到每个分组下的1食1饮组合:
# 提取食物数据,重命名字段方便后续关联 food_data = df_expanded[df_expanded['TYPE'] == 'Food'][['DATE', 'USER', 'TIME', 'FOOD']].rename(columns={'FOOD': 'food_item'}) # 提取饮料数据,同理重命名 bvg_data = df_expanded[df_expanded['TYPE'] == 'Bvg'][['DATE', 'USER', 'TIME', 'BVG']].rename(columns={'BVG': 'bvg_item'}) # 按日期、用户、时段关联,得到所有合法组合 combined = pd.merge( food_data, bvg_data, on=['DATE', 'USER', 'TIME'], how='inner' ) # 生成组合列,整理成目标格式 result_df = combined.assign( COMBINATION=combined['bvg_item'] + ', ' + combined['food_item'] )[['TIME', 'COMBINATION']] # 重置索引(可选操作) result_df = result_df.reset_index(drop=True)
验证结果
运行上述代码后,result_df的内容就和预期输出一致,会列出所有符合条件的1食1饮组合。
内容的提问来源于stack exchange,提问作者vins
相关产品推荐
相关产品推荐

