You need to enable JavaScript to run this app. 使用awk实现多列字符串计数的长格式转宽格式
优惠活动
大模型
产品
解决方案
定价
更多

使用awk实现多列字符串计数的长格式转宽格式

长格式转宽格式的字符串频次统计实现方案

核心适配逻辑

你之前写的awk代码是针对数值列做累加、按分组求平均的场景,无法满足当前需求的核心原因是没有加入「分组内不同字符串值的独立计数」逻辑,改造后的逻辑完全匹配需求:

  • 以第一列的样本ID为一级分组维度
  • 对第二、第三列的每个不同字符串值单独累加出现次数
  • 遍历分组下的所有计数结果,按要求拼接成出现次数_字符串格式,同列多个值用逗号分隔

方案1:原生awk实现(无需额外依赖,适配你当前的使用习惯)

直接替换原有命令即可,适配你提供的示例输入:

awk '
# 逐行读取原始数据
{
    sample = $1
    # 统计第二列各字符串的出现次数:计数结构为 [样本ID][字符串值] = 累计次数
    col2_cnt[sample][$2]++
    # 统计第三列各字符串的出现次数:计数结构为 [样本ID][字符串值] = 累计次数
    col3_cnt[sample][$3]++
}
# 所有数据读取完成后输出结果
END {
    # 遍历每个样本的分组数据
    for (sid in col2_cnt) {
        col2_str = ""
        # 拼接第二列的目标格式
        for (str_val in col2_cnt[sid]) {
            col2_str = col2_str (col2_str ? "," : "") col2_cnt[sid][str_val] "_" str_val
        }
        col3_str = ""
        # 拼接第三列的目标格式
        for (str_val in col3_cnt[sid]) {
            col3_str = col3_str (col3_str ? "," : "") col3_cnt[sid][str_val] "_" str_val
        }
        # 输出最终宽格式结果
        print sid "\t" col2_str "\t" col3_str
    }
}
' your_raw_data.txt

输出校验(匹配你给出的预期结果)

79264   3_Bacteria  3_Firmicutes
2947    7_Bacteria  6_Nitrospirae,1_Proteobacteria

注意:高版本gawk(4.0及以上)才支持二维数组结构,如果你使用的是低版本awk(比如macOS自带的默认awk),可以改用一维拼接结构实现,兼容性更强,逻辑完全一致:

awk '
{
    col2_cnt[$1 SUBSEP $2]++
    col3_cnt[$1 SUBSEP $3]++
    sample_list[$1] = 1
}
END {
    for (sid in sample_list) {
        col2_str = ""; col3_str = ""
        # 匹配当前样本下所有第二列的计数记录
        for (key in col2_cnt) {
            split(key, parts, SUBSEP)
            if (parts[1] == sid) {
                col2_str = col2_str (col2_str ? "," : "") col2_cnt[key] "_" parts[2]
            }
        }
        # 匹配当前样本下所有第三列的计数记录
        for (key in col3_cnt) {
            split(key, parts, SUBSEP)
            if (parts[1] == sid) {
                col3_str = col3_str (col3_str ? "," : "") col3_cnt[key] "_" parts[2]
            }
        }
        print sid "\t" col2_str "\t" col3_str
    }
}
' your_raw_data.txt

方案2:Python pandas 实现(适合后续需要做复杂数据清洗的场景)

如果数据量较大、后续还要开展多步分析,用pandas的分组聚合逻辑实现更简洁易维护:

import pandas as pd
# 读取原始长格式数据
df = pd.read_csv("your_raw_data.txt", sep="\t", header=None, names=["sample", "col2", "col3"])
# 自定义拼接函数:按字符串值分组计数,生成目标格式的拼接结果
def format_cnt(series):
    cnt = series.value_counts()
    return ",".join([f"{v}_{k}" for k, v in cnt.items()])
# 按第一列分组,分别对第二、第三列做格式转换
result = df.groupby("sample").agg(
    col2=("col2", format_cnt),
    col3=("col3", format_cnt)
).reset_index()
# 输出无表头的宽格式结果
result.to_csv("wide_format_result.txt", sep="\t", index=False, header=False)

内容的提问来源于stack exchange,提问作者guest33

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 11:06:06