前言
本文记录和鲸社区的Python刷题记录及题解。
2.1_气象Python中常用的基本库
Q1: 读取/home/mw/input/fnl6384/fnl/文件夹下所有 GRIB2 文件,计算其中最早和最晚两个时间之间相差多少小时。然后对这个小时值求 sin 值。请问这个值的前 5 位有效数字是多少?
提示:
- 注意什么是有效数字,及其“四舍六入五留双”的修约规则。如,0.12345 的 前 4 位有效数字为 1234。
- 在下方 cell 中编写并运行你的代码,将结果赋值给 a1。
题解代码
import numpy as np
import os
import math
import re
from datetime import datetime
dir_path = "/home/mw/input/fnl6384/fnl/" # 目录路径
files = os.listdir(dir_path) # 获取目录下的所有文件名列表
# 定义正则表达式,用于从文件名中提取时间信息
pattern = r'fnl_(\d{8})_(\d{2})_(\d{2})\.grib2'
# 获取目录下的所有文件名
files = os.listdir('/home/mw/input/fnl6384/fnl/')
# 从文件名中提取时间信息,并存储到字典中
time_dict = {}
for file in files:
match = re.search(pattern, file)
if match:
time_str = match.group(1) + match.group(2) + match.group(3)
time_dict[file] = int(time_str)
# 按照时间顺序对文件名进行排序
sorted_files = sorted(time_dict, key=time_dict.get)
# 输出排序后的文件名列表
print(sorted_files)
a = sorted_files[0]
b = sorted_files[-1]
print(a)
print(b)
c = math.sin(738)
print(c)
a1 = 27085
2.2_NumPy 数组基础
Q1: 生成两个数组,两者的大小都为(10000000,),元素都在[0,1]的区间内随机分布。对两者相同位置上的每个元素分别求平方和,然后保存到另一个(10000000,)的数组中。计算这个数组中小于 1 的数组的个数,并将其除以 10000000,再乘以 400。这个值取整后是多少?
提示:想一想,上面的操作究竟是在干什么?如果你想通的话,也许根本不用计算,就能答出来这个问题了。
import xarray as xr
# 生成两个数组
arr1 = np.random.rand(10000000)
arr2 = np.random.rand(10000000)
# 计算两个数组对应元素的平方和
sums = np.square(arr1) + np.square(arr2)
# 统计符合条件的数组元素个数
count = np.count_nonzero(sums < 1)
# 计算结果并输出
result = int(np.round(count / 10000000 * 400))
print(result)
2.3 Pandas数据帧基础
Q1: 读取 /home/mw/input/beijing_weather5275/beijing_weather.csv 文件,计算 2021-09-18 00:00:00~2021-09-24 00:00:00 北京最高和最低露点温度之差(保留整数位)。
import pandas as pd
import numpy as np
df = pd.read_csv("/home/mw/input/beijing_weather5275/beijing_weather.csv")
df = df.replace(999999.000000, np.nan) #异常值替换为nan
def ludian(t,rh):
if np.isnan(t) or np.isnan(rh):
return np.nan
else:
return 237.7*(17.27*t/(237.7+t) + np.log( rh/100 ))/(17.27-(17.27*t/(237.7+t) + np.log( rh/100 ))) #求露点温度的公式
df['ludian'] = df.apply(lambda x : ludian(x['t'],x['rh']),axis=1)
#将计算的露点温度加入dataframe
df.describe()
#可以查看露点温度的最大值和最小值
a1=int(df.loc[:,"ludian"].max()-df.loc[:,"ludian"].min())
2.4_使用Python处理常见气象数据
Q1: 读取/home/mw/input/fnl6384/fnl/fnl_20210101_00_00.grib2文件,计算2021年1月1日0时,北半球(含赤道)地表以上 2 米( 注意:不是 2 米以上)温度最高值和最低值之差(保留整数)。提示:注意是北半球!可以用类似于 NumPy 中的切片方法,截取出北半球部分,然后再进行计算。
import xarray as xr
ds = xr.open_dataset("/home/mw/input/fnl6384/fnl/fnl_20210101_00_00.grib2",engine="pynio")
# 读取数据
tem=ds['TMP_P0_L103_GLL0'][0,][0:91,:]
#第二个方括号索引是第0维:地表2米数据;第三个方括号索引是经纬度坐标(赤道及以北)。
t= tem.max()-tem.min() #最大值-最小值
a1=int(t)
a1
2.5_使用Python处理常见气象数据
Q1. 站点气象数据的处理
在 /home/mw/input/beijing_weather5275/beijing_weather.csv 文件中,计算温度在 20 摄氏度以上(含)、相对湿度在55%以上(含)的时间中,平均露点温度(单位:摄氏度)是多少?(取其整数部分)提示:1. 如何按照多个条件进行筛选?筛两次就可以了。 2. 使用.values
方法,可以获得 Dataframe 或 Series 的值,并以 NumPy 数组形式返回。当然,Pandas 也有求列平均的方法。看你自己的选择哦。3. 记得要处理异常值哦。
import pandas as pd
import numpy as np
df = pd.read_csv("/home/mw/input/beijing_weather5275/beijing_weather.csv")
df = df.replace(999999.000000, np.nan) #异常值999999替换为nan
df
def ludian(t,rh):
if t>=20 and rh>=55:
return 237.7*(17.27*t/(237.7+t) + np.log( rh/100 ))/(17.27-(17.27*t/(237.7+t) + np.log( rh/100 )))
df['ludian'] = df.apply(lambda x : ludian(x['t'],x['rh']),axis=1)
df.describe()
a1=int(df.loc[:,"ludian"].mean())
a1
a1 = 16
Q2. 网格化气象数据处理
利用 fnl 再分析数据,计算 2021 年 1 月(UTC)北半球(含赤道)平均 10 米风速(取整数部分)。
数据集路径:/home/mw/input/fnl6384(2.9G,体积较大,需要一些时间完成挂载)。
提示:先算出每个时刻的平均风速再求平均。
import glob
import xarray as xr
import numpy as np
file_name_list = glob.glob("/home/mw/input/fnl6384/fnl/fnl_*.grib2")
# 返回文件名,以列表呈现
mean_values = []
# 用于存储均值的列表
for i in file_name_list:
ds = xr.open_dataset(i, engine="pynio")
wind1 = ds['UGRD_P0_L103_GLL0'][0,][0:91, :]
# UGRD纬向风 VGRD径向风 风速=(UGRD^2+VGRD^2)^(1/2)
wind2 = ds['VGRD_P0_L103_GLL0'][0,][0:91, :]
wind_h = (wind1**2 + wind2**2)**(1/2)
a2 = wind_h.mean()
mean_values.append(a2) # 将均值添加到列表中
mean_values = np.array(mean_values)
a2 = int(mean_values.mean()) # 对均值列表求均值
print("均值:", a2)
a2 = 5
Q1: 读取 FNL 再分析资料中 2021 年 1 月 1 日 0 时地表以上2m温度的二维数组。从该数组中,取出每个维度里索引号都属于斐波那契数列(即截取该数组每个维度里索引号为0,1,1,2,3,5…..的部分)的数组。然后计算新的数组中,温度大于等于 0℃ 格点的平均温度(单位:摄氏度),然后取整。
提示:
- 完成下方 cell 的代码,将结果赋值给 a1。
- FNL 再分析资料的数据集路径在哪里?左侧文件树 input 目录里。单击,进去,找到对应文件夹,右键可以复制路径。
- 参考思路:搓个斐波那契函数→生成斐波那契数列→选取地面以上2m温度→条件索引→转化为摄氏度→求均值。
import xarray as xr
import numpy as np
import pandas as pd
def fibonacci(n):
lis = []
for i in range(n):
if i == 1 or i == 0:
lis.append(1)
else:
lis.append(lis[i-2]+lis[i-1])
print(lis)
a = fibonacci(13)
ds = xr.open_dataset("/home/mw/input/fnl6384/fnl/fnl_20210101_00_00.grib2", engine="pynio")
tem = ds['TMP_P0_L103_GLL0'][0,]
list1 = [1,1,2,3,5,8,13,21,34,55,89,144,233] #根据构造的斐波那契函数计算结果,再自行生成了新的数列。因为用函数生成的a的type是NoneType(不知道为什么),好像直接用报错了。
list2 = [1,1,2,3,5,8,13,21,34,55,89,144]
data1 = np.array(tem)
t_data1 = data1[np.ix_(list2,list1)] #索引方式!! 花式索引索引器np.ix_,能帮我们更加灵活地索引我们的数组
t_data1
t_data2 = t_data1-273.15
t_data3 = t_data2[t_data2>0]
a1 = int(np.mean(t_data3))
print(a1)
参考文献及链接
Python for Atmosphere and Ocean Scientists
https://carpentries-lab.github.io/python-aos-lesson/