Python中对lights1992列执行np.log对数转换报错问题排查
报错核心原因
问题出在zonal_stats的返回值特性,你之前尝试的类型转换、+1操作没有覆盖到异常场景:
- 当矢量要素完全落在栅格nodata区域时,即使你在
zonal_stats里指定了nodata=np.nan,部分版本的rasterstats返回的mean不是np.nan,而是Python原生None或者numpy掩码对象np.ma.masked。 - 你直接把生成的列表赋值给DataFrame列时,因为绝大多数值是正常浮点数,pandas会把列的dtype显示为
float64,但数组里混杂的少量特殊对象不会被自动转成合法浮点值。这时候调用np.log做向量化运算,遇到这些特殊对象就会触发类型错误;单纯调用pd.to_numeric不加参数、或者直接做+1运算,都无法彻底清理这类特殊值,自然没法解决报错。 - 额外可能触发报错的点:如果栅格值本身存在0或者负数,会超出对数函数的正实数定义域,触发运算域错误。
修复方案
按以下步骤处理即可:
- 从源头清理zonal_stats返回的异常值,赋值列的时候就做强制转换,把所有非法值统一转成
np.nan:
import numpy as np import pandas as pd from rasterstats import zonal_stats zs1 = zonal_stats(city_join, junk1992, stats=['mean'], nodata=np.nan) # 提取值的时候直接做数值转换,非法值统一转为NaN city_join['lights1992'] = pd.to_numeric( [x['mean'] for x in zs1], errors='coerce' )
- 处理对数运算的定义域问题,根据你的数据场景选对应转换方式:
# 先排查列里是否存在小于等于0的无效值 invalid_count = city_join[city_join['lights1992'] <= 0].shape[0] # 场景1:小于等于0的值都是无数据,直接过滤后取对数 city_join['log_lights1992'] = np.log( city_join['lights1992'].where(city_join['lights1992'] > 0) ) # 场景2:需要保留0值样本(比如灯光亮度为0的无灯光区域),确认不存在<-1的值后,用log1p等价转换更稳妥 # city_join['log_lights1992'] = np.log1p(city_join['lights1992'])
注:
np.log1p(x)等价于np.log(x+1),但对浮点精度的处理更友好,适合处理包含0值的非负序列。
- 校验结果:如果执行后依然报错,运行下面代码检查列内是否残留非浮点类型对象:
# 统计列内各值的实际类型,排查残留特殊对象 print(city_join['lights1992'].apply(lambda x: type(x).__name__).value_counts())
正常情况下输出应该只有float一类,没有其他类型。
内容的提问来源于stack exchange,提问作者OgeiD
相关产品推荐
相关产品推荐

