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
必要があります。print
write
このように:
#!/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
など)をテスト/操作できます。