python – 计算允许不匹配的唯一句子数

我有一个包含2亿个句子的文本文件.我想计算文件中特定类型句子的出现次数,并允许两个不匹配的字符(这可能是重复字符的插入,或两个缺少的字符).字符总是A,G,C或T.不匹配字符的位置可以是随机的.我提供了一个小样本来说明我要解释的内容:

我有以下句子:

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT
GTTTAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT
GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTAAT
TAACGTTCAGTTACGGCGTTGAGGTTTTACCTAAGATCGGAAGAGCTCGT
TCCGTAGCGCTCTGCTTCCAGTCGTGGCGGGGAGATCGGAAGAGCTCGTA
TACAAGACTTCATGAATAACGTGACTACGGAGATCGGAAGAGCTCGTATG
TAATGCCACTCCTCTCCCGACTGTTAACACTACTGGTTATATTGACCATG
CGACCTGGGTCAGCTCTGGAGTTTCGTTGAGTTAGATCGGAAGAGCTCGT
ATTTTGATAGTTTGACGGTTAATGCTGGTAATGGTGGTTTTCTTCATTGC
ACCCATGCCTACAGTATTGTTATCGGTAGCAAGCACATCACCTTGAATGC
GCAAGTTGCCATACAAAACAGGGTCGCCAGCAATATCGGTATAAGTCAAA
GAGTTCTAGTGTACGAGAGAGAGACGACGATGGAGATCGGAAGCGCTCTT
TGTTACTACAGGCATAATACGTGTTCCCGGATGAAGATCGGAAGAGCTCG
GACGACCAAAATTAGGGTCAACGCTACCTGTAGGAAGTGTCCGCATAAAG

例如,如果这是我正在看的第一句话

 GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT

然后是文件中的第二句

 GT**TT**AGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT

将与第一句类似,因为只有2个字符的区别.

然后是文件中的第三个句子

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCT**AA**T

在这里,最后但两个字符被修改,但其他一切都与第一句话类似.

因此,未改变的句子可以是任何东西,然后将其余句子与两个不匹配的句子进行比较然后计算.差异可能是重复字符或缺少字符,或新字符.并且,最后当您读取文件时,输出将是特定句子出现3次以允许不匹配.

GTCGAGGTTCTCATCGCCTGGCCGCGCGTGTCTAGATCGGAAGAGCTCGT 3 times

有没有办法可以使用awk?我试过了:

cat myfile.fq | 
awk '((NR-2)%4==0){character=$1;total++;count[character]++}END{for(character 
   in count){if(!max||count[character]>max) 
    {max=count[character];maxcharacter=character};if(count[character]==1){unique++}};print  total,unique}'

由Ed Morton编辑 – 通过C美化器(https://codebeautify.org/c-formatter-beautifier)运行上述awk脚本以使其可读产生:

((NR - 2) % 4 == 0) {
  character = $1;
  total++;
  count[character]++
}
END {
  for (character in count) {
    if (!max || count[character] > max) {
      max = count[character];
      maxcharacter = character
    };
    if (count[character] == 1) {
      unique++
    }
  };
  print total, unique
}

最佳答案 您的要求不明确,但这是我认为您可能尝试做的一个开始:

$cat tst.awk
BEGIN {
    tgtStr  = "APPLEISHEALTHY"
    tgtLgth = length(tgtStr)
}
{
    curStr  = $0
    curLgth = length(curStr)

    isMatch = 0

    if ( curStr == tgtStr ) {
        # curStr is tgtStr
        # "APPLEISHEALTHY" vs "APPLEISHEALTHY"
        isMatch = 1
    }
    else if ( curLgth == (tgtLgth-2) ) {
        # curStr may be tgtStr minus 2 chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALT"
        isMatch = 1
        maxLgth = tgtLgth
        curPos = tgtPos = 0
        for (pos=1; pos<=maxLgth; pos++) {
            curChar = substr(curStr,++curPos,1)
            tgtChar = substr(tgtStr,++tgtPos,1)
            if (curChar != tgtChar) {
                if (curPos == tgtPos) {
                    # first char mismatch but curStr is 2 chars shorter
                    # than tgtStr so thats expected so advance tgtPos
                    # 1 char and back up curPos 1 char and continue.
                    curPos--
                    tgtPos++
                }
                else {
                    # still mismatching after first 2-char skip so fail
                    isMatch = 0
                }
            }
        }
    }
    else if ( curLgth == tgtLgth ) {
        # curStr may be tgtStr minus 2 chars plus 2 other chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALTXX"
    }
    else if ( curLgth == (tgtLgth+2) ) {
        # curStr may be tgtStr plus 2 chars, e.g.
        # "APPLEISHEALTHY" vs "APPLEISHEALTHYXX"
    }

    print curStr, (isMatch ? "is" : "is not"), "a match for", tgtStr
}

例如:

$cat file
APPLEISHEALTHY
APPLEISALTHY
APPLEISXLTHY

$awk -f tst.awk file
APPLEISHEALTHY is a match for APPLEISHEALTHY
APPLEISALTHY is a match for APPLEISHEALTHY
APPLEISXLTHY is not a match for APPLEISHEALTHY

你必须仔细考虑上面的逻辑,看看它是否正确并为其余2个案例编写逻辑,但希望这能告诉你如何处理这个问题.

点赞