简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français

站内搜索

搜索

活动公告

10-31 22:15
10-23 09:32
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31
10-23 09:28
通知:签到时间调整为每日4:00(东八区)
10-23 09:26

NumPy数组长度获取方法详解从基础概念到高级技巧涵盖实际应用案例常见错误解析和性能优化策略帮助开发者高效处理数组尺寸问题

3万

主题

308

科技点

3万

积分

大区版主

木柜子打湿

积分
31891

财Doro三倍冰淇淋无人之境【一阶】立华奏小樱(小丑装)⑨的冰沙以外的星空【二阶】

发表于 2025-10-8 11:40:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

NumPy(Numerical Python)是Python科学计算的核心库,提供了高性能的多维数组对象及相关工具。在数据处理、科学计算、机器学习等领域,NumPy数组是最常用的数据结构之一。正确理解和获取NumPy数组的长度(尺寸)是高效处理数据的基础。本文将全面介绍NumPy数组长度获取的各种方法,从基础概念到高级技巧,并结合实际应用案例、常见错误解析和性能优化策略,帮助开发者更好地处理数组尺寸问题。

NumPy数组基础概念

什么是NumPy数组

NumPy数组是一个多维表格,包含相同类型的元素,可以通过非负整数的元组进行索引。在NumPy中,维度被称为轴(axes),轴的数量称为秩(rank)。
  1. import numpy as np
  2. # 创建一维数组
  3. arr1d = np.array([1, 2, 3, 4, 5])
  4. print("一维数组:", arr1d)
  5. # 创建二维数组
  6. arr2d = np.array([[1, 2, 3], [4, 5, 6]])
  7. print("二维数组:\n", arr2d)
  8. # 创建三维数组
  9. arr3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
  10. print("三维数组:\n", arr3d)
复制代码

NumPy数组的维度和形状

NumPy数组的形状(shape)是一个描述数组在每个维度上大小的元组。例如,一个2行3列的二维数组的形状是(2, 3)。
  1. # 查看数组形状
  2. print("一维数组形状:", arr1d.shape)  # 输出: (5,)
  3. print("二维数组形状:", arr2d.shape)  # 输出: (2, 3)
  4. print("三维数组形状:", arr3d.shape)  # 输出: (2, 2, 2)
复制代码

NumPy数组与Python列表的区别

虽然NumPy数组在某些方面类似于Python列表,但它们有几个关键区别:

1. 同质性:NumPy数组中的所有元素必须是相同类型,而Python列表可以包含不同类型的元素。
2. 性能:NumPy数组在数值计算上比Python列表更高效。
3. 功能:NumPy提供了丰富的数学和统计函数,可以直接应用于整个数组。
  1. # Python列表
  2. py_list = [1, 2, 3, 4, 5]
  3. # NumPy数组
  4. np_array = np.array([1, 2, 3, 4, 5])
  5. # 对列表和数组进行乘法操作
  6. print("Python列表乘法:", py_list * 2)  # 输出: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
  7. print("NumPy数组乘法:", np_array * 2)  # 输出: [ 2  4  6  8 10]
复制代码

获取NumPy数组长度的基础方法

使用len()函数

Python内置的len()函数可以用于获取NumPy数组的长度,但它只返回第一个维度(最外层)的大小。
  1. # 一维数组
  2. print("一维数组长度:", len(arr1d))  # 输出: 5
  3. # 二维数组
  4. print("二维数组长度:", len(arr2d))  # 输出: 2 (行数)
  5. # 三维数组
  6. print("三维数组长度:", len(arr3d))  # 输出: 2 (第一个维度的大小)
复制代码

使用size属性

NumPy数组的size属性返回数组中元素的总数,不考虑维度。
  1. # 一维数组
  2. print("一维数组元素总数:", arr1d.size)  # 输出: 5
  3. # 二维数组
  4. print("二维数组元素总数:", arr2d.size)  # 输出: 6 (2行 × 3列)
  5. # 三维数组
  6. print("三维数组元素总数:", arr3d.size)  # 输出: 8 (2 × 2 × 2)
复制代码

使用shape属性

shape属性返回一个元组,表示数组在每个维度上的大小。通过访问shape元组的元素,可以获取特定维度的大小。
  1. # 一维数组
  2. print("一维数组形状:", arr1d.shape)  # 输出: (5,)
  3. print("一维数组第一个维度大小:", arr1d.shape[0])  # 输出: 5
  4. # 二维数组
  5. print("二维数组形状:", arr2d.shape)  # 输出: (2, 3)
  6. print("二维数组行数:", arr2d.shape[0])  # 输出: 2
  7. print("二维数组列数:", arr2d.shape[1])  # 输出: 3
  8. # 三维数组
  9. print("三维数组形状:", arr3d.shape)  # 输出: (2, 2, 2)
  10. print("三维数组第一个维度大小:", arr3d.shape[0])  # 输出: 2
  11. print("三维数组第二个维度大小:", arr3d.shape[1])  # 输出: 2
  12. print("三维数组第三个维度大小:", arr3d.shape[2])  # 输出: 2
复制代码

高级技巧

多维数组的长度获取

对于多维数组,获取长度需要考虑具体的维度。以下是几种获取多维数组不同维度长度的方法:
  1. # 创建一个4维数组
  2. arr4d = np.random.rand(2, 3, 4, 5)
  3. print("4维数组形状:", arr4d.shape)  # 输出: (2, 3, 4, 5)
  4. # 获取各个维度的长度
  5. for i in range(arr4d.ndim):
  6.     print(f"维度 {i} 的长度:", arr4d.shape[i])
  7. # 使用ndim属性获取数组的总维度数
  8. print("数组总维度数:", arr4d.ndim)  # 输出: 4
复制代码

沿特定轴获取长度

在处理多维数组时,经常需要沿特定轴(axis)获取长度或进行操作。NumPy提供了多种方法来实现这一点:
  1. # 创建一个3维数组
  2. arr = np.random.rand(3, 4, 5)
  3. print("原始数组形状:", arr.shape)  # 输出: (3, 4, 5)
  4. # 沿不同轴获取长度
  5. print("沿轴0的长度:", arr.shape[0])  # 输出: 3
  6. print("沿轴1的长度:", arr.shape[1])  # 输出: 4
  7. print("沿轴2的长度:", arr.shape[2])  # 输出: 5
  8. # 使用np.shape()函数
  9. print("使用np.shape()获取形状:", np.shape(arr))  # 输出: (3, 4, 5)
复制代码

条件筛选后的数组长度获取

在实际应用中,经常需要根据条件筛选数组元素,然后获取满足条件的元素数量:
  1. # 创建一个随机数组
  2. arr = np.random.randint(0, 100, size=20)
  3. print("原始数组:", arr)
  4. # 筛选大于50的元素
  5. filtered = arr[arr > 50]
  6. print("大于50的元素:", filtered)
  7. print("大于50的元素数量:", len(filtered))  # 使用len()
  8. print("大于50的元素数量:", filtered.size)  # 使用size属性
  9. # 直接计算满足条件的元素数量,不创建新数组
  10. count = np.sum(arr > 50)
  11. print("大于50的元素数量(直接计算):", count)
  12. # 使用np.count_nonzero()
  13. count_nonzero = np.count_nonzero(arr > 50)
  14. print("大于50的元素数量(count_nonzero):", count_nonzero)
复制代码

实际应用案例

数据预处理中的数组长度处理

在数据预处理过程中,经常需要处理不同长度的数组,例如处理缺失值或标准化数据:
  1. # 创建一个包含缺失值的数据集
  2. data = np.array([[1, 2, 3], [4, np.nan, 6], [7, 8, 9], [np.nan, np.nan, np.nan]])
  3. print("原始数据:\n", data)
  4. # 计算每行的非NaN值数量
  5. row_counts = np.sum(~np.isnan(data), axis=1)
  6. print("每行的非NaN值数量:", row_counts)
  7. # 计算每列的非NaN值数量
  8. col_counts = np.sum(~np.isnan(data), axis=0)
  9. print("每列的非NaN值数量:", col_counts)
  10. # 标准化数据(忽略NaN值)
  11. def normalize_with_nan(arr):
  12.     mask = ~np.isnan(arr)
  13.     mean = np.mean(arr[mask])
  14.     std = np.std(arr[mask])
  15.     normalized = np.where(mask, (arr - mean) / std, np.nan)
  16.     return normalized
  17. # 对每列进行标准化
  18. normalized_data = np.apply_along_axis(normalize_with_nan, 0, data)
  19. print("标准化后的数据:\n", normalized_data)
复制代码

机器学习中的批量数据处理

在机器学习中,经常需要将数据分成批次进行处理,这涉及到对数组长度的精确控制:
  1. # 创建一个大型数据集
  2. X = np.random.rand(1000, 10)  # 1000个样本,每个样本10个特征
  3. y = np.random.randint(0, 2, size=1000)  # 1000个标签
  4. print("特征数据形状:", X.shape)
  5. print("标签数据形状:", y.shape)
  6. # 定义批次大小
  7. batch_size = 32
  8. # 计算批次数
  9. num_batches = len(X) // batch_size
  10. if len(X) % batch_size != 0:
  11.     num_batches += 1
  12. print("总批次数:", num_batches)
  13. # 创建批次生成器
  14. def batch_generator(X, y, batch_size):
  15.     num_samples = len(X)
  16.     indices = np.arange(num_samples)
  17.     np.random.shuffle(indices)
  18.    
  19.     for start_idx in range(0, num_samples, batch_size):
  20.         end_idx = min(start_idx + batch_size, num_samples)
  21.         batch_indices = indices[start_idx:end_idx]
  22.         
  23.         yield X[batch_indices], y[batch_indices]
  24. # 使用批次生成器
  25. for i, (batch_X, batch_y) in enumerate(batch_generator(X, y, batch_size)):
  26.     print(f"批次 {i+1}:")
  27.     print("  特征批次形状:", batch_X.shape)
  28.     print("  标签批次形状:", batch_y.shape)
  29.     print("  标签批次长度:", len(batch_y))
  30.    
  31.     # 在这里可以进行模型训练...
  32.     if i >= 2:  # 只展示前3个批次
  33.         break
复制代码

图像处理中的数组尺寸操作

在图像处理中,图像通常表示为多维数组(高度、宽度、通道),处理这些数组需要精确控制尺寸:
  1. # 创建一个模拟的RGB图像 (高度: 100, 宽度: 150, 通道: 3)
  2. image = np.random.randint(0, 256, size=(100, 150, 3), dtype=np.uint8)
  3. print("图像数组形状:", image.shape)
  4. print("图像高度:", image.shape[0])
  5. print("图像宽度:", image.shape[1])
  6. print("图像通道数:", image.shape[2])
  7. # 调整图像大小
  8. def resize_image(image, new_height, new_width):
  9.     height, width = image.shape[:2]
  10.    
  11.     # 计算缩放比例
  12.     h_ratio = new_height / height
  13.     w_ratio = new_width / width
  14.    
  15.     # 创建新图像
  16.     resized_image = np.zeros((new_height, new_width, image.shape[2]), dtype=image.dtype)
  17.    
  18.     # 简单的最近邻插值
  19.     for i in range(new_height):
  20.         for j in range(new_width):
  21.             # 计算原始图像中的对应位置
  22.             orig_i = min(int(i / h_ratio), height - 1)
  23.             orig_j = min(int(j / w_ratio), width - 1)
  24.             resized_image[i, j] = image[orig_i, orig_j]
  25.    
  26.     return resized_image
  27. # 调整图像大小
  28. resized_image = resize_image(image, 50, 75)
  29. print("调整后的图像形状:", resized_image.shape)
  30. # 图像裁剪
  31. def crop_image(image, top, left, height, width):
  32.     return image[top:top+height, left:left+width]
  33. # 裁剪图像中心区域
  34. center_y, center_x = image.shape[0] // 2, image.shape[1] // 2
  35. crop_height, crop_width = 50, 50
  36. top = center_y - crop_height // 2
  37. left = center_x - crop_width // 2
  38. cropped_image = crop_image(image, top, left, crop_height, crop_width)
  39. print("裁剪后的图像形状:", cropped_image.shape)
复制代码

常见错误解析

维度混淆错误

在处理多维数组时,最常见的错误之一是混淆维度,特别是在使用不同的NumPy函数时:
  1. # 创建一个2D数组
  2. arr = np.array([[1, 2, 3], [4, 5, 6]])
  3. print("原始数组:\n", arr)
  4. # 错误示例1: 混淆len()和size
  5. print("len(arr)返回:", len(arr))  # 返回行数: 2
  6. print("arr.size返回:", arr.size)  # 返回元素总数: 6
  7. # 错误示例2: 在使用np.sum时混淆轴
  8. print("np.sum(arr, axis=0):", np.sum(arr, axis=0))  # 沿列求和: [5 7 9]
  9. print("np.sum(arr, axis=1):", np.sum(arr, axis=1))  # 沿行求和: [6 15]
  10. # 错误示例3: 在使用np.concatenate时混淆维度
  11. arr1 = np.array([[1, 2], [3, 4]])
  12. arr2 = np.array([[5, 6]])
  13. # 尝试沿轴0连接,但维度不匹配
  14. try:
  15.     result = np.concatenate((arr1, arr2), axis=0)
  16.     print("连接结果:\n", result)
  17. except ValueError as e:
  18.     print("连接错误:", e)
  19. # 正确的连接方式
  20. arr2_correct = np.array([[5, 6]])
  21. result = np.concatenate((arr1, arr2_correct), axis=0)
  22. print("正确的连接结果:\n", result)
复制代码

索引越界错误

索引越界是另一个常见错误,特别是在处理数组边界时:
  1. # 创建一个数组
  2. arr = np.array([1, 2, 3, 4, 5])
  3. print("数组:", arr)
  4. # 错误示例1: 访问超出范围的索引
  5. try:
  6.     print("尝试访问arr[5]:", arr[5])  # 索引从0开始,最大有效索引是4
  7. except IndexError as e:
  8.     print("索引错误:", e)
  9. # 正确的索引访问
  10. print("最后一个元素:", arr[-1])  # 使用负索引
  11. print("最后一个元素:", arr[len(arr)-1])  # 使用长度计算
  12. # 错误示例2: 在多维数组中的索引越界
  13. arr2d = np.array([[1, 2, 3], [4, 5, 6]])
  14. print("\n二维数组:\n", arr2d)
  15. try:
  16.     print("尝试访问arr2d[2, 0]:", arr2d[2, 0])  # 第一维只有0和1
  17. except IndexError as e:
  18.     print("索引错误:", e)
  19. # 安全访问数组元素的函数
  20. def safe_access(arr, *indices):
  21.     for i, idx in enumerate(indices):
  22.         if idx >= arr.shape[i] or idx < -arr.shape[i]:
  23.             print(f"警告: 维度 {i} 的索引 {idx} 超出范围 [0, {arr.shape[i]-1}]")
  24.             return None
  25.     return arr[indices]
  26. # 使用安全访问函数
  27. print("安全访问arr2d[1, 2]:", safe_access(arr2d, 1, 2))
  28. print("安全访问arr2d[2, 0]:", safe_access(arr2d, 2, 0))
复制代码

广播机制中的尺寸不匹配错误

NumPy的广播机制允许不同形状的数组进行运算,但需要满足特定的条件,否则会导致错误:
  1. # 创建不同形状的数组
  2. a = np.array([[1, 2, 3], [4, 5, 6]])  # 形状: (2, 3)
  3. b = np.array([1, 2, 3])  # 形状: (3,)
  4. # 正确的广播示例
  5. print("a + b (广播):\n", a + b)  # b被广播为(2, 3)
  6. # 错误示例1: 不兼容的形状
  7. c = np.array([1, 2])  # 形状: (2,)
  8. try:
  9.     print("a + c (尝试广播):", a + c)  # 无法广播
  10. except ValueError as e:
  11.     print("广播错误:", e)
  12. # 错误示例2: 混淆轴的方向
  13. d = np.array([[1], [2]])  # 形状: (2, 1)
  14. e = np.array([1, 2, 3])  # 形状: (3,)
  15. try:
  16.     print("d + e (尝试广播):", d + e)  # 可以广播,结果形状为(2, 3)
  17. except ValueError as e:
  18.     print("广播错误:", e)
  19. # 检查两个数组是否可以广播
  20. def can_broadcast(shape1, shape2):
  21.     # 从右向左比较维度
  22.     for dim1, dim2 in zip(reversed(shape1), reversed(shape2)):
  23.         if dim1 != dim2 and dim1 != 1 and dim2 != 1:
  24.             return False
  25.     return True
  26. # 测试广播兼容性
  27. print("(2, 3)和(3,)可以广播?", can_broadcast((2, 3), (3,)))  # True
  28. print("(2, 3)和(2,)可以广播?", can_broadcast((2, 3), (2,)))  # False
  29. print("(2, 1)和(3,)可以广播?", can_broadcast((2, 1), (3,)))  # True
复制代码

性能优化策略

避免不必要的数组复制

在NumPy中,某些操作会创建数组的副本,这会消耗额外的内存和时间。了解哪些操作创建副本,哪些操作创建视图,对于性能优化至关重要:
  1. # 创建一个大数组
  2. large_arr = np.random.rand(1000, 1000)
  3. # 创建视图而非副本
  4. view_arr = large_arr[:500, :500]  # 创建视图,不复制数据
  5. print("视图是否是原数组的视图?", view_arr.base is large_arr)  # True
  6. # 修改视图会影响原数组
  7. view_arr[0, 0] = 999
  8. print("原数组的[0,0]元素:", large_arr[0, 0])  # 999
  9. # 创建副本
  10. copy_arr = large_arr[:500, :500].copy()  # 显式创建副本
  11. print("副本是否是原数组的视图?", copy_arr.base is large_arr)  # None
  12. # 修改副本不会影响原数组
  13. copy_arr[0, 0] = 888
  14. print("原数组的[0,0]元素:", large_arr[0, 0])  # 仍然是999
  15. # 性能比较
  16. import time
  17. # 测量创建视图的时间
  18. start_time = time.time()
  19. for _ in range(1000):
  20.     view = large_arr[:500, :500]
  21. view_time = time.time() - start_time
  22. # 测量创建副本的时间
  23. start_time = time.time()
  24. for _ in range(1000):
  25.     copy = large_arr[:500, :500].copy()
  26. copy_time = time.time() - start_time
  27. print(f"创建视图1000次的时间: {view_time:.6f}秒")
  28. print(f"创建副本1000次的时间: {copy_time:.6f}秒")
  29. print(f"副本/视图时间比: {copy_time/view_time:.2f}")
复制代码

使用视图而非副本

除了切片操作,其他NumPy函数也可能返回视图或副本。了解这些差异可以帮助优化性能:
  1. # 创建一个数组
  2. arr = np.random.rand(1000, 1000)
  3. # reshape()可能返回视图或副本
  4. reshaped_view = arr.reshape(1000000)  # 在可能的情况下返回视图
  5. print("reshape是否返回视图?", reshaped_view.base is arr)  # True
  6. # ravel()总是返回视图(如果可能)
  7. raveled_view = arr.ravel()
  8. print("ravel是否返回视图?", raveled_view.base is arr)  # True
  9. # flatten()总是返回副本
  10. flattened_copy = arr.flatten()
  11. print("flatten是否返回视图?", flattened_copy.base is arr)  # False
  12. # 转置操作返回视图
  13. transposed_view = arr.T
  14. print("转置是否返回视图?", transposed_view.base is arr)  # True
  15. # 性能比较:使用视图进行操作 vs 使用副本进行操作
  16. # 使用视图
  17. start_time = time.time()
  18. for _ in range(100):
  19.     view = arr[:500, :500]
  20.     result = np.sum(view)
  21. view_op_time = time.time() - start_time
  22. # 使用副本
  23. start_time = time.time()
  24. for _ in range(100):
  25.     copy = arr[:500, :500].copy()
  26.     result = np.sum(copy)
  27. copy_op_time = time.time() - start_time
  28. print(f"使用视图操作100次的时间: {view_op_time:.6f}秒")
  29. print(f"使用副本操作100次的时间: {copy_op_time:.6f}秒")
  30. print(f"副本/视图操作时间比: {copy_op_time/view_op_time:.2f}")
复制代码

利用NumPy内置函数

NumPy的内置函数通常比Python循环快得多,特别是在处理大型数组时:
  1. # 创建一个大数组
  2. large_arr = np.random.rand(10000)
  3. # 使用Python循环计算平方和
  4. start_time = time.time()
  5. sum_squares_py = 0
  6. for x in large_arr:
  7.     sum_squares_py += x**2
  8. py_time = time.time() - start_time
  9. # 使用NumPy函数计算平方和
  10. start_time = time.time()
  11. sum_squares_np = np.sum(large_arr**2)
  12. np_time = time.time() - start_time
  13. print(f"Python循环计算平方和的时间: {py_time:.6f}秒")
  14. print(f"NumPy函数计算平方和的时间: {np_time:.6f}秒")
  15. print(f"Python/NumPy时间比: {py_time/np_time:.2f}")
  16. # 另一个例子:条件计数
  17. # 使用Python循环
  18. start_time = time.time()
  19. count_py = 0
  20. for x in large_arr:
  21.     if x > 0.5:
  22.         count_py += 1
  23. py_count_time = time.time() - start_time
  24. # 使用NumPy函数
  25. start_time = time.time()
  26. count_np = np.sum(large_arr > 0.5)
  27. np_count_time = time.time() - start_time
  28. print(f"\nPython循环计数的时间: {py_count_time:.6f}秒")
  29. print(f"NumPy函数计数的时间: {np_count_time:.6f}秒")
  30. print(f"Python/NumPy计数时间比: {py_count_time/np_count_time:.2f}")
  31. # 使用更高效的NumPy函数
  32. start_time = time.time()
  33. count_np_fast = np.count_nonzero(large_arr > 0.5)
  34. np_count_fast_time = time.time() - start_time
  35. print(f"使用np.count_nonzero的时间: {np_count_fast_time:.6f}秒")
  36. print(f"np.sum/np.count_nonzero时间比: {np_count_time/np_count_fast_time:.2f}")
复制代码

总结

NumPy数组长度获取是数据处理和科学计算中的基本操作。本文从基础概念到高级技巧,全面介绍了NumPy数组长度获取的各种方法,并结合实际应用案例、常见错误解析和性能优化策略,帮助开发者更好地处理数组尺寸问题。

关键要点总结:

1. 基础方法:使用len()、size属性和shape属性可以获取数组的不同维度信息。len()返回第一个维度的大小size返回数组元素的总数shape返回一个元组,表示每个维度的大小
2. len()返回第一个维度的大小
3. size返回数组元素的总数
4. shape返回一个元组,表示每个维度的大小
5. 高级技巧:对于多维数组,需要考虑特定轴的长度,可以使用shape属性结合索引来获取。条件筛选后的数组长度可以使用np.sum()或np.count_nonzero()高效计算。
6. 实际应用:在数据预处理、机器学习和图像处理等领域,数组长度获取和处理是常见任务,需要根据具体需求选择合适的方法。
7. 常见错误:维度混淆、索引越界和广播机制中的尺寸不匹配是常见错误,需要理解NumPy的维度系统和广播规则来避免。
8. 性能优化:避免不必要的数组复制、使用视图而非副本、利用NumPy内置函数可以显著提高性能,特别是在处理大型数组时。

基础方法:使用len()、size属性和shape属性可以获取数组的不同维度信息。

• len()返回第一个维度的大小
• size返回数组元素的总数
• shape返回一个元组,表示每个维度的大小

高级技巧:对于多维数组,需要考虑特定轴的长度,可以使用shape属性结合索引来获取。条件筛选后的数组长度可以使用np.sum()或np.count_nonzero()高效计算。

实际应用:在数据预处理、机器学习和图像处理等领域,数组长度获取和处理是常见任务,需要根据具体需求选择合适的方法。

常见错误:维度混淆、索引越界和广播机制中的尺寸不匹配是常见错误,需要理解NumPy的维度系统和广播规则来避免。

性能优化:避免不必要的数组复制、使用视图而非副本、利用NumPy内置函数可以显著提高性能,特别是在处理大型数组时。

通过掌握这些方法和技巧,开发者可以更高效地处理NumPy数组尺寸问题,提高代码的性能和可靠性。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.