You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas按国家自定义时段条件分组求最小值的优化方案咨询

基于国家自定义时段的GroupBy最小值计算优化方案

需求:根据不同国家的自定义时段,对数据按scenario、country和对应时段分组,计算每组内value的最小值,并将结果映射回原数据的每一行。现有代码可正常运行,但需要更高效简洁的实现方案。

原始数据集

datetime                country  scenario  value
2023-01-01 00:00:00         FR      1         1  
2023-01-01 01:00:00         FR      1         2  
2023-01-01 02:00:00         FR      1         3  
2023-01-01 03:00:00         FR      1         4  
2023-01-01 01:00:00         DE      1         1  
2023-01-01 02:00:00         DE      1         2 
2023-01-01 03:00:00         DE      1         3  
2023-01-01 04:00:00         DE      1         4  

自定义时段字典

countries = {'DE':2,'FR':4}

当前实现代码

df3l=[]
for sc in scenarios: # iterate over countries
    df2l = []
    for c in countries: # iterate over scenarios
        df2 = df[ (df['scenario']==sc) & (df['country']==c)] # select country and scenario
        # compute min over period per country
        df2['min over period']= pd.DataFrame(df.groupby(['scenario','country',pd.Grouper(key='datetime', freq=str(countries[c])+'H')]).transform('min'))
        df2l.append(df2)
    df2 = pd.concat(df2l,axis=0)
    df3l.append(df2)
df = pd.concat(df3l,axis=0)

优化方案

方案1:向量化操作+分组Transform(最简洁高效)

核心思路:先为每行生成对应国家的时段分组标识,再通过一次分组+Transform完成最小值计算,彻底消除嵌套循环和重复数据拼接。

代码实现:

# 确保datetime列为datetime类型
df['datetime'] = pd.to_datetime(df['datetime'])

# 生成时段分组键:根据国家对应的时段,将时间向下取整到时段起始点
df['period'] = df.apply(lambda row: row['datetime'].floor(f"{countries[row['country']]}H"), axis=1)

# 计算时段内最小值并映射回原数据
df['min over period'] = df.groupby(['scenario', 'country', 'period'])['value'].transform('min')

# 可选:删除临时的period列
df = df.drop('period', axis=1)

方案2:批量分组处理,提升大数据量性能

若数据集规模较大,逐行apply可能存在性能瓶颈,可改为按country分组批量生成时段标识:

df['datetime'] = pd.to_datetime(df['datetime'])

# 按country分组,批量生成时段键
def get_period(group):
    freq = f"{countries[group.name]}H"
    return group['datetime'].floor(freq)

df['period'] = df.groupby('country')['datetime'].transform(get_period)

# 计算时段最小值
df['min over period'] = df.groupby(['scenario', 'country', 'period'])['value'].transform('min')
df = df.drop('period', axis=1)

方案3:针对性修复原代码的冗余问题

原代码存在重复分组全量数据、多次筛选拼接的问题,可先完成分组计算再合并回原数据:

df['datetime'] = pd.to_datetime(df['datetime'])

# 按scenario+country分组后,分别计算对应时段的最小值
result = df.groupby(['scenario', 'country']).apply(
    lambda g: g.groupby(pd.Grouper(key='datetime', freq=f"{countries[g.name[1]]}H"))['value'].min()
).reset_index(name='min over period')

# 将结果合并回原数据
df = df.merge(result, on=['scenario', 'country', 'datetime'], how='left')

优化效果说明

  • 消除嵌套循环和多次concat,代码量减少60%以上
  • 避免重复分组全量数据,计算效率随数据量增大提升更明显
  • 逻辑更清晰,可读性和可维护性更强

内容的提问来源于stack exchange,提问作者Peslier53

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:57:12