oafuncs 0.0.80__py2.py3-none-any.whl → 0.0.82__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oafuncs/__init__.py +27 -12
- oafuncs/oa_cmap.py +31 -52
- oafuncs/oa_data.py +107 -28
- oafuncs/oa_down/hycom_3hourly.py +151 -34
- oafuncs/oa_draw.py +148 -96
- oafuncs/oa_file.py +61 -50
- oafuncs/oa_nc.py +131 -53
- {oafuncs-0.0.80.dist-info → oafuncs-0.0.82.dist-info}/METADATA +1 -2
- oafuncs-0.0.82.dist-info/RECORD +24 -0
- oafuncs-0.0.82.dist-info/top_level.txt +1 -0
- oafuncs/oa_down/test.py +0 -151
- oafuncs/oa_s/__init__.py +0 -23
- oafuncs/oa_s/oa_cmap.py +0 -163
- oafuncs/oa_s/oa_data.py +0 -187
- oafuncs/oa_s/oa_draw.py +0 -451
- oafuncs/oa_s/oa_file.py +0 -332
- oafuncs/oa_s/oa_help.py +0 -39
- oafuncs/oa_s/oa_nc.py +0 -410
- oafuncs/oa_s/oa_python.py +0 -107
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/__init__.py" +0 -26
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_cmap.py" +0 -163
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_data.py" +0 -187
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/__init__.py" +0 -20
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/hycom_3hourly.py" +0 -1176
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/literature.py" +0 -332
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/test_ua.py" +0 -151
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_draw.py" +0 -451
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_file.py" +0 -332
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_help.py" +0 -39
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_nc.py" +0 -410
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_python.py" +0 -107
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/__init__.py" +0 -21
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/meteorological.py" +0 -168
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/ocean.py" +0 -158
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/scientific.py" +0 -139
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_tool/__init__.py" +0 -18
- oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_tool/email.py" +0 -114
- oafuncs-0.0.80.dist-info/RECORD +0 -51
- oafuncs-0.0.80.dist-info/top_level.txt +0 -2
- {oafuncs-0.0.80.dist-info → oafuncs-0.0.82.dist-info}/LICENSE.txt +0 -0
- {oafuncs-0.0.80.dist-info → oafuncs-0.0.82.dist-info}/WHEEL +0 -0
oafuncs/__init__.py
CHANGED
@@ -4,26 +4,41 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-09-17 16:09:20
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-12-13
|
8
|
-
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\__init__.py
|
7
|
+
LastEditTime: 2024-12-13 12:31:06
|
8
|
+
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_s\\__init__.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
12
12
|
SystemInfo: Windows 11
|
13
|
-
Python Version: 3.
|
13
|
+
Python Version: 3.12
|
14
14
|
"""
|
15
15
|
|
16
|
+
|
16
17
|
# 会导致OAFuncs直接导入所有函数,不符合模块化设计
|
17
|
-
from oafuncs.oa_s import
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
oa_python,
|
25
|
-
)
|
18
|
+
# from oafuncs.oa_s.oa_cmap import *
|
19
|
+
# from oafuncs.oa_s.oa_data import *
|
20
|
+
# from oafuncs.oa_s.oa_draw import *
|
21
|
+
# from oafuncs.oa_s.oa_file import *
|
22
|
+
# from oafuncs.oa_s.oa_help import *
|
23
|
+
# from oafuncs.oa_s.oa_nc import *
|
24
|
+
# from oafuncs.oa_s.oa_python import *
|
26
25
|
|
26
|
+
# ------------------- 2024-12-13 12:31:06 -------------------
|
27
|
+
# path: My_Funcs/OAFuncs/oafuncs/
|
28
|
+
from .oa_cmap import *
|
29
|
+
from .oa_data import *
|
30
|
+
from .oa_draw import *
|
31
|
+
from .oa_file import *
|
32
|
+
from .oa_help import *
|
33
|
+
from .oa_nc import *
|
34
|
+
from .oa_python import *
|
35
|
+
# ------------------- 2024-12-13 12:31:06 -------------------
|
36
|
+
# path: My_Funcs/OAFuncs/oafuncs/oa_down/
|
27
37
|
from .oa_down import *
|
38
|
+
# ------------------- 2024-12-13 12:31:06 -------------------
|
39
|
+
# path: My_Funcs/OAFuncs/oafuncs/oa_sign/
|
28
40
|
from .oa_sign import *
|
41
|
+
# ------------------- 2024-12-13 12:31:06 -------------------
|
42
|
+
# path: My_Funcs/OAFuncs/oafuncs/oa_tool/
|
29
43
|
from .oa_tool import *
|
44
|
+
# ------------------- 2024-12-13 12:31:06 -------------------
|
oafuncs/oa_cmap.py
CHANGED
@@ -17,11 +17,9 @@ import matplotlib as mpl
|
|
17
17
|
import matplotlib.pyplot as plt
|
18
18
|
import numpy as np
|
19
19
|
|
20
|
-
__all__ = ["show", "
|
20
|
+
__all__ = ["show", "cmap2colors", "create_cmap", "create_cmap_rgbtxt", "choose_cmap"]
|
21
21
|
|
22
22
|
# ** 将cmap用填色图可视化(官网摘抄函数)
|
23
|
-
|
24
|
-
|
25
23
|
def show(colormaps: list):
|
26
24
|
"""
|
27
25
|
Helper function to plot data with associated colormap.
|
@@ -40,28 +38,28 @@ def show(colormaps: list):
|
|
40
38
|
|
41
39
|
|
42
40
|
# ** 将cmap转为list,即多个颜色的列表
|
43
|
-
def
|
41
|
+
def cmap2colors(cmap, n=256):
|
44
42
|
"""
|
45
43
|
cmap : cmap名称
|
46
44
|
n : 提取颜色数量
|
47
45
|
return : 提取的颜色列表
|
48
|
-
example :
|
46
|
+
example : out_colors = cmap2colors('viridis', 256)
|
49
47
|
"""
|
50
48
|
c_map = mpl.colormaps.get_cmap(cmap)
|
51
|
-
|
52
|
-
return
|
49
|
+
out_colors = [c_map(i) for i in np.linspace(0, 1, n)]
|
50
|
+
return out_colors
|
53
51
|
|
54
52
|
|
55
53
|
# ** 自制cmap,多色,可带位置
|
56
|
-
def
|
54
|
+
def create_cmap(colors: list, nodes=None, under=None, over=None): # 利用颜色快速配色
|
57
55
|
"""
|
58
56
|
func : 自制cmap,自动确定颜色位置(等比例)
|
59
57
|
description : colors可以是颜色名称,也可以是十六进制颜色代码
|
60
58
|
param {*} colors 颜色
|
61
59
|
param {*} nodes 颜色位置,默认不提供,等间距
|
62
|
-
return {*}
|
63
|
-
example :
|
64
|
-
|
60
|
+
return {*} cmap
|
61
|
+
example : cmap = create_cmap(['#C2B7F3','#B3BBF2','#B0CBF1','#ACDCF0','#A8EEED'])
|
62
|
+
cmap = create_cmap(['aliceblue','skyblue','deepskyblue'],[0.0,0.5,1.0])
|
65
63
|
"""
|
66
64
|
if nodes is None: # 采取自动分配比例
|
67
65
|
cmap_color = mpl.colors.LinearSegmentedColormap.from_list("mycmap", colors)
|
@@ -74,46 +72,27 @@ def create_custom(colors: list, nodes=None, under=None, over=None): # 利用颜
|
|
74
72
|
return cmap_color
|
75
73
|
|
76
74
|
|
77
|
-
# ** 自制diverging型cmap,默认中间为白色
|
78
|
-
|
79
|
-
|
80
|
-
def create_diverging(colors: list):
|
81
|
-
"""
|
82
|
-
func : 自制cmap,双色,中间默认为白色;如果输入偶数个颜色,则中间为白,如果奇数个颜色,则中间色为中间色
|
83
|
-
description : colors可以是颜色名称,也可以是十六进制颜色代码
|
84
|
-
param {*} colors
|
85
|
-
return {*}
|
86
|
-
example : diverging_cmap = mk_cmap_diverging(["#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247"])
|
87
|
-
"""
|
88
|
-
# 自定义颜色位置
|
89
|
-
n = len(colors)
|
90
|
-
nodes = np.linspace(0.0, 1.0, n + 1 if n % 2 == 0 else n)
|
91
|
-
newcolors = colors
|
92
|
-
if n % 2 == 0:
|
93
|
-
newcolors.insert(int(n / 2), "#ffffff") # 偶数个颜色,中间为白色
|
94
|
-
cmap_color = mpl.colors.LinearSegmentedColormap.from_list("mycmap", list(zip(nodes, newcolors)))
|
95
|
-
return cmap_color
|
96
|
-
|
97
|
-
|
98
75
|
# ** 根据RGB的txt文档制作色卡(利用Grads调色盘)
|
99
|
-
|
100
|
-
|
101
|
-
def create_5rgb_txt(rgb_txt_filepath: str): # 根据RGB的txt文档制作色卡/根据rgb值制作
|
76
|
+
def create_cmap_rgbtxt(rgbtxt_file,split_mark=','): # 根据RGB的txt文档制作色卡/根据rgb值制作
|
102
77
|
"""
|
103
78
|
func : 根据RGB的txt文档制作色卡
|
104
|
-
description :
|
105
|
-
param {*}
|
79
|
+
description : rgbtxt_file='E:/python/colorbar/test.txt'
|
80
|
+
param {*} rgbtxt_file txt文件路径
|
106
81
|
return {*} camp
|
107
|
-
example :
|
82
|
+
example : cmap=create_cmap_rgbtxt(path,split_mark=',') #
|
83
|
+
|
84
|
+
txt example : 251,251,253
|
85
|
+
225,125,25
|
86
|
+
250,205,255
|
108
87
|
"""
|
109
|
-
with open(
|
88
|
+
with open(rgbtxt_file) as fid:
|
110
89
|
data = fid.readlines()
|
111
90
|
n = len(data)
|
112
91
|
rgb = np.zeros((n, 3))
|
113
92
|
for i in np.arange(n):
|
114
|
-
rgb[i][0] = data[i].split(
|
115
|
-
rgb[i][1] = data[i].split(
|
116
|
-
rgb[i][2] = data[i].split(
|
93
|
+
rgb[i][0] = data[i].split(split_mark)[0]
|
94
|
+
rgb[i][1] = data[i].split(split_mark)[1]
|
95
|
+
rgb[i][2] = data[i].split(split_mark)[2]
|
117
96
|
max_rgb = np.max(rgb)
|
118
97
|
if max_rgb > 2: # 如果rgb值大于2,则认为是0-255的值,需要归一化
|
119
98
|
rgb = rgb / 255.0
|
@@ -121,7 +100,7 @@ def create_5rgb_txt(rgb_txt_filepath: str): # 根据RGB的txt文档制作色卡
|
|
121
100
|
return icmap
|
122
101
|
|
123
102
|
|
124
|
-
def
|
103
|
+
def choose_cmap(cmap_name=None, query=False):
|
125
104
|
"""
|
126
105
|
description: Choosing a colormap from the list of available colormaps or a custom colormap
|
127
106
|
param {*} cmap_name:
|
@@ -130,9 +109,9 @@ def my_cmap(cmap_name=None, query=False):
|
|
130
109
|
"""
|
131
110
|
|
132
111
|
my_cmap_dict = {
|
133
|
-
"diverging_1":
|
134
|
-
"cold_1":
|
135
|
-
"warm_1":
|
112
|
+
"diverging_1": create_cmap(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"]),
|
113
|
+
"cold_1": create_cmap(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC"]),
|
114
|
+
"warm_1": create_cmap(["#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"]),
|
136
115
|
# "land_1": create_custom(["#3E6436", "#678A59", "#91A176", "#B8A87D", "#D9CBB2"], under="#A6CEE3", over="#FFFFFF"), # 陆地颜色从深绿到浅棕,表示从植被到沙地的递减
|
137
116
|
# "ocean_1": create_custom(["#126697", "#2D88B3", "#4EA1C9", "#78B9D8", "#A6CEE3"], under="#8470FF", over="#3E6436"), # 海洋颜色从深蓝到浅蓝,表示从深海到浅海的递减
|
138
117
|
# "ocean_land_1": create_custom(
|
@@ -150,7 +129,7 @@ def my_cmap(cmap_name=None, query=False):
|
|
150
129
|
# "#3E6436", # 深绿(高山)
|
151
130
|
# ]
|
152
131
|
# ),
|
153
|
-
"colorful_1":
|
132
|
+
"colorful_1": create_cmap(["#6d00db", "#9800cb", "#F2003C", "#ff4500", "#ff7f00", "#FE28A2", "#FFC0CB", "#DDA0DD", "#40E0D0", "#1a66f2", "#00f7fb", "#8fff88", "#E3FF00"]),
|
154
133
|
}
|
155
134
|
if query:
|
156
135
|
for key, _ in my_cmap_dict.items():
|
@@ -160,7 +139,7 @@ def my_cmap(cmap_name=None, query=False):
|
|
160
139
|
return my_cmap_dict[cmap_name]
|
161
140
|
else:
|
162
141
|
try:
|
163
|
-
return mpl.
|
142
|
+
return mpl.colormaps.get_cmap(cmap_name)
|
164
143
|
except ValueError:
|
165
144
|
raise ValueError(f"Unknown cmap name: {cmap_name}")
|
166
145
|
|
@@ -169,16 +148,16 @@ if __name__ == "__main__":
|
|
169
148
|
# ** 测试自制cmap
|
170
149
|
colors = ["#C2B7F3", "#B3BBF2", "#B0CBF1", "#ACDCF0", "#A8EEED"]
|
171
150
|
nodes = [0.0, 0.2, 0.4, 0.6, 1.0]
|
172
|
-
c_map =
|
151
|
+
c_map = create_cmap(colors, nodes)
|
173
152
|
show([c_map])
|
174
153
|
|
175
154
|
# ** 测试自制diverging型cmap
|
176
|
-
diverging_cmap =
|
155
|
+
diverging_cmap = create_cmap(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"])
|
177
156
|
show([diverging_cmap])
|
178
157
|
|
179
158
|
# ** 测试根据RGB的txt文档制作色卡
|
180
159
|
file_path = "E:/python/colorbar/test.txt"
|
181
|
-
|
160
|
+
cmap_rgb = create_cmap_rgbtxt(file_path)
|
182
161
|
|
183
162
|
# ** 测试将cmap转为list
|
184
|
-
|
163
|
+
out_colors = cmap2colors("viridis", 256)
|
oafuncs/oa_data.py
CHANGED
@@ -1,31 +1,97 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# coding=utf-8
|
3
|
-
|
3
|
+
"""
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-09-17 17:12:47
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-
|
7
|
+
LastEditTime: 2024-12-13 19:11:08
|
8
8
|
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_data.py
|
9
|
-
Description:
|
9
|
+
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
12
12
|
SystemInfo: Windows 11
|
13
13
|
Python Version: 3.11
|
14
|
-
|
15
|
-
|
14
|
+
"""
|
16
15
|
|
16
|
+
import itertools
|
17
17
|
import multiprocessing as mp
|
18
18
|
from concurrent.futures import ThreadPoolExecutor
|
19
19
|
|
20
20
|
import numpy as np
|
21
21
|
from scipy.interpolate import griddata
|
22
22
|
|
23
|
-
__all__ = [
|
23
|
+
__all__ = ["interp_2d"]
|
24
24
|
|
25
|
-
# ** 高维插值函数,插值最后两个维度
|
26
25
|
|
26
|
+
def interp_2d(target_x, target_y, origin_x, origin_y, data, method="linear", parallel=True):
|
27
|
+
"""
|
28
|
+
Perform 2D interpolation on the last two dimensions of a multi-dimensional array.
|
29
|
+
|
30
|
+
Parameters:
|
31
|
+
- target_x (array-like): 1D array of target grid's x-coordinates.
|
32
|
+
- target_y (array-like): 1D array of target grid's y-coordinates.
|
33
|
+
- origin_x (array-like): 1D array of original grid's x-coordinates.
|
34
|
+
- origin_y (array-like): 1D array of original grid's y-coordinates.
|
35
|
+
- data (numpy.ndarray): Multi-dimensional array where the last two dimensions correspond to the original grid.
|
36
|
+
- method (str, optional): Interpolation method, default is 'linear'. Other options include 'nearest', 'cubic', etc.
|
37
|
+
- parallel (bool, optional): Flag to enable parallel processing. Default is True.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
- interpolated_data (numpy.ndarray): Interpolated data with the same leading dimensions as the input data, but with the last two dimensions corresponding to the target grid.
|
41
|
+
|
42
|
+
Raises:
|
43
|
+
- ValueError: If the shape of the data does not match the shape of the origin_x or origin_y grids.
|
44
|
+
|
45
|
+
Usage:
|
46
|
+
- Interpolate a 2D array:
|
47
|
+
result = interp_2d(target_x, target_y, origin_x, origin_y, data_2d)
|
48
|
+
- Interpolate a 3D array (where the last two dimensions are spatial):
|
49
|
+
result = interp_2d(target_x, target_y, origin_x, origin_y, data_3d)
|
50
|
+
- Interpolate a 4D array (where the last two dimensions are spatial):
|
51
|
+
result = interp_2d(target_x, target_y, origin_x, origin_y, data_4d)
|
52
|
+
"""
|
53
|
+
|
54
|
+
def interp_single(data_slice, target_points, origin_points, method):
|
55
|
+
return griddata(origin_points, data_slice.ravel(), target_points, method=method).reshape(target_y.shape)
|
56
|
+
|
57
|
+
# 确保目标网格和初始网格都是二维的
|
58
|
+
if len(target_y.shape) == 1:
|
59
|
+
target_x, target_y = np.meshgrid(target_x, target_y)
|
60
|
+
if len(origin_y.shape) == 1:
|
61
|
+
origin_x, origin_y = np.meshgrid(origin_x, origin_y)
|
62
|
+
|
63
|
+
# 根据经纬度网格判断输入数据的形状是否匹配
|
64
|
+
if origin_x.shape != data.shape[-2:] or origin_y.shape != data.shape[-2:]:
|
65
|
+
raise ValueError("Shape of data does not match shape of origin_x or origin_y.")
|
66
|
+
|
67
|
+
# 创建网格和展平数据
|
68
|
+
target_points = np.column_stack((target_y.ravel(), target_x.ravel()))
|
69
|
+
origin_points = np.column_stack((origin_y.ravel(), origin_x.ravel()))
|
70
|
+
|
71
|
+
# 根据是否并行选择不同的执行方式
|
72
|
+
if parallel:
|
73
|
+
with ThreadPoolExecutor(max_workers=mp.cpu_count() - 2) as executor:
|
74
|
+
if len(data.shape) == 2:
|
75
|
+
interpolated_data = list(executor.map(interp_single, [data], [target_points], [origin_points], [method]))
|
76
|
+
elif len(data.shape) == 3:
|
77
|
+
interpolated_data = list(executor.map(interp_single, [data[i] for i in range(data.shape[0])], [target_points] * data.shape[0], [origin_points] * data.shape[0], [method] * data.shape[0]))
|
78
|
+
elif len(data.shape) == 4:
|
79
|
+
index_combinations = list(itertools.product(range(data.shape[0]), range(data.shape[1])))
|
80
|
+
interpolated_data = list(executor.map(interp_single, [data[i, j] for i, j in index_combinations], [target_points] * len(index_combinations), [origin_points] * len(index_combinations), [method] * len(index_combinations)))
|
81
|
+
interpolated_data = np.array(interpolated_data).reshape(data.shape[0], data.shape[1], *target_y.shape)
|
82
|
+
else:
|
83
|
+
if len(data.shape) == 2:
|
84
|
+
interpolated_data = interp_single(data, target_points, origin_points, method)
|
85
|
+
elif len(data.shape) == 3:
|
86
|
+
interpolated_data = np.stack([interp_single(data[i], target_points, origin_points, method) for i in range(data.shape[0])])
|
87
|
+
elif len(data.shape) == 4:
|
88
|
+
interpolated_data = np.stack([np.stack([interp_single(data[i, j], target_points, origin_points, method) for j in range(data.shape[1])]) for i in range(data.shape[0])])
|
89
|
+
|
90
|
+
return np.array(interpolated_data)
|
27
91
|
|
28
|
-
|
92
|
+
|
93
|
+
# ** 高维插值函数,插值最后两个维度
|
94
|
+
def interp_2d_20241213(target_x, target_y, origin_x, origin_y, data, method="linear"):
|
29
95
|
"""
|
30
96
|
高维插值函数,默认插值最后两个维度,传输数据前请确保数据的维度正确
|
31
97
|
参数:
|
@@ -52,7 +118,7 @@ def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
|
|
52
118
|
|
53
119
|
if origin_x.shape != dims[-2:] or origin_y.shape != dims[-2:]:
|
54
120
|
print(origin_x.shape, dims[-2:])
|
55
|
-
raise ValueError(
|
121
|
+
raise ValueError("Shape of data does not match shape of origin_x or origin_y.")
|
56
122
|
|
57
123
|
# 将目标网格展平成一维数组
|
58
124
|
target_points = np.column_stack((np.ravel(target_y), np.ravel(target_x)))
|
@@ -69,7 +135,7 @@ def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
|
|
69
135
|
for i in range(dims[0]):
|
70
136
|
dt = griddata(origin_points, np.ravel(data[i, :, :]), target_points, method=method)
|
71
137
|
interpolated_data.append(np.reshape(dt, target_y.shape))
|
72
|
-
print(f
|
138
|
+
print(f"Interpolating {i+1}/{dims[0]}...")
|
73
139
|
interpolated_data = np.array(interpolated_data)
|
74
140
|
elif len_dims == 4:
|
75
141
|
interpolated_data = []
|
@@ -78,8 +144,8 @@ def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
|
|
78
144
|
for j in range(dims[1]):
|
79
145
|
dt = griddata(origin_points, np.ravel(data[i, j, :, :]), target_points, method=method)
|
80
146
|
interpolated_data[i].append(np.reshape(dt, target_y.shape))
|
81
|
-
print(f
|
82
|
-
print(
|
147
|
+
print(f"\rInterpolating {i*dims[1]+j+1}/{dims[0]*dims[1]}...", end="")
|
148
|
+
print("\n")
|
83
149
|
interpolated_data = np.array(interpolated_data)
|
84
150
|
|
85
151
|
return interpolated_data
|
@@ -87,8 +153,8 @@ def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
|
|
87
153
|
|
88
154
|
# ** 高维插值函数,插值最后两个维度,使用多线程进行插值
|
89
155
|
# 在本地电脑上可以提速三倍左右,超算上暂时无法加速
|
90
|
-
def
|
91
|
-
|
156
|
+
def interp_2d_parallel_20241213(target_x, target_y, origin_x, origin_y, data, method="linear"):
|
157
|
+
"""
|
92
158
|
param {*} target_x 目标经度网格 1D 或 2D
|
93
159
|
param {*} target_y 目标纬度网格 1D 或 2D
|
94
160
|
param {*} origin_x 初始经度网格 1D 或 2D
|
@@ -98,22 +164,23 @@ def interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='lin
|
|
98
164
|
return {*} 插值结果
|
99
165
|
description : 高维插值函数,默认插值最后两个维度,传输数据前请确保数据的维度正确
|
100
166
|
example : interpolated_data = interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='linear')
|
101
|
-
|
102
|
-
|
167
|
+
"""
|
168
|
+
|
169
|
+
def interp_single2d(target_y, target_x, origin_y, origin_x, data, method="linear"):
|
103
170
|
target_points = np.column_stack((np.ravel(target_y), np.ravel(target_x)))
|
104
171
|
origin_points = np.column_stack((np.ravel(origin_y), np.ravel(origin_x)))
|
105
172
|
|
106
173
|
dt = griddata(origin_points, np.ravel(data[:, :]), target_points, method=method)
|
107
174
|
return np.reshape(dt, target_y.shape)
|
108
175
|
|
109
|
-
def interp_single3d(i, target_y, target_x, origin_y, origin_x, data, method=
|
176
|
+
def interp_single3d(i, target_y, target_x, origin_y, origin_x, data, method="linear"):
|
110
177
|
target_points = np.column_stack((np.ravel(target_y), np.ravel(target_x)))
|
111
178
|
origin_points = np.column_stack((np.ravel(origin_y), np.ravel(origin_x)))
|
112
179
|
|
113
180
|
dt = griddata(origin_points, np.ravel(data[i, :, :]), target_points, method=method)
|
114
181
|
return np.reshape(dt, target_y.shape)
|
115
182
|
|
116
|
-
def interp_single4d(i, j, target_y, target_x, origin_y, origin_x, data, method=
|
183
|
+
def interp_single4d(i, j, target_y, target_x, origin_y, origin_x, data, method="linear"):
|
117
184
|
target_points = np.column_stack((np.ravel(target_y), np.ravel(target_x)))
|
118
185
|
origin_points = np.column_stack((np.ravel(origin_y), np.ravel(origin_x)))
|
119
186
|
|
@@ -129,19 +196,31 @@ def interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='lin
|
|
129
196
|
len_dims = len(dims)
|
130
197
|
|
131
198
|
if origin_x.shape != dims[-2:] or origin_y.shape != dims[-2:]:
|
132
|
-
raise ValueError(
|
199
|
+
raise ValueError("数据形状与 origin_x 或 origin_y 的形状不匹配.")
|
133
200
|
|
134
201
|
interpolated_data = []
|
135
202
|
|
136
203
|
# 使用多线程进行插值
|
137
|
-
with ThreadPoolExecutor(max_workers=mp.cpu_count()-2) as executor:
|
138
|
-
print(f
|
204
|
+
with ThreadPoolExecutor(max_workers=mp.cpu_count() - 2) as executor:
|
205
|
+
print(f"Using {mp.cpu_count()-2} threads...")
|
139
206
|
if len_dims == 2:
|
140
207
|
interpolated_data = list(executor.map(interp_single2d, [target_y], [target_x], [origin_y], [origin_x], [data], [method]))
|
141
208
|
elif len_dims == 3:
|
142
|
-
interpolated_data = list(executor.map(interp_single3d, [i for i in range(dims[0])], [target_y]*dims[0], [target_x]*dims[0], [origin_y]*dims[0], [origin_x]*dims[0], [data]*dims[0], [method]*dims[0]))
|
209
|
+
interpolated_data = list(executor.map(interp_single3d, [i for i in range(dims[0])], [target_y] * dims[0], [target_x] * dims[0], [origin_y] * dims[0], [origin_x] * dims[0], [data] * dims[0], [method] * dims[0]))
|
143
210
|
elif len_dims == 4:
|
144
|
-
interpolated_data = list(
|
211
|
+
interpolated_data = list(
|
212
|
+
executor.map(
|
213
|
+
interp_single4d,
|
214
|
+
[i for i in range(dims[0]) for j in range(dims[1])],
|
215
|
+
[j for i in range(dims[0]) for j in range(dims[1])],
|
216
|
+
[target_y] * dims[0] * dims[1],
|
217
|
+
[target_x] * dims[0] * dims[1],
|
218
|
+
[origin_y] * dims[0] * dims[1],
|
219
|
+
[origin_x] * dims[0] * dims[1],
|
220
|
+
[data] * dims[0] * dims[1],
|
221
|
+
[method] * dims[0] * dims[1],
|
222
|
+
)
|
223
|
+
)
|
145
224
|
interpolated_data = np.array(interpolated_data).reshape(dims[0], dims[1], target_y.shape[0], target_x.shape[1])
|
146
225
|
|
147
226
|
interpolated_data = np.array(interpolated_data)
|
@@ -149,7 +228,7 @@ def interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='lin
|
|
149
228
|
return interpolated_data
|
150
229
|
|
151
230
|
|
152
|
-
if __name__ ==
|
231
|
+
if __name__ == "__main__":
|
153
232
|
import time
|
154
233
|
|
155
234
|
import matplotlib.pyplot as plt
|
@@ -169,15 +248,15 @@ if __name__ == '__main__':
|
|
169
248
|
data = np.random.rand(10, 10, 11, 11)
|
170
249
|
|
171
250
|
start = time.time()
|
172
|
-
interpolated_data = interp_2d(target_x, target_y, origin_x, origin_y, data)
|
173
|
-
print(f
|
251
|
+
interpolated_data = interp_2d(target_x, target_y, origin_x, origin_y, data, parallel=False)
|
252
|
+
print(f"Interpolation time: {time.time()-start:.2f}s")
|
174
253
|
|
175
254
|
print(interpolated_data.shape)
|
176
255
|
|
177
256
|
# 高维插值多线程
|
178
257
|
start = time.time()
|
179
|
-
interpolated_data =
|
180
|
-
print(f
|
258
|
+
interpolated_data = interp_2d(target_x, target_y, origin_x, origin_y, data)
|
259
|
+
print(f"Interpolation time: {time.time()-start:.2f}s")
|
181
260
|
|
182
261
|
print(interpolated_data.shape)
|
183
262
|
print(interpolated_data[0, 0, :, :].shape)
|