条件付きで行を数字に置き換える

条件付きで行を数字に置き換える

27列とほぼ600万行の大容量ファイルがあります。以下は私のファイルの小さな例です。

head data
0.65   0.722222   1.0      0.75     0
0.35   0.277778   0.0      0.25     0
0      0.666667   0.75     0.5      0.5625
0      0.333333   0.25     0.5      0.4375 

行はサンプルであり、「サンプルごとに2つの行」があります(1つは観察「a」、もう1つは観察「b」です)。上記の例では、2つのサンプルのデータが表示されています(1行と2行はサンプル1に対応し、3行と4行はサンプル2に対応します)。各サンプルの両方の観測値が0であることを確認し、それを9に置き換えたいと思います。これが私が望む結果です:

head desired
0.65   0.722222   1.0      0.75     9
0.35   0.277778   0.0      0.25     9
9      0.666667   0.75     0.5      0.5625
9      0.333333   0.25     0.5      0.4375 

Perl、Python、またはBash(大容量ファイルに対して信頼できる場合)ソリューションを実行するには?過去には、各サンプルのファイルを分割し、各ファイルに対して次のコードを実行しました。

awk 'NR==1 { split($0,a);next;} NR==2 {split($0,b);for(i=1;i<= NF;i++) printf("%s%s",(i==1?"":"\t"),a[i]==0 && b[i]==0?9:a[i]);
printf("\n");;for(i=1;i<= NF;i++) printf("%s%s",(i==1?"":"\t"),a[i]==0 && b[i]==0?9:b[i]);printf("\n");} ' 

しかし、今では、ファイル全体に対してこれを実行したいと分割したくありません。

ありがとうございます。

ありがとうございます。

答え1

Pythonで行う方法は次のとおりです。

#!/usr/bin/env python3

firstLineZero = False

# Open the file for reading
with open("biodata2", "r") as inFile:
    for line in inFile:
        # Check if last value in line is 0
        if not firstLineZero and line.split()[-1] == "0":
            # Save this line, and set a boolean
            firstLineZero = True
            prevLine = line
        elif firstLineZero and line.split()[-1] == "0":
            # Now we know that both lines end with 0.
            # Change the final value to 9 in both lines...
            prevLineSplit = prevLine.split()
            thisLineSplit = line.split()
            prevLineSplit[-1] = "9" 
            thisLineSplit[-1] = "9" 
            prevLine = "\t".join(prevLineSplit)
            thisLine = "\t".join(thisLineSplit)
            print(prevLine)
            print(thisLine)
            # Reset boolean
            firstLineZero = False
            # Reset prevLine
            prevLine = ""
        else:
            print(line, end="")

# If we have a 'trailing' saved line, print that
if prevLine is not None:
    print(prevLine, end="")

数行のコードでPOCを提供する例を実装してください。

データ:

cat biodata2 
0.65    0.722222    1.0     0.75    0
0.35    0.277778    0.0     0.25    0
0       0.666667    0.75    0.5     0.5625
0       0.333333    0.25    0.5     0.4375
0       0.333333    0.25    0.5     1
0       0.333333    0.25    0.5     0

実装する:

./readBioData.py
0.65    0.722222    1.0     0.75    9
0.35    0.277778    0.0     0.25    9
0       0.666667    0.75    0.5     0.5625
0       0.333333    0.25    0.5     0.4375
0       0.333333    0.25    0.5     1
0       0.333333    0.25    0.5     0

明らかに印刷するのではなくファイルに保存するには、ステートメントをに変更して書き込み用のファイルを設定するstdout必要があります。printwrite

このように:

#!/usr/bin/env python3

firstLineZero = False
outFile = open("bioDataOut.txt", "w")

# Open the file for reading
with open("biodata2", "r") as inFile:
    for line in inFile:
        # Check if last value in line is 0
        if not firstLineZero and line.split()[-1] == "0":
            # Save this line, and set a boolean
            firstLineZero = True
            prevLine = line
        elif firstLineZero and line.split()[-1] == "0":
            # Now we know that both lines end with 0.
            # Change the final value to 9 in both lines...
            prevLineSplit = prevLine.split()
            thisLineSplit = line.split()
            prevLineSplit[-1] = "9" 
            thisLineSplit[-1] = "9" 
            prevLine = "\t".join(prevLineSplit)
            thisLine = "\t".join(thisLineSplit)
            outFile.write(prevLine + "\n")
            outFile.write(thisLine + "\n")
            # Reset boolean
            firstLineZero = False
            # Reset prevLine
            prevLine = ""
        else:
            outFile.write(line)

# If we have a 'trailing' saved line, print that
if prevLine is not None:
    outFile.write(prevLine)

outFile.close()

これにより、次のことができます。

./readBioDataSaveToFile.py
cat bioDataOut.txt 
0.65    0.722222    1.0     0.75    9
0.35    0.277778    0.0     0.25    9
0       0.666667    0.75    0.5     0.5625
0       0.333333    0.25    0.5     0.4375
0       0.333333    0.25    0.5     1
0       0.333333    0.25    0.5     0

答え2

ラインペアを処理する秘訣は、ラインペアをマージすることです。

paste - - < paired_file

その後、awkを使用してフィールド($1==0 && $6==0など)をテスト/操作できます。

関連情報