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.
Files changed (41) hide show
  1. oafuncs/__init__.py +27 -12
  2. oafuncs/oa_cmap.py +31 -52
  3. oafuncs/oa_data.py +107 -28
  4. oafuncs/oa_down/hycom_3hourly.py +151 -34
  5. oafuncs/oa_draw.py +148 -96
  6. oafuncs/oa_file.py +61 -50
  7. oafuncs/oa_nc.py +131 -53
  8. {oafuncs-0.0.80.dist-info → oafuncs-0.0.82.dist-info}/METADATA +1 -2
  9. oafuncs-0.0.82.dist-info/RECORD +24 -0
  10. oafuncs-0.0.82.dist-info/top_level.txt +1 -0
  11. oafuncs/oa_down/test.py +0 -151
  12. oafuncs/oa_s/__init__.py +0 -23
  13. oafuncs/oa_s/oa_cmap.py +0 -163
  14. oafuncs/oa_s/oa_data.py +0 -187
  15. oafuncs/oa_s/oa_draw.py +0 -451
  16. oafuncs/oa_s/oa_file.py +0 -332
  17. oafuncs/oa_s/oa_help.py +0 -39
  18. oafuncs/oa_s/oa_nc.py +0 -410
  19. oafuncs/oa_s/oa_python.py +0 -107
  20. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/__init__.py" +0 -26
  21. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_cmap.py" +0 -163
  22. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_data.py" +0 -187
  23. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/__init__.py" +0 -20
  24. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/hycom_3hourly.py" +0 -1176
  25. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/literature.py" +0 -332
  26. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_down/test_ua.py" +0 -151
  27. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_draw.py" +0 -451
  28. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_file.py" +0 -332
  29. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_help.py" +0 -39
  30. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_nc.py" +0 -410
  31. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_python.py" +0 -107
  32. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/__init__.py" +0 -21
  33. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/meteorological.py" +0 -168
  34. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/ocean.py" +0 -158
  35. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_sign/scientific.py" +0 -139
  36. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_tool/__init__.py" +0 -18
  37. oafuncs - /321/205/320/231/320/277/321/206/320/254/320/274/oa_tool/email.py" +0 -114
  38. oafuncs-0.0.80.dist-info/RECORD +0 -51
  39. oafuncs-0.0.80.dist-info/top_level.txt +0 -2
  40. {oafuncs-0.0.80.dist-info → oafuncs-0.0.82.dist-info}/LICENSE.txt +0 -0
  41. {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 10:56:43
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.11
13
+ Python Version: 3.12
14
14
  """
15
15
 
16
+
16
17
  # 会导致OAFuncs直接导入所有函数,不符合模块化设计
17
- from oafuncs.oa_s import (
18
- oa_cmap,
19
- oa_data,
20
- oa_draw,
21
- oa_file,
22
- oa_help,
23
- oa_nc,
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", "extract_colors", "create_custom", "create_diverging", "create_5rgb_txt", "my_cmap"]
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 extract_colors(cmap, n=256):
41
+ def cmap2colors(cmap, n=256):
44
42
  """
45
43
  cmap : cmap名称
46
44
  n : 提取颜色数量
47
45
  return : 提取的颜色列表
48
- example : out_cmap = extract_colors('viridis', 256)
46
+ example : out_colors = cmap2colors('viridis', 256)
49
47
  """
50
48
  c_map = mpl.colormaps.get_cmap(cmap)
51
- out_cmap = [c_map(i) for i in np.linspace(0, 1, n)]
52
- return out_cmap
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 create_custom(colors: list, nodes=None, under=None, over=None): # 利用颜色快速配色
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 {*} c_map
63
- example : c_map = mk_cmap(['#C2B7F3','#B3BBF2','#B0CBF1','#ACDCF0','#A8EEED'])
64
- c_map = mk_cmap(['aliceblue','skyblue','deepskyblue'],[0.0,0.5,1.0])
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 : rgb_txt_filepath='E:/python/colorbar/test.txt'
105
- param {*} rgb_txt_filepath txt文件路径
79
+ description : rgbtxt_file='E:/python/colorbar/test.txt'
80
+ param {*} rgbtxt_file txt文件路径
106
81
  return {*} camp
107
- example : cmap_color=dcmap(path)
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(rgb_txt_filepath) as fid:
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(",")[0]
115
- rgb[i][1] = data[i].split(",")[1]
116
- rgb[i][2] = data[i].split(",")[2]
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 my_cmap(cmap_name=None, query=False):
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": create_custom(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"]),
134
- "cold_1": create_custom(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC"]),
135
- "warm_1": create_custom(["#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"]),
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": create_custom(["#6d00db", "#9800cb", "#F2003C", "#ff4500", "#ff7f00", "#FE28A2", "#FFC0CB", "#DDA0DD", "#40E0D0", "#1a66f2", "#00f7fb", "#8fff88", "#E3FF00"]),
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.cm.get_cmap(cmap_name)
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 = create_custom(colors, nodes)
151
+ c_map = create_cmap(colors, nodes)
173
152
  show([c_map])
174
153
 
175
154
  # ** 测试自制diverging型cmap
176
- diverging_cmap = create_diverging(["#4e00b3", "#0000FF", "#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"])
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
- cmap_color = create_5rgb_txt(file_path)
160
+ cmap_rgb = create_cmap_rgbtxt(file_path)
182
161
 
183
162
  # ** 测试将cmap转为list
184
- out_cmap = extract_colors("viridis", 256)
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-11-21 13:13:20
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__ = ['interp_2d', 'interp_2d_parallel']
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
- def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
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('Shape of data does not match shape of origin_x or origin_y.')
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'Interpolating {i+1}/{dims[0]}...')
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'\rInterpolating {i*dims[1]+j+1}/{dims[0]*dims[1]}...', end='')
82
- print('\n')
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 interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='linear'):
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
- def interp_single2d(target_y, target_x, origin_y, origin_x, data, method='linear'):
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='linear'):
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='linear'):
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('数据形状与 origin_x 或 origin_y 的形状不匹配.')
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'Using {mp.cpu_count()-2} threads...')
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(executor.map(interp_single4d, [i for i in range(dims[0]) for j in range(dims[1])], [j for i in range(dims[0]) for j in range(dims[1])], [target_y]*dims[0]*dims[1], [target_x]*dims[0]*dims[1], [origin_y]*dims[0]*dims[1], [origin_x]*dims[0]*dims[1], [data]*dims[0]*dims[1], [method]*dims[0]*dims[1]))
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__ == '__main__':
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'Interpolation time: {time.time()-start:.2f}s')
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 = interp_2d_parallel(target_x, target_y, origin_x, origin_y, data)
180
- print(f'Interpolation time: {time.time()-start:.2f}s')
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)