如何通过子矩阵均值实现CSV降维?求对应Python代码
Python实现基于子矩阵均值的CSV矩阵降维
问题描述
现有m×n(m行n列)的CSV文件,需通过子矩阵均值替换实现降维,核心规则:
- 将原矩阵划分为对应目标维度的子矩阵,每个子矩阵的均值作为降维后矩阵的对应元素
- 当原维度不是目标维度的倍数时,用天花板函数确定初始子矩阵的行/列大小,边缘剩余元素直接计算均值
典型场景示例
比如原5×6矩阵降维为2×2时:
- 行方向分为两组:前3行、后2行;列方向分为两组:每组3列
- 前3行+前3列的子矩阵均值为结果第一行第一列元素,后2行+前3列的均值为结果第二行第一列元素,以此类推
实现代码(Pandas版本,高效简洁)
import pandas as pd import math def csv_submatrix_mean_downscale(input_path, output_path, target_rows, target_cols): # 读取CSV,保留表头 df = pd.read_csv(input_path) original_rows, original_cols = df.shape # 计算子矩阵的行/列跨度(天花板函数确保覆盖所有元素) row_step = math.ceil(original_rows / target_rows) col_step = math.ceil(original_cols / target_cols) # 初始化结果表,生成新表头 new_headers = [f"col{i+1}" for i in range(target_cols)] result_df = pd.DataFrame(columns=new_headers) # 遍历每个目标行组 for row_idx in range(target_rows): # 确定当前行组的起止索引,最后一组自动截断到原矩阵末尾 start_row = row_idx * row_step end_row = min((row_idx + 1) * row_step, original_rows) current_row_group = df.iloc[start_row:end_row, :] # 计算当前行的所有列均值 current_row_data = [] for col_idx in range(target_cols): start_col = col_idx * col_step end_col = min((col_idx + 1) * col_step, original_cols) # 提取子矩阵并计算均值 submatrix = current_row_group.iloc[:, start_col:end_col] mean_val = submatrix.values.mean() current_row_data.append(mean_val) result_df.loc[len(result_df)] = current_row_data # 导出结果CSV(不保留索引) result_df.to_csv(output_path, index=False) # 示例调用 if __name__ == "__main__": # 参数:输入路径、输出路径、目标行数、目标列数 csv_submatrix_mean_downscale("input.csv", "output.csv", 2, 2)
纯Python标准库实现(无依赖)
如果环境无法安装Pandas,可使用csv标准库实现:
import csv import math def csv_submatrix_mean_downscale_no_pandas(input_path, output_path, target_rows, target_cols): # 读取CSV数据(假设所有数据为数值型,若有字符串需提前转换) with open(input_path, 'r', newline='') as infile: reader = csv.reader(infile) headers = next(reader) data = [list(map(float, row)) for row in reader] original_rows = len(data) original_cols = len(data[0]) if original_rows > 0 else 0 row_step = math.ceil(original_rows / target_rows) col_step = math.ceil(original_cols / target_cols) # 生成结果数据 result_data = [] result_data.append([f"col{i+1}" for i in range(target_cols)]) # 新表头 for row_idx in range(target_rows): start_row = row_idx * row_step end_row = min((row_idx + 1) * row_step, original_rows) current_rows = data[start_row:end_row] row_means = [] for col_idx in range(target_cols): start_col = col_idx * col_step end_col = min((col_idx + 1) * col_step, original_cols) # 收集子矩阵所有元素 sub_elements = [] for row in current_rows: sub_elements.extend(row[start_col:end_col]) # 计算均值(处理空矩阵边界情况) mean_val = sum(sub_elements) / len(sub_elements) if sub_elements else 0.0 row_means.append(mean_val) result_data.append(row_means) # 写入结果CSV with open(output_path, 'w', newline='') as outfile: writer = csv.writer(outfile) writer.writerows(result_data) # 示例调用 if __name__ == "__main__": csv_submatrix_mean_downscale_no_pandas("input.csv", "output_no_pandas.csv", 2, 2)
关键细节说明
- 子矩阵跨度计算:用
math.ceil(原维度/目标维度)确保所有元素都被划分到子矩阵中,避免遗漏 - 边界处理:最后一个子矩阵的起止索引通过
min()函数截断,防止超出原矩阵范围 - 数据兼容性:Pandas版本自动处理数值型数据,纯Python版本假设数据为数值型,若有混合类型需提前做类型转换
内容的提问来源于stack exchange,提问作者S. M.
相关产品推荐
相关产品推荐

