如何在分组DataFrame中按条件检查并交换产品数值?
按日期检查并交换棉花与咖啡的数值,确保棉花价格始终更高
我有一个按date(日期)和product(产品)分组、value(数值)为均值的DataFrame。已知棉花(cotton)的价格应该始终高于咖啡(coffee),需要按日期逐一检查,当不符合该条件时交换两者的value值。
当前DataFrame
| date | product | value |
|---|---|---|
| 01/01/2023 | cotton | 500.00 |
| coffee | 300.00 | |
| 02/01/2023 | cotton | 400.00 |
| coffee | 600.00 |
期望输出DataFrame
| date | product | value |
|---|---|---|
| 01/01/2023 | cotton | 500.00 |
| coffee | 300.00 | |
| 02/01/2023 | cotton | 600.00 |
| coffee | 400.00 |
解决方案(Pandas实现)
步骤1:处理空日期并构造DataFrame
原始数据中同一日期的第二行(coffee)日期为空,先通过向前填充补全日期,确保后续分组处理正常:
import pandas as pd # 构造原始数据 data = { 'date': ['01/01/2023', '', '02/01/2023', ''], 'product': ['cotton', 'coffee', 'cotton', 'coffee'], 'value': [500.00, 300.00, 400.00, 600.00] } df = pd.DataFrame(data) # 填充空日期 df['date'] = df['date'].ffill()
步骤2:转宽表便于比较
将数据转为宽表格式,让同一日期的棉花和咖啡值处于同一行,方便直接比较:
df_wide = df.pivot(index='date', columns='product', values='value').reset_index()
步骤3:检查并交换数值
筛选出棉花价格低于咖啡的日期,交换两者的数值:
# 生成布尔掩码,标记需要交换的日期 mask = df_wide['cotton'] < df_wide['coffee'] # 交换不符合条件的行的cotton和coffee值 df_wide.loc[mask, ['cotton', 'coffee']] = df_wide.loc[mask, ['coffee', 'cotton']].values
步骤4:转回长表并恢复原始格式
将宽表转回长表,同时把每个日期对应的咖啡行的日期设为空,匹配原始数据格式:
# 转回长表 df_result = df_wide.melt(id_vars='date', var_name='product', value_name='value') # 将每个日期的第二行(咖啡)的date设为空 df_result.loc[df_result.groupby('date').cumcount() == 1, 'date'] = ''
执行上述代码后,df_result即为期望的结果。
内容的提问来源于stack exchange,提问作者Vinícius Tomazoni
相关产品推荐
相关产品推荐

