Python实现同尺寸数组对应元素求和及月度均值计算
问题:Copernicus海洋温度数据月度均值计算(在线访问)
我是Python新手,可能我的问题已有解答,但我对相关方案的代码实现(尤其是函数定义)不太熟悉,若有重复提问请见谅。
我处理Copernicus的每日海洋温度数据,因多年月度每日数据的NetCDF文件过大,需直接在线访问数据而非下载。
数据以单日数组形式存储,我需要实现月度所有日期数组的对应元素求和,最终计算月度均值。
简化示例
单日数据示例
import numpy as np array1 = np.array([[1,4,3,9], [7,5,2,3]]) array2 = np.array([[3,8,6,1], [6,4,7,2]]) # ... 直到当月最后一天(28/29/30/31)
期望求和结果
# 对应元素求和 sum_array = array1 + array2 # 结果: # [[4,12,9,10], # [13,9,9,5]]
最终月度均值(以3天为例)
array3 = np.array([[3,2,6,1], [1,3,5,2]]) mean_array = (array1 + array2 + array3) / 3 # 结果示例: # [[2.3,4.6,5,3.6], # [4.6,4.3,4.6,2.3]]
已实现的两天数据求和代码
import os import xarray as xr import numpy as np import netCDF4 as nc import copernicusmarine # 在线访问数据集 DS = copernicusmarine.open_dataset(dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m") # 获取2014-01-01的表层温度数据 subset = DS[['thetao']].sel(time = slice("2014-01-01", "2014-01-01")) target_depth = 0 # 表层 subset_T = subset.thetao.isel(depth=target_depth) thetao_depth0 = subset_T.data # 获取2014-01-02的表层温度数据 subset2 = DS[['thetao']].sel(time = slice("2014-01-02", "2014-01-02")) subset_T2 = subset2.thetao.isel(depth=target_depth) thetao_depth0_2 = subset_T2.data # 两天数据求和 days_sum = thetao_depth0 + thetao_depth0_2 days_sum
遇到的问题
我尝试用循环遍历月度所有日期实现累加,但无法完成求和,尝试np.sum也未成功,初始化空数组后不知后续操作,循环代码如下:
day = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'] month = ['01'] year = ['2014'] DS = copernicusmarine.open_dataset(dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m") for y in year: for m in month: for d in day: start_date="%s"%y+"-%s"%m+"-%s"%d end_date=start_date subset_thetao = DS[['thetao']].sel(time = slice(start_date, end_date)) target_depth = 0 subset_depth = subset_thetao.thetao.isel(depth=target_depth) thetao_depth0 = subset_depth.data
解决方案
方案1:改进循环实现累加
核心思路是初始化零数组用于累加,同时跳过无效日期,最后除以有效天数得到均值:
import xarray as xr import numpy as np import copernicusmarine from datetime import datetime year = '2014' month = '01' target_depth = 0 # 在线访问数据集 DS = copernicusmarine.open_dataset(dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m") total_sum = None valid_days = 0 # 遍历所有可能日期 for day_str in ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31']: try: # 验证日期合法性 datetime.strptime(f"{year}-{month}-{day_str}", "%Y-%m-%d") date_str = f"{year}-{month}-{day_str}" # 获取当日表层温度数据 subset = DS['thetao'].sel(time=slice(date_str, date_str)).isel(depth=target_depth) daily_data = subset.data # 初始化求和数组 if total_sum is None: total_sum = np.zeros_like(daily_data) # 累加数据 total_sum += daily_data valid_days += 1 except ValueError: # 跳过无效日期 continue # 计算月度均值 monthly_mean = total_sum / valid_days print(monthly_mean)
方案2:使用xarray内置时间聚合(推荐)
xarray支持直接对时间维度分组聚合,代码更简洁高效,无需手动处理日期:
import xarray as xr import copernicusmarine year = '2014' month = '01' target_depth = 0 # 在线访问数据集 DS = copernicusmarine.open_dataset(dataset_id="cmems_mod_glo_phy_my_0.083deg_P1D-m") # 筛选目标年月的表层温度数据 surface_temp = DS['thetao'].sel(time=slice(f"{year}-{month}-01", f"{year}-{month}-31")).isel(depth=target_depth) # 直接计算月度均值 monthly_mean = surface_temp.groupby('time.month').mean(dim='time') # 转换为numpy数组(如果需要) monthly_mean_array = monthly_mean.data print(monthly_mean_array)
说明:如果需要先求和再计算均值,可替换为:
monthly_sum = surface_temp.sum(dim='time') monthly_mean = monthly_sum / surface_temp.time.size
内容的提问来源于stack exchange,提问作者Camille
相关产品推荐
相关产品推荐

