如何在Pandas DataFrame中按商品计算Rho列的差值
问题描述
我有如下Pandas DataFrame:
| index | N1 | N2 | N3 | N4 | N5 | time | CountN1 | CountN2 | CountN3 | CountN4 | CountN5 | resultN1 | resultN2 | resultN3 | resultN4 | resultN5 | RhoN1 | RhoN2 | RhoN3 | RhoN4 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | chocolate | sugar | milk | eggs | flour | 1 | 1 | 1 | 1 | 1 | 1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.4142135623730951 | 1.4142135623730951 | 1.4142135623730951 | 1.4142135623730951 |
| 1 | bread | pizza | soda | water | batteries | 2 | 1 | 1 | 1 | 1 | 1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 2.23606797749979 | 2.23606797749979 | 2.23606797749979 | 2.23606797749979 |
| 2 | plant | tea | coffe | chorizo | pasta | 3 | 1 | 1 | 1 | 1 | 1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 3.1622776601683795 | 3.1622776601683795 | 3.1622776601683795 | 3.1622776601683795 |
| 3 | tomatoes | bread | cheese | pasta | soda | 4 | 1 | 2 | 1 | 2 | 2 | 0.0 | 2.0 | 0.0 | 1.0 | 2.0 | 4.123105625617661 | 4.898979485566356 | 4.123105625617661 | 4.58257569495584 |
| 4 | Garlic | Onion | Rice | Bacon | Water | 5 | 1 | 1 | 1 | 1 | 2 | 0.0 | 0.0 | 0.0 | 0.0 | 3.0 | 5.0990195135927845 | 5.0990195135927845 | 5.0990195135927845 | 5.0990195135927845 |
其中:
- N1~N5列是顾客购买的商品,每行每个商品仅出现一次
- time为连续排序的时间
- CountN1~CountN5是对应商品的累计购买次数
- resultN1~resultN5是同一商品在不同顾客间的时间间隔
- RhoN1~RhoN4是对应商品的角度值
需要生成RhoN1_diff~RhoN5_diff列,计算每个商品对应Rho值的差值:比如商品bread在time=2时的Rho值是2.23606797749979,在time=4时的Rho值是4.898979485566356,二者差值为4.898979485566356-2.23606797749979=2.662911508066566。注意商品可能出现在任意N列中。
解决方案
通过数据重塑+分组计算差值+映射回原DataFrame的方式实现,具体步骤如下:
1. 重塑数据格式
将原DataFrame中商品列、Rho列和time列转换为长格式,方便按商品分组处理:
import pandas as pd # 假设原DataFrame名为df # 定义列名列表 n_cols = [f'N{i}' for i in range(1, 6)] rho_cols = [f'RhoN{i}' for i in range(1, 6)] # 原数据无RhoN5,后续会自动填充NaN # 拆分商品列和Rho列,合并为长格式数据 melted_products = df.melt( id_vars=['time'], value_vars=n_cols, var_name='N_col', value_name='product' ) melted_rho = df.melt( id_vars=['time'], value_vars=rho_cols, var_name='Rho_col', value_name='Rho' ) # 匹配商品列和对应的Rho列 melted = melted_products.merge( melted_rho, left_on=['time', 'N_col'], right_on=['time', melted_rho['Rho_col'].str.replace('Rho', '')] ).drop(columns=['N_col', 'Rho_col'])
2. 计算商品的Rho差值
按商品分组,计算当前行Rho与上一次出现时Rho的差值:
# 按商品分组,计算相邻出现的Rho差值 melted['Rho_diff'] = melted.groupby('product')['Rho'].diff()
3. 将差值映射回原DataFrame
把计算好的差值匹配到原DataFrame对应的列中:
# 构建商品+时间到差值的映射字典 diff_map = melted.set_index(['product', 'time'])['Rho_diff'].to_dict() # 为每个N列生成对应的差值列 for i in range(1, 6): n_col = f'N{i}' diff_col = f'RhoN{i}_diff' # 每行根据商品和时间获取差值,首次出现的商品差值设为0.0(可改为NaN) df[diff_col] = df.apply(lambda row: diff_map.get((row[n_col], row['time']), 0.0), axis=1)
最终结果示例
处理后关键列的结果如下:
- time=2时,
RhoN1_diff(对应bread)为0.0(首次出现无差值) - time=4时,
RhoN2_diff(对应bread)为2.662911508066566 - 原数据无RhoN5列,
RhoN5_diff全部为0.0
内容的提问来源于stack exchange,提问作者Bry Sab
相关产品推荐
相关产品推荐

