文章目录
- 一、列表
- 1.1、列表索引
- 1.2、枚举索引
- 二、numpy 数组
- 2.1、数组索引
- 2.2、乘法运算:image * mask
- 2.3、条件索引
- 2.3.1、np.argwhere():返回满足条件的元素的坐标(数组表示)
- 2.3.2、np.where():返回满足条件的元素的索引(元组表示)
- 2.3.3、np.nonzero():返回数组中非零元素的索引(元组表示)
- 2.3.4、np.indices():返回数组中每个维度上索引值的数组(元组表示)
- 2.3.5、np.extract():提取数组中满足条件的元素并返回一维数组
- 实战一:获取每一列的最小值:np.min(coordinates, axis=0)
- 实战二:提取坐标(时耗优化)
- 实战三:数据归一化到[0, 255] + 数据类型转换为uint8
一、列表
1.1、列表索引
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] row_index = 1 column_index = 2 value_at_index = my_list[row_index][column_index] print(f"列表索引: 在位置 ({row_index}, {column_index}) 的值是 {value_at_index}") # 列表索引: 在位置 (1, 2) 的值是 6
1.2、枚举索引
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for row_index, row_list in enumerate(my_list): # 使用 enumerate 遍历行 for col_index, value in enumerate(row_list): # 使用 enumerate 遍历列 print(f"在位置 ({row_index}, {col_index}) 的值是 {value}") """ 在位置 (0, 0) 的值是 1 在位置 (0, 1) 的值是 2 在位置 (0, 2) 的值是 3 在位置 (1, 0) 的值是 4 在位置 (1, 1) 的值是 5 在位置 (1, 2) 的值是 6 在位置 (2, 0) 的值是 7 在位置 (2, 1) 的值是 8 在位置 (2, 2) 的值是 9 """
二、numpy 数组
2.1、数组索引
import numpy as np my_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) row_index = 1 column_index = 2 value_at_index = my_array[row_index, column_index] print(f"数组索引: 在位置 ({row_index}, {column_index}) 的值是 {value_at_index}") # 数组索引: 在位置 (1, 2) 的值是 6
2.2、乘法运算:image * mask
使用 * 操作符对图像和掩码进行逐元素的乘法运算,两者的形状必须相同。
import numpy as np image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # mask = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]).astype(bool) # 指定索引 mask = (image > 4) # 条件索引 result = image * mask # 获取image中mask对应为True的图像(其余置零) print(result) """ [[0 0 0] [0 5 6] [7 8 9]] """
2.3、条件索引
2.3.1、np.argwhere():返回满足条件的元素的坐标(数组表示)
import numpy as np arr = np.array([[1, 0, 3], [4, 0, 6], [7, 8, 0]]) coordinates = np.argwhere(arr != 0) print(coordinates) """ [[0 0] [0 2] [1 0] [1 2] [2 0] [2 1]] """
2.3.2、np.where():返回满足条件的元素的索引(元组表示)
import numpy as np arr = np.array([[1, 0, 3], [4, 0, 6], [7, 8, 0]]) indices = np.where(arr != 0) coordinates = np.array(np.nonzero(arr)).T print(indices) print(coordinates) """ (array([0, 0, 1, 1, 2, 2], dtype=int64), array([0, 2, 0, 2, 0, 1], dtype=int64)) [[0 0] [0 2] [1 0] [1 2] [2 0] [2 1]] """
2.3.3、np.nonzero():返回数组中非零元素的索引(元组表示)
import numpy as np arr = np.array([[1, 0, 3], [4, 0, 6], [7, 8, 0]]) indices = np.nonzero(arr) # 返回数组中非零元素的索引 coordinates = np.array(np.nonzero(arr)).T # 返回数组中非零元素的坐标 print(indices) print(coordinates) """ (array([0, 0, 1, 1, 2, 2], dtype=int64), array([0, 2, 0, 2, 0, 1], dtype=int64)) [[0 0] [0 2] [1 0] [1 2] [2 0] [2 1]] """
2.3.4、np.indices():返回数组中每个维度上索引值的数组(元组表示)
import numpy as np image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) coordinates = np.indices(image.shape) # 获取图像所有坐标 flat_coordinates = np.vstack([coord.flatten() for coord in coordinates]).T # 将坐标展平为一维数组(获取图像中所有像素的坐标) print(flat_coordinates) """ [[0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2]] """
2.3.5、np.extract():提取数组中满足条件的元素并返回一维数组
import numpy as np import matplotlib.pyplot as plt # 生成一个随机的图像数据 np.random.seed(42) ImageStack = np.random.randint(0, 256, size=(10, 10), dtype=np.uint8) threshold = 150 # 设置阈值 # 使用 np.extract 函数提取满足条件的元素 condition = ImageStack > threshold image_extracted = np.extract(condition, ImageStack) print("提取的元素个数", len(image_extracted)) # 恢复原图的形状 image_extracted_reshaped = np.zeros_like(ImageStack, dtype=np.uint8) image_extracted_reshaped[condition] = image_extracted # 显示原始图像、处理后的图像以及提取得到的元素的图像 plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(ImageStack, cmap='gray', vmin=0, vmax=255) plt.title('ImageStack') plt.subplot(1, 3, 2) plt.imshow(image_extracted_reshaped, cmap='gray', vmin=0, vmax=255) plt.title(f'image_extracted_reshaped') plt.subplot(1, 3, 3) plt.plot(image_extracted, marker='o') plt.title(f'image_extracted') plt.show()
实战一:获取每一列的最小值:np.min(coordinates, axis=0)
import numpy as np my_array = np.zeros((10, 10, 10)) # 随机生成0和1整数的数组 my_array[2:4, 2:3, 5:9] = 1 # 指定位置填充值 nonzero_coordinates = np.argwhere(my_array != 0) # 获取非零元素的坐标 min_coords_nonzero = np.min(nonzero_coordinates, axis=0) # 获取所有列中每一列的最小值(axis=0 表示沿着第一个轴(即列轴)进行操作。) max_coords_nonzero = np.max(nonzero_coordinates, axis=0) # 获取所有列中每一列的最大值(axis=0 表示沿着第一个轴(即列轴)进行操作。) print("最小坐标值:", min_coords_nonzero) print("最大坐标值:", max_coords_nonzero) # 最小坐标值: [2 2 5] # 最大坐标值: [3 2 8]
实战二:提取坐标(时耗优化)
import numba import numpy as np import time @numba.jit() def where(input_data, output_data): # output_coordinate = [] num = 0 for z in range(input_data.shape[0]): for y in range(input_data.shape[1]): for x in range(input_data.shape[2]): if input_data[z, y, x]: # output_coordinate.append([z, y, x]) # 时耗增加 output_data[num][0] = z output_data[num][1] = y output_data[num][2] = x num += 1 # return output_coordinate # 时耗增加 return num if __name__ == "__main__": np.random.seed(42) start_time = time.time() ImageStack11 = np.random.randint(0, 256, size=(1024, 1024, 2024), dtype=np.uint8) # 生成一个随机的图像数据 print(f"总耗时:{time.time() - start_time:.4f}秒") ####################################### start_time = time.time() ImageStack22 = np.random.randint(0, 256, size=(1024, 1024, 2024)).astype(np.uint8) # 生成一个随机的图像数据 print(f"总耗时:{time.time() - start_time:.4f}秒") """ 总耗时:1.2737秒 总耗时:2.8277秒 """ ImageStack = ImageStack11.copy() threshold = 50 # 设置阈值 mask = (ImageStack < threshold) print("非零数量", np.count_nonzero(mask)) #################################################################### start_time = time.time() output_data = np.zeros((ImageStack.shape[0]*ImageStack.shape[1]*ImageStack.shape[2], 3), dtype=ImageStack.dtype) # 创建一个与 arr 具有相同形状和数据类型的全零数组 num = where(mask, output_data) # 找到mask的非零元素的坐标 coordinate1 = output_data[0:num] print(f"总耗时:{time.time() - start_time:.4f}秒") #################################################################### start_time = time.time() coordinate2 = np.argwhere(mask) # 找到mask的非零元素的坐标 print(f"总耗时:{time.time() - start_time:.4f}秒") #################################################################### start_time = time.time() index3 = np.where(mask) # (1)找到mask的非零元素的索引 # coordinates = np.array(c1).T print(f"总耗时:{time.time() - start_time:.4f}秒") #################################################################### start_time = time.time() coordinate4 = np.array(np.where(mask)).T # (1)找到mask的非零元素的索引(2)索引转坐标 print(f"总耗时:{time.time() - start_time:.4f}秒") #################################################################### start_time = time.time() coordinate5 = np.array(np.nonzero(mask)).T # (1)找到mask的非零元素的索引(2)索引转坐标 print(f"总耗时:{time.time() - start_time:.4f}秒") """ 非零数量 209707383 总耗时:2.1542秒 Numba加速 总耗时:5.0483秒 np.argwhere(mask) 总耗时:3.8276秒 np.where(mask) 总耗时:5.1381秒 np.array(np.where(mask)).T 总耗时:5.1958秒 np.array(np.nonzero(mask)).T """ #################################################################### # (2)根据条件进行索引与赋值(正方向) ImageStack2 = ImageStack.copy() start_time = time.time() ImageStack2[np.where(ImageStack2 < threshold)] = 0 # (1)条件索引(2)坐标获取(3)再赋值 end_time = time.time() runtime2 = end_time - start_time ImageStack3 = ImageStack.copy() start_time = time.time() ImageStack3[ImageStack3 < threshold] = 0 # (2)条件索引(2)再赋值(速度最快,但无法获取坐标) end_time = time.time() runtime3 = end_time - start_time print(f"方法二:总运行时间: {runtime2:.2f} 秒") print(f"方法三:总运行时间: {runtime3:.2f} 秒") """ 方法二:总运行时间: 0.56 秒 方法三:总运行时间: 0.07 秒 """ #################################################################### # (3)根据条件进行索引与赋值(反方向) ImageStack2 = ImageStack.copy() start_time = time.time() ImageStack2[np.where(ImageStack2 > threshold)] = 0 # (1)条件索引(2)坐标获取(3)再赋值 end_time = time.time() runtime2 = end_time - start_time ImageStack3 = ImageStack.copy() start_time = time.time() ImageStack3[ImageStack3 > threshold] = 0 # (2)条件索引(2)再赋值(速度最快,但无法获取坐标) end_time = time.time() runtime3 = end_time - start_time print(f"方法二:总运行时间: {runtime2:.2f} 秒") print(f"方法三:总运行时间: {runtime3:.2f} 秒") """ 方法二:总运行时间: 0.18 秒 方法三:总运行时间: 0.07 秒 """
实战三:数据归一化到[0, 255] + 数据类型转换为uint8
import numpy as np np.random.seed(42) # 设置种子点 # (1)生成一个随机的uintt16数据类型的图像[0, 65535] ImageStack = np.random.randint(0, 65535, size=(10, 10), dtype=np.uint16) # (2)数据归一化到[0, 255] + 数据类型转换为uint8 normalized_data = ((ImageStack - ImageStack.min()) / (ImageStack.max()- ImageStack.min()) * 255).astype(np.uint8) print(ImageStack.min(), ImageStack.max()) print(normalized_data.min(), normalized_data.max()) # import napari # viewer = napari.Viewer() # viewer.add_image(ImageStack, name='ImageStack', colormap='gray') # viewer.add_image(normalized_data, name='normalized_data', colormap='gray') # napari.run()