N linhas aleatórias de Python de um arquivo grande (sem linhas duplicadas)

Eu preciso usar python para pegar o número N de linhas de arquivo txt grande. Esses arquivos são basicamente tabelas delimitadas por tabulações. Minha tarefa tem as seguintes restrições:

Esses arquivos podem conter cabeçalhos (alguns têm cabeçalhos de várias linhas).Os cabeçalhos precisam aparecer na saída na mesma ordem.Cada linha pode ser tomada apenas uma vez.O maior arquivo atualmente é de cerca de 150 GB (cerca de 60.000.000 linhas).As linhas têm aproximadamente o mesmo comprimento em um arquivo, mas podem variar entre arquivos diferentes.Eu usarei normalmente 5000 linhas aleatórias (posso precisar de até 1 000 000 linhas)

Atualmente eu escrevi o seguinte código:

inputSize=os.path.getsize(options.input)
usedPositions=[] #Start positions of the lines already in output

with open(options.input) as input:
    with open(options.output, 'w') as output:

        #Handling of header lines
        for i in range(int(options.header)):
            output.write(input.readline())
            usedPositions.append(input.tell())

        # Find and write all random lines, except last
        for j in range(int(args[0])):
            input.seek(random.randrange(inputSize)) # Seek to random position in file (probably middle of line)
            input.readline() # Read the line (probably incomplete). Next input.readline() results in a complete line.
            while input.tell() in usedPositions: # Take a new line if current one is taken
                input.seek(random.randrange(inputSize))
                input.readline() 
            usedPositions.append(input.tell()) # Add line start position to usedPositions
            randomLine=input.readline() # Complete line
            if len(randomLine) == 0: # Take first line if end of the file is reached
                input.seek(0)
                for i in range(int(options.header)): # Exclude headers
                    input.readline()
                randomLine=input.readline()
            output.write(randomLine)            

Este código parece estar funcionando corretamente.

Estou ciente de que este código prefere linhas que seguem as linhas mais longas na entrada, porque é mais provável que seek () retorne uma posição na linha mais longa e a próxima linha seja gravada na saída. Isso é irrelevante, pois as linhas no arquivo de entrada são aproximadamente do mesmo tamanho. Também estou ciente de que este código resulta em um loop infinito se N for maior que o número de linhas no arquivo de entrada. Não implementarei uma verificação para isso, pois a contagem da linha leva muito tempo.

Limitações de RAM e HDD são irrelevantes. Estou preocupado apenas com a velocidade do programa. Existe uma maneira de otimizar ainda mais esse código? Ou talvez haja uma abordagem melhor?

EDITAR: Para esclarecer, as linhas em um arquivo têm aproximadamente o mesmo tamanho. No entanto, eu tenho vários arquivos que este script precisa ser executado e o comprimento médio de uma linha será diferente para esses arquivos. Por exemplo, o arquivo A pode ter ~ 100 caracteres por linha e arquivo B ~ 50000 caracteres por linha. Eu não sei o comprimento médio da linha de qualquer arquivo de antemão.

questionAnswers(5)

yourAnswerToTheQuestion