以下全文代码和数据均已发布至和鲸社区,复制下面链接或者阅读原文前往,可一键fork跑通:
https://www.heywhale.com/mw/project/62f9033c738412246370ef04
前不久在测试python代码的时候,我发现了两个不容易被人关注到的小坑(也有可能是我没注意到,哈哈哈)。这里给大家浅浅地分享一下,一起避雷了!
一、python中的“=”、“numpy.copy”、“copy.deepcopy”
这个是关于在python中赋值的小坑,给大家看看下面的几个例子,大家应该就明白了。
我们先来建立一个初始数组a,然后分别用这三种方法来进行赋值。
import numpy as np
import copy as cp
a = np.array([9,'自学气象人',[1,2,3],[997,998,999]])
b = a
c = np.copy(a)
d = cp.deepcopy(a)
print('a',a)
print('b',b)
print('c',c)
print('d',d)
现在,我们先来改变d中的三个元素的值,看看初始数组a会不会发生变化。可以看到,改变采用copy.deepcopy()方法赋值的d数组中的数值,完全不会影响到初始数组a的值。即copy.deepcopy()方法是深复制(完全的复制了)。
print('改变前的a',a)
print('改变前的d',d)
d[0] = -1
d[1] = '好好学习'
d[2] = ['天天向上']
d[3][1] = 1000
print('改变后的d',d)
print('改变后的a',a)
接着,我们再来改变c中的三个元素的值,看看初始数组a会不会发生变化。可以看到,改变采用numpy.copy()方法赋值的c数组中的数值,会部分影响到初始数组a中的值。这仅发生于我们改变初始数组a中的列表中的元素(改变整个列表则不会影响初始数组a),也即numpy.copy()方法无法复制其作用数组中所包含对象内的元素,属于浅复制。
print('改变前的a',a)
print('改变前的c',c)
c[0] = -1
c[1] = '好好学习'
c[2] = ['天天向上']
c[3][1] = 1000
print('改变后的c',c)
print('改变后的a',a)
最后,我们来看一下改变b中的三个元素的值,看看初始数组a会不会发生变化。可以看到,改变采用 “=” 方法赋值的b数组中的数值,会完全地影响到初始数组a中的值。即对b进行的操作会完全地同步到初始数组a上。
print('改变前的a',a)
print('改变前的b',b)
b[0] = -1
b[1] = '好好学习'
b[2] = ['天天向上']
b[3][1] = 1000
print('改变后的b',b)
print('改变后的a',a)
二、python中的“np.nanmean”、“xarray.mean”
这个呢,是python中求平均值的小坑(当计算的数据中存在nan值时会出现)。同样给大家看看下面几个例子,一起来具体地感受一下。
首先我们来创建个dataset,其中有一个nan值(缺省值)。
import xarray as xr
import numpy as np
import pandas as pd
data = np.array([[1, np.nan, 2],
[3, 4, 5]])
da = xr.DataArray(
data,
[
("lat", np.array([10,11])),
("lon", np.array([1,2,3]))],
)
ds = da.to_dataset(name="temp")
ds['temp']
接着我们先来看一下正确计算的平均值是多少(也就是这五个数加起来的平均值)。
(1+2+3+4+5) / 5
当我们使用numpy.nanmean()方法计算时,可以看到是正确的结果。
np.nanmean(ds['temp'])
当我们使用xarray.mean()方法并同时输入两个维度“lat”“lon”计算时,可以看到是正确的结果。
ds['temp'].mean(dim=['lat','lon'])
当我们使用xarray.mean()方法并先对维度“lon”计算平均,再对维度“lat”计算平均时,可以看到结果偏离了正确的均值。
ds['temp'].mean(dim=['lon']).mean(dim=['lat'])
上面这种分步计算的方法等价于下面的计算。即由于存在nan值,所以计算时候分母发生了变化,导致分步计算的结果与正确计算结果之间出现偏差。如果没有nan值的话,这几种计算方法得到的结果就会一致。
大家也可以试试先计算“lat”再计算“lon”,结果也不会是3.0。这个问题在我们求区域平均时候要十分注意,切记检查是否有nan值,并据此选择合适的均值计算方法。
以上就是本文的全部内容。如有不妥之处,还望各位指正!