向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 # 错误发生处
错误原因
- pandas的loc赋值逻辑问题:当使用
df.loc[i, 'Month_Diff']给单个单元格赋值列表时,pandas会将列表视为要分配给多个行的序列,而非单个单元格的值。由于列表长度和目标行数量(1行)不匹配,因此抛出长度不相等的错误。 - 变量名拼写错误:代码中
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
相关产品推荐
相关产品推荐

