前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python中赋值以及平均值计算的两个小坑

python中赋值以及平均值计算的两个小坑

作者头像
自学气象人
发布2022-10-09 10:00:16
1.7K0
发布2022-10-09 10:00:16
举报
文章被收录于专栏:自学气象人自学气象人

以下全文代码和数据均已发布至和鲸社区,复制下面链接或者阅读原文前往,可一键fork跑通:

https://www.heywhale.com/mw/project/62f9033c738412246370ef04

前不久在测试python代码的时候,我发现了两个不容易被人关注到的小坑(也有可能是我没注意到,哈哈哈)。这里给大家浅浅地分享一下,一起避雷了!

一、python中的“=”、“numpy.copy”、“copy.deepcopy”

这个是关于在python中赋值的小坑,给大家看看下面的几个例子,大家应该就明白了。

我们先来建立一个初始数组a,然后分别用这三种方法来进行赋值。

代码语言:javascript
复制
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()方法是深复制(完全的复制了)。

代码语言:javascript
复制
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()方法无法复制其作用数组中所包含对象内的元素,属于浅复制。

代码语言:javascript
复制
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上。

代码语言:javascript
复制
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值(缺省值)。

代码语言:javascript
复制
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']

接着我们先来看一下正确计算的平均值是多少(也就是这五个数加起来的平均值)。

代码语言:javascript
复制
(1+2+3+4+5) / 5

当我们使用numpy.nanmean()方法计算时,可以看到是正确的结果。

代码语言:javascript
复制
np.nanmean(ds['temp'])

当我们使用xarray.mean()方法并同时输入两个维度“lat”“lon”计算时,可以看到是正确的结果。

代码语言:javascript
复制
ds['temp'].mean(dim=['lat','lon'])

当我们使用xarray.mean()方法并先对维度“lon”计算平均,再对维度“lat”计算平均时,可以看到结果偏离了正确的均值。

代码语言:javascript
复制
ds['temp'].mean(dim=['lon']).mean(dim=['lat'])

上面这种分步计算的方法等价于下面的计算。即由于存在nan值,所以计算时候分母发生了变化,导致分步计算的结果与正确计算结果之间出现偏差。如果没有nan值的话,这几种计算方法得到的结果就会一致。

大家也可以试试先计算“lat”再计算“lon”,结果也不会是3.0。这个问题在我们求区域平均时候要十分注意,切记检查是否有nan值,并据此选择合适的均值计算方法。

以上就是本文的全部内容。如有不妥之处,还望各位指正!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 自学气象人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档