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

为Pandas DataFrame应用多输入多输出函数时触发形状异常

问题分析与解决方案

你遇到的Shape of passed values is (1816, 2), indices imply (1816, 6)错误,核心原因是apply(axis=1)的返回结构和你预期的不符:你的函数返回两个值,但在当前pandas环境下,apply将其解析成了两列的DataFrame,而不是每个元素为二元组的Series,这就导致zip(*...)解包后的结构无法匹配原DataFrame的列数要求。

下面给出两种针对性的解决方案,同时优化你的代码可读性和准确性:

方案一:直接返回Series,批量赋值新列

修改函数返回为pd.Series,让apply直接生成包含结果的DataFrame,然后一次性赋值给新列:

import numpy as np
import pandas as pd

def calculate_solar_params(row):
    gsc = 1367
    phi = np.deg2rad(row['Latitude'])
    date = row['Date']
    
    # 直接从datetime对象获取年月日,避免冗余的DatetimeIndex创建
    year = date.year
    month = date.month
    day = date.day
    
    # 更准确的闰年判断逻辑(处理整百年情况)
    is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    B = (day - 1) * (360 / 366) if is_leap else (day - 1) * (360 / 365)
    B = np.deg2rad(B)
    
    delta = (0.006918 - 0.399912*np.cos(B) + 0.070257*np.sin(B) 
             - 0.006758*np.cos(2*B) + 0.000907*np.sin(2*B) 
             - 0.002697*np.cos(3*B) + 0.00148*np.sin(3*B))
    
    ws = np.arccos(-np.tan(phi) * np.tan(delta))
    daylength = (2/15) * np.rad2deg(ws)  # 修正拼写错误
    
    dayangle = np.deg2rad(360 * day / 366) if is_leap else np.deg2rad(360 * day / 365)
    h0_value = (24*3600*gsc/np.pi) * (1 + 0.033*np.cos(dayangle)) * (np.cos(phi)*np.cos(delta)*np.sin(ws) + ws*np.sin(phi)*np.sin(delta))
    
    # 返回Series,指定列名更清晰
    return pd.Series([h0_value, daylength], index=['h0', 'daylength'])

# 直接将结果赋值给新列
ak[['h0', 'N']] = ak.apply(calculate_solar_params, axis=1)

方案二:强制返回元组,用zip解包

如果希望继续使用zip(*...)的方式,需要确保apply返回的是每个元素为二元组的Series,同时优化代码细节:

import numpy as np
import pandas as pd

def calculate_solar_params(row):
    gsc = 1367
    phi = np.deg2rad(row['Latitude'])
    date = row['Date']
    
    year = date.year
    month = date.month
    day = date.day
    
    is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    B = (day - 1) * (360 / 366) if is_leap else (day - 1) * (360 / 365)
    B = np.deg2rad(B)
    
    delta = (0.006918 - 0.399912*np.cos(B) + 0.070257*np.sin(B) 
             - 0.006758*np.cos(2*B) + 0.000907*np.sin(2*B) 
             - 0.002697*np.cos(3*B) + 0.00148*np.sin(3*B))
    
    ws = np.arccos(-np.tan(phi) * np.tan(delta))
    daylength = (2/15) * np.rad2deg(ws)
    
    dayangle = np.deg2rad(360 * day / 366) if is_leap else np.deg2rad(360 * day / 365)
    h0_value = (24*3600*gsc/np.pi) * (1 + 0.033*np.cos(dayangle)) * (np.cos(phi)*np.cos(delta)*np.sin(ws) + ws*np.sin(phi)*np.sin(delta))
    
    # 显式返回元组,确保apply生成Series of tuples
    return (h0_value, daylength)

# 解包并赋值新列
ak['h0'], ak['N'] = zip(*ak.apply(calculate_solar_params, axis=1))

额外优化说明

  1. 修正了变量名daylenght的拼写错误为daylength,避免后续使用混淆;
  2. 替换了冗余的pd.DatetimeIndex创建逻辑,直接从datetime对象获取年月日,提升代码效率;
  3. 使用更严谨的闰年判断逻辑,支持整百年的闰年校验(比如2000年是闰年,1900年不是);
  4. 将函数内的h0变量名改为h0_value,避免和函数名冲突,提高代码可读性。

内容的提问来源于stack exchange,提问作者Erol Can Akbaba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:37:30