如何添加两列 DataFrame 并使用前缀名称重命名 bash

How to Add Two Columns of DataFrame and Rename it with Prefix Name using bash

The original Data looks like

ID,kgp11274425_A,kgp11274425_HET,kgp5732633_C,kgp5732633_HET,rs707_G,rs707_HET,kgp75_T,kgp75_HET
1,C,T,G,T,C,A,0,0
2,C,C,T,G,A,A,G,T
3,A,A,G,G,C,G,A,A
4,G,G,C,C,A,A,T,A

Desired Output:

ID,kgp11274425,kgp5732633,rs707,kgp75
1,CT,GT,CA,00
2,CC,TG,AA,GT
3,AA,GG,CG,AA
4,GG,CC,AA,TA

I was able to accomplish this using the following Python Script

sep = '_'
unique_cols = pd.Index(map(lambda x : x.split(sep, 1)[0], df.columns)).unique()

results = []
columns = []
for col in unique_cols:
    my_cols = [x for x in df.columns if x.startswith(col)]
    results.append(df[my_cols].sum(axis=1).values)
    columns.append(col)

new_df = pd.DataFrame(results).T
new_df.columns = columns

但是这次我得到了 522rows & 5311137cols (5GB) 数据,Python 无法读取文件。所以我需要使用 bash 命令 运行 相同的 python 逻辑,bash 的新手请帮助

输入:

$ cat raw.dat
ID,kgp11274425_A,kgp11274425_HET,kgp5732633_C,kgp5732633_HET,rs707_G,rs707_HET,kgp75_T,kgp75_HET
1,C,T,G,T,C,A,0,0
2,C,C,T,G,A,A,G,T
3,A,A,G,G,C,G,A,A
4,G,G,C,C,A,A,T,A

一个awk想法:

awk -F, '
{ printf                                                 # print 1st column
  for (i=2;i<=NF;i=i+2) {                                  # process columns 2 at a time
      if (FNR==1)                                          # 1st row? then ...
         printf "%s%s", FS, substr($i,1,index($i,"_")-1)   # print ith column sans the '_xxxx' suffix
      else
         printf "%s%s%s", FS, $i, $(i+1)                   # print the (i)th and (i+1)th columns
  }
  print ""
}
' raw.dat

这会生成:

ID,kgp11274425,kgp5732633,rs707,kgp75
1,CT,GT,CA,00
2,CC,TG,AA,GT
3,AA,GG,CG,AA
4,GG,CC,AA,TA

注意: OP 的所需输出似乎不是 single-space 分隔的,也不是制表符分隔的,所以我选择了一个 space; OP 可以修改 printf 格式字符串以完成所需的格式

基本方法是模拟 FPAT 的功能,但以更便携的方式 - 此代码已经过测试并确认可以在 gawk 5.1.1 上运行,包括标志 -ce/-Pemawk 1.3.4mawk 1.9.9.6macOS 12.3 nawk

ID, kgp11274425     kgp5732633      rs707       kgp75       
1       CT            GT              CA       00
2       CC            TG              AA       GT
3       AA            GG              CG       AA
4       GG            CC              AA       TA

[mng]awk 'BEGIN {

    FS = "[_][^_]+[_][^,]+[,]?[ " (substr(\
   OFS = "\t\t", _+=_=_~_))  "]*"

    print $( (getline) < -(NF=NF) )

    __ = (__="[^ \t]+") substr(_=substr(___="&",_) \
               "[ \t]+",  index(_, "[") ) __ "|_"
    FS = "^$"

 } gsub(__,___) + gsub(_,"")' datafile.txt
  1. 通过使用 regex,它避免了手动循环 字段,即使一次 2 个字段。 </code> (<code>ACK + ETX) 只是 ASCII-only SEPSUBSEP (4) 或 null-byte ([=23=]).

  2. 第二个优点是通过独立的逻辑 试图模拟 FPATFS 可以直接设置为 ^$, 因为拆分各个领域的理由是不 不再适用...

    。 . .希望这可以帮助推动事情发展,因为 OP 确实提到了 500K+ 列。

  • 此解决方案的注意事项是它不会尝试以完美的方式排列所有内容,而是使用 \t\t 2 个水平制表符作为粗略的解决方案。

综合 5GB 文件基准测试: 1 min 14 secs 用于 5.12GB 文件,read-in 吞吐率为 70.5 MB/s

     out9: 2.54GiB 0:01:14 [34.9MiB/s] [34.9MiB/s]
           [====================================>] 102%
      in0: 5.12GiB 0:01:14 [70.5MiB/s] [70.5MiB/s]
           [====================================>] 100%            
( pvE 0.1 in0 < testcase_dna_002.txt | gawk -be ; )  

  73.44s user 2.20s system 101% cpu 1:14.37 total

nice pv -pteba -i 0.25 -r --size='2540m' -cN out9 > /dev/null  0.24s 

 user 0.73s system 1% cpu 1:14.37 total