You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过子矩阵均值实现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)

关键细节说明

  1. 子矩阵跨度计算:用math.ceil(原维度/目标维度)确保所有元素都被划分到子矩阵中,避免遗漏
  2. 边界处理:最后一个子矩阵的起止索引通过min()函数截断,防止超出原矩阵范围
  3. 数据兼容性:Pandas版本自动处理数值型数据,纯Python版本假设数据为数值型,若有混合类型需提前做类型转换

内容的提问来源于stack exchange,提问作者S. M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:14:52