爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 360|回复: 2

[求助] 想用滑动阈值法定义极端降水事件,但是结果都是0,不知道哪里出了问题,求各位...

[复制链接]

新浪微博达人勋

发表于 2024-7-15 12:29:02 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
import numpy as np
import netCDF4 as nc
import csv
from datetime import datetime

def process_extreme_precip(file_path):
    dataset = nc.Dataset(file_path)

    precipitation = dataset.variables['tp'][:]
    times = dataset.variables['time'][:]

    extreme_precip_days_sum = np.zeros((4140 // 30))  # 存储每年的极端降水事件总数

    def calculate_90th_percentile(data):
        data_above_01 = data[data > 0.1]
        if len(data_above_01) > 0:
            sorted_data = np.sort(data_above_01)
            percentile_index = int(len(sorted_data) * 0.9)
            return sorted_data[percentile_index]
        else:
            return np.nan

    window_size = 11
    for t in range(window_size//2, precipitation.shape[0] - window_size//2):
        # 计算当前年份
        year = datetime.strptime(str(times[t])[:4], '%Y').year
        year_index = year - 1979  # 计算在数组中的索引
        for i in range(precipitation.shape[1]):
            for j in range(precipitation.shape[2]):
                window_data = precipitation[t - window_size//2:t + window_size//2 + 1, i, j]
                window_data = window_data[window_data > 0.1]
                if len(window_data) > 0:
                    threshold = calculate_90th_percentile(window_data)
                    if precipitation[t, i, j] > threshold:
                        extreme_precip_days_sum[year_index] += 1

    csv_file_path = r'C:\Users\Lenovo\Desktop\extreme_precip_days_sum1.csv'
    with open(csv_file_path, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['year', 'extreme_precip_total'])  # 修改标题行

        for year, total in enumerate(extreme_precip_days_sum, start=1979):
            writer.writerow([year, total])

    dataset.close()

if __name__ == "__main__":
    file_path = r'C:\Users\Lenovo\Desktop\extreme preciptation\ERA5_China_1979-2023_summer_dailysum_precipitation.nc'
    process_extreme_precip(file_path)


另外也有一个代码是拉长了时间窗口的但结果一样
import numpy as np
import netCDF4 as nc
import csv
from datetime import datetime

# 读取nc文件
file_path = r'C:\Users\Lenovo\Desktop\extreme preciptation\ERA5_China_1979-2023_summer_dailysum_precipitation.nc'
dataset = nc.Dataset(file_path)

# 获取降水数据,假设变量名为'precipitation'
precipitation = dataset.variables['tp'][:]

# 获取时间维度数据,假设变量名为'time'
times = dataset.variables['time'][:]

# 初始化极端降水天数总和数组
extreme_precip_days_sum = np.zeros((precipitation.shape[1], precipitation.shape[2], 4140 // 30))

# 定义一个函数来计算滑动窗口内大于0.1的降水数据的第90个百分位数
def calculate_90th_percentile(data):
    # 只对大于0.1的数据进行排序
    data_above_01 = data[data > 0.1]
    if len(data_above_01) > 0:
        sorted_data = np.sort(data_above_01)
        percentile_index = int(len(sorted_data) * 0.9)
        return sorted_data[percentile_index]
    else:
        return np.nan

# 计算滑动阈值
window_size = 11
for i in range(precipitation.shape[1]):
    for j in range(precipitation.shape[2]):
        for t in range(window_size//2, precipitation.shape[0] - window_size//2):
            # 计算窗口内的数据
            window_data = precipitation[t-window_size//2:t+window_size//2+1, i, j]
            window_data = window_data[window_data > 0.1]  # 过滤出大于0.1的数据
            if len(window_data) > 0:
                # 计算第90个百分位数
                threshold = calculate_90th_percentile(window_data)
                # 检查是否为极端降水事件
                if precipitation[t, i, j] > threshold:
                    extreme_precip_days_sum[i, j, t//30] += 1

# 输出结果到CSV文件
csv_file_path = r'C:\Users\Lenovo\Desktop\extreme_precip_days_sum.csv'
with open(csv_file_path, 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    # 写入标题行
    writer.writerow(['lat', 'lon', 'year', 'extreme_precip_days'])

    # 遍历每个格点
    for i in range(precipitation.shape[1]):
        for j in range(precipitation.shape[2]):
            for t in range(precipitation.shape[0] // 30):
                # 获取当前年份
                year = datetime.strptime(str(times[t*30])[:4], '%Y').year
                # 写入每个格点的数据
                writer.writerow([i, j, year, extreme_precip_days_sum[i, j, t]])

# 关闭文件
dataset.close()

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2024-7-17 15:14:15 | 显示全部楼层
码一下,看看后续
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2024-7-22 20:22:38 | 显示全部楼层
llyxxn. 发表于 2024-7-17 15:14
码一下,看看后续

谢谢,已经解决了,主要是浮点数的问题
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表