如何按水果分组,基于index_value=100的基准年计算后续年份index列?
解决按分组基准行计算后续年份指数的问题
我来帮你搞定这个需求!你想要按fruit分组,把每组里index_value等于100的行作为基准年,计算该行之后所有年份的index列。先说说你原来代码的问题:你用了x.iloc[0]取每组第一行的价格当基准,但这完全没考虑到我们需要的是指定的基准行(就是index_value=100的那些行),而且也没法处理同一组里有多个基准点的情况(比如你的例子里apple有1961和1963两个基准年)。
解决方案代码
首先我们得保证数据按fruit和year排序,这样基准年之后的年份顺序是对的,然后分组处理基准价格并计算指数:
import pandas as pd # 假设你的原始DataFrame是这个样子 data = { 'fruit': ['apple', 'apple', 'apple', 'apple', 'banana', 'banana', 'apple'], 'year': [1960, 1961, 1962, 1963, 1960, 1961, 1964], 'price': [11, 12, 13, 13, 11, 12, 11], 'index_value': [None, 100, None, 100, None, None, None], 'Boolean': [None, True, None, True, None, None, None], 'index': [None, None, None, None, None, None, None] } df = pd.DataFrame(data) # 第一步:按fruit和year排序,确保年份顺序正确 df = df.sort_values(['fruit', 'year']).reset_index(drop=True) # 第二步:生成基准价格列,只有index_value=100的行保留价格,其余为NaN df['base_price'] = df['price'].mask(df['index_value'] != 100) # 第三步:按fruit分组向前填充基准价格,让后续行都使用最近的基准价 df['base_price'] = df.groupby('fruit')['base_price'].ffill() # 第四步:计算index列,只有基准价存在的行才计算,否则留空 df['index'] = df.apply( lambda row: round((row['price'] / row['base_price']) * 100) if pd.notna(row['base_price']) else None, axis=1 ) # 移除临时的base_price列 df = df.drop('base_price', axis=1) # 查看结果 print(df)
代码解释
- 排序:先按
fruit和year排序,保证每个分组内的年份是递增的,这样基准年之后的行能正确继承基准价格。 - 生成基准价格列:用
mask方法把非基准行的价格设为NaN,只有index_value=100的行保留原始价格。 - 向前填充基准价:按
fruit分组后用ffill()(向前填充),这样基准年之后的每一行都会使用最近的那个基准年的价格。比如apple的1962年用1961年的基准价,1964年用1963年的基准价。 - 计算指数:对有基准价的行,用
(当前价格/基准价格)*100取整得到index,没有基准价的行(比如基准年之前的行、没有基准行的banana组)则留空。
输出结果
运行后得到的结果和你期望的完全一致:
fruit year price index_value Boolean index 0 apple 1960 11 NaN None NaN 1 apple 1961 12 100.0 True 100.0 2 apple 1962 13 NaN None 108.0 3 apple 1963 13 100.0 True 100.0 4 apple 1964 11 NaN None 84.0 5 banana 1960 11 NaN None NaN 6 banana 1961 12 NaN None NaN
内容的提问来源于stack exchange,提问作者asd
相关产品推荐
相关产品推荐

