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

向Pandas DataFrame单元格赋值列表报错及月份差计算求助

DataFrame赋值列表单元格时的ValueError错误解决

问题场景

现有名为dfTest的DataFrame,结构及数据如下:

Date1_Year  Date1_Month  DateList
2020        5            ['2020-04','2020-01']
2020        9            ['2020-08','2020-07','2020-06']
2021        9            ['2021-09']
2020        12           ['2020-10','2020-01'] 
1999        03           NaN

需求是计算Date1_Year+Date1_Month组成的日期与DateList中每个日期的月份差,期望输出:

Date1_Year  Date1_Month  DateList                         Month_Diff
2020        5            ['2020-04','2020-01']            [1,4]
2020        9            ['2020-08','2020-07','2020-06']  [1,2,3]
2021        9            ['2021-09']                      [0]
2020        12           ['2020-10','2020-01']            [2,11]
1999        03           NaN                              

编写的代码如下,但执行赋值时抛出ValueError: must have equal len keys and value when setting an iterable错误:

for i in range(len(dfTest)):
    My_Date_List = dfTest.loc[i,'DateList']
    Date1Months = dfTest.loc[i,'Date1_Year']*12 + dfTest.loc[i,'Date1_Month']
    months_since_date1 = []

    if isinstance(My_Date_List,list):
        if len(My_Date_List) >= 1:
            for j in range(len(My_Date_List)):
                Date2_Year = int(My_Date_List[j][:4])
                Date2_Month = int(My_Date_list[j][5:])  # 变量名大小写错误
                Date2Months = Date2_Year*12 + Date2_Month
                if Date1Months < Date2Months:
                    months_since_date1.append(-999)
                else:
                    months_since_date1.append(Date1Months-Date2Months)
             dfTest.loc[i,'Month_Diff'] = months_since_date1  # 错误发生处

错误原因

  1. pandas的loc赋值逻辑问题:当使用df.loc[i, 'Month_Diff']给单个单元格赋值列表时,pandas会将列表视为要分配给多个行的序列,而非单个单元格的值。由于列表长度和目标行数量(1行)不匹配,因此抛出长度不相等的错误。
  2. 变量名拼写错误:代码中My_Date_list[j]应为My_Date_List[j](大小写不一致),这会导致NameError,也是需要修复的潜在问题。

修正方案

方案1:使用at替代loc进行单个单元格赋值

at是pandas专门用于访问/设置单个单元格值的方法,支持直接将列表作为单元格值赋值,不会触发序列长度检查。

方案2:修正变量名拼写错误

将My_Date_list[j]改为My_Date_List[j],避免变量未定义错误。

修正后的完整代码

for i in range(len(dfTest)):
    My_Date_List = dfTest.loc[i,'DateList']
    Date1Months = dfTest.loc[i,'Date1_Year']*12 + dfTest.loc[i,'Date1_Month']
    months_since_date1 = []

    if isinstance(My_Date_List, list):
        if len(My_Date_List) >= 1:
            for j in range(len(My_Date_List)):
                Date2_Year = int(My_Date_List[j][:4])
                Date2_Month = int(My_Date_List[j][5:])  # 修正变量名大小写
                Date2Months = Date2_Year*12 + Date2_Month
                if Date1Months < Date2Months:
                    months_since_date1.append(-999)
                else:
                    months_since_date1.append(Date1Months-Date2Months)
        dfTest.at[i, 'Month_Diff'] = months_since_date1  # 使用at赋值列表

额外优化建议

可以避免使用循环,改用apply方法提升效率,示例代码如下:

def calculate_month_diff(row):
    date1_months = row['Date1_Year'] * 12 + row['Date1_Month']
    date_list = row['DateList']
    if not isinstance(date_list, list):
        return None
    diffs = []
    for date_str in date_list:
        year = int(date_str[:4])
        month = int(date_str[5:])
        date2_months = year * 12 + month
        if date1_months < date2_months:
            diffs.append(-999)
        else:
            diffs.append(date1_months - date2_months)
    return diffs

dfTest['Month_Diff'] = dfTest.apply(calculate_month_diff, axis=1)

这种方式更符合pandas的向量化操作习惯,尤其在数据量较大时性能更优。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:10:26