为何填充函数单独运行正常,作为PySpark UDF却报错?
问题原因
当输入数组的尺寸(高度/宽度)大于目标尺寸(224,224)时,计算得到的pad_h或pad_w会是负数(比如原高度300,(224-300)//2 = -38),而np.pad不接受负的padding参数,因此抛出ValueError: index can't contain negative values。
直接调用函数时正常,是因为你测试的输入数据尺寸都小于等于目标尺寸;而Spark数据集里存在尺寸超过224x224的样本,触发了这个问题。
解决方法
修改pad函数,先对超过目标尺寸的数组做中心裁剪,再对不足的部分做padding,确保padding值始终非负:
def pad(array, target_size=(224, 224), pad_value=255): h, w = array.shape[0], array.shape[1] target_h, target_w = target_size # 先处理尺寸超过目标的情况:中心裁剪到目标尺寸 if h > target_h: crop_h_start = (h - target_h) // 2 array = array[crop_h_start:crop_h_start+target_h, :, :] h = target_h if w > target_w: crop_w_start = (w - target_w) // 2 array = array[:, crop_w_start:crop_w_start+target_w, :] w = target_w # 再计算padding并填充 pad_h = (target_h - h) // 2 pad_w = (target_w - w) // 2 padded_array = np.pad( array, ((pad_h, pad_h), (pad_w, pad_w), (0, 0)), mode='constant', constant_values=(pad_value, pad_value) ) processed_array_bytes = padded_array.tobytes() return processed_array_bytes
额外建议
如果担心Spark任务因单个错误样本崩溃,可以在顶层函数里加异常捕获:
def top_level(input_data): try: array = first_steps(input_data) final_array = pad(array) return final_array except Exception: # 出现异常时返回空值,后续可筛选处理错误样本 return None
内容的提问来源于stack exchange,提问作者T_d
相关产品推荐
相关产品推荐

