如何以最Pythonic的方式按城市计算Pandas DataFrame行比值?
按城市分组计算value列的前后行比值
这是个很典型的Pandas分组计算场景,我来给你讲讲最Pythonic的实现方式~
首先先确认你的原始数据和结构:
import pandas as pd df = pd.DataFrame() df['city'] = ['NY','NY','LA','LA'] df['hour'] = ['0','12','0','12'] df['value'] = [12,24,3,9]
对应的DataFrame结构:
city hour value 0 NY 0 12 1 NY 12 24 2 LA 0 3 3 LA 12 9
你需要按city分组,计算每组内后一行value与前一行的比值,最终得到每个城市的结果。这里分两种情况给你提供方案:
针对当前固定两行的简洁写法
因为你的数据里每个城市恰好只有两行(0点和12点),可以直接定位每组的第二行和第一行做除法,代码非常简洁高效:
result = df.groupby('city')['value'].apply(lambda x: x.iloc[1]/x.iloc[0]).reset_index(name='ratio')
通用的前后行比值计算(适配多行分组)
如果以后你的数据每组可能包含更多行,想要通用的“后一行除以前一行”逻辑,可以用shift()方法实现:
# 计算每组内每行与前一行的比值,去掉无前置行的NaN后整理格式 result = ( df.groupby('city')['value'] .apply(lambda x: x / x.shift()) .dropna() .reset_index(name='ratio') .drop(columns='level_1') )
两种方案都会得到你期望的输出:
city ratio 0 NY 2.0 1 LA 3.0
简单解释下逻辑:
- 第一种方案利用了当前数据的固定结构,直接通过
iloc索引取值计算,性能最优。 - 第二种方案更通用,
x.shift()会把每组的value序列整体上移一位,和原序列做除法就得到了前后行的比值,dropna()去掉每组第一行的无效值,最后整理成目标格式。
内容的提问来源于stack exchange,提问作者sato
相关产品推荐
相关产品推荐

