조건부로 행을 숫자로 바꾸기

조건부로 행을 숫자로 바꾸기

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해야 합니다 .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등) 를 테스트/조작할 수 있습니다.

관련 정보