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개의 행"이 있습니다(하나는 관찰 "a"에 대한 것이고 다른 하나는 관찰 "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
등) 를 테스트/조작할 수 있습니다.