基于Pearson相关性使用Awk筛选两个文件的匹配行
基于Pearson相关系数筛选双文件行的Awk解决方案
需求回顾
- 输入文件规则:
file1.txt:共15列,仅用1-14列计算相关性,匹配成功后输出第15列file2.txt:共16列,仅用1-14列计算相关性,匹配成功后输出第15、16列
- 匹配逻辑:将
file1的每一行与file2的所有行逐一计算Pearson相关系数,仅保留系数大于0.9的组合 - 输出格式:3列结果,顺序为
file1第15列、file2第15列、file2第16列
Awk实现代码
BEGIN { # 参与相关性计算的列数(固定为14列:1-14) col_count = 14 } # 先预加载file2的所有数据、统计量和待输出列 FILENAME == "file2.txt" { # 存储当前行1-14列的每个数值 for (i=1; i<=col_count; i++) { file2_vals[FNR "," i] = $i } # 计算当前行的sum(x)、sum(x²)、sum(x)的平方 sum_x = 0 sum_x2 = 0 for (i=1; i<=col_count; i++) { sum_x += $i sum_x2 += $i * $i } file2_sum_x[FNR] = sum_x file2_sum_x2[FNR] = sum_x2 file2_sum_x_sq[FNR] = sum_x * sum_x # 存储待输出的第15、16列内容 file2_col15[FNR] = $15 file2_col16[FNR] = $16 # 记录file2的总行数 file2_total_rows = FNR next } # 处理file1的每一行,与file2所有行计算相关性 FILENAME == "file1.txt" { # 计算当前行的sum(y)、sum(y²)、sum(y)的平方 sum_y = 0 sum_y2 = 0 for (i=1; i<=col_count; i++) { sum_y += $i sum_y2 += $i * $i } sum_y_sq = sum_y * sum_y # 提取当前行待输出的第15列 output_col1 = $15 # 遍历file2的每一行进行匹配 for (j=1; j<=file2_total_rows; j++) { # 计算对应列的乘积和sum(xy) sum_xy = 0 for (i=1; i<=col_count; i++) { sum_xy += $i * file2_vals[j "," i] } # 计算Pearson相关系数的分子与分母 numerator = col_count * sum_xy - file2_sum_x[j] * sum_y denom_part1 = col_count * file2_sum_x2[j] - file2_sum_x_sq[j] denom_part2 = col_count * sum_y2 - sum_y_sq denominator = sqrt(denom_part1 * denom_part2) # 跳过分母为0的情况,避免计算错误 if (denominator == 0) continue r = numerator / denominator # 满足阈值则输出结果 if (r > 0.9) { print output_col1, file2_col15[j], file2_col16[j] } } }
使用方法
- 将上述代码保存为
filter_correlation.awk文件 - 执行以下命令(注意必须先传入
file2.txt,确保Awk先预加载其数据):
awk -f filter_correlation.awk file2.txt file1.txt
测试示例
测试数据
file1.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 f1_row1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 f1_row2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 f1_row3 3 6 9 12 15 18 21 24 27 30 33 36 39 42 f1_row4
file2.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 f2_row1_col15 f2_row1_col16 2 4 6 8 10 12 14 16 18 20 22 24 26 28 f2_row2_col15 f2_row2_col16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f2_row3_col15 f2_row3_col16 3 6 9 12 15 18 21 24 27 30 33 36 39 42 f2_row4_col15 f2_row4_col16
示例输出
f1_row1 f2_row1_col15 f2_row1_col16 f1_row2 f2_row2_col15 f2_row2_col16 f1_row4 f2_row4_col15 f2_row4_col16
内容的提问来源于stack exchange,提问作者Gery
相关产品推荐
相关产品推荐

