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

如何为带日期索引的Pandas DataFrame每行应用函数生成新列?

问题描述

我有一个以日期为索引的Pandas DataFrame,编写了prevRate函数用于判断当日数值较前一日是上升还是下降。函数代码如下:

def prevRate(currentDate, df):
  prevDate = currentDate.date() - timedelta(days=1)
  prevRate =df.loc[prevDate,'Total per Million'].item()
  currentRate = df.loc[currentDate.date(),'Total  per Million'].item()

  if prevRate>currentRate:
    rateChange='inc'
  else:
    rateChange='dec'
  return rateChange

我希望将该函数应用到每个索引值,生成一个值为'inc'或'dec'的新列'rateChange',尝试了以下两种方式:

df['rateChange']=df.apply(prevRate(df.index.get_level_values(0).item().to_pydatetime(),df))
df['rateChange']=prevRate(df.index.item().to_pydatetime(),df)

但这些方法提取的是整个索引而非单个元素,报错信息如下:

ValueError                                Traceback (most recent call last)
<ipython-input-69-0d45be10dffa> in <module>
----> 1 df['rateChange']=df.apply(prevRate(df.index.item().to_pydatetime(),df))


  
      329         if len(self) == 1:
        330             return next(iter(self))
    ---> 331         raise ValueError("can only convert an array of size 1 to a Python scalar")
        332 
        333     @property
    
    ValueError: can only convert an array of size 1 to a Python scalar

请问该如何正确将函数应用到每行并生成新列?

解决方案

方法1:修正索引遍历逻辑

你之前的代码错误在于用df.index.item()提取索引,这个方法仅适用于单元素索引,多元素时直接触发报错。正确的做法是用df.index.map()逐个遍历每个日期索引:

from datetime import timedelta

def prevRate(currentDate, df):
    prevDate = currentDate.date() - timedelta(days=1)
    # 增加前一日数据存在性检查,避免KeyError
    if prevDate not in df.index:
        return 'unknown'  # 或根据需求返回None等默认值
    prevRate_val = df.loc[prevDate, 'Total per Million']
    currentRate_val = df.loc[currentDate.date(), 'Total per Million']
    return 'inc' if prevRate_val > currentRate_val else 'dec'

# 遍历每个索引日期,生成新列
df['rateChange'] = df.index.map(lambda dt: prevRate(dt, df))

方法2:用Pandas内置函数实现(更高效)

不需要自定义函数,直接用shift()获取前一日数据,结合numpy.where快速生成结果,性能比自定义函数遍历更好:

import numpy as np

# shift(1)将数据向下移动一行,即得到前一日的数值
prev_values = df['Total per Million'].shift(1)
# 对比当日与前一日数值,生成对应标记
df['rateChange'] = np.where(prev_values > df['Total per Million'], 'inc', 'dec')

错误原因总结

  • df.index.item()仅能处理单元素索引,你的DataFrame有多日期索引,因此触发ValueError。
  • 直接调用df.apply(prevRate(...))是错误用法,apply需要传入函数对象,而非提前执行函数的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:45:36