Pergunta

Ok, aqui está o meu código existente:

////////////// = []
for line in datafile:
    splitline = line.split()
    for item in splitline:
        if not item.endswith("JAX"):
            if item.startswith("STF") or item.startswith("BRACKER"):
                //////////.append( item )


for line in //////////
    print /////////////
   /////////// +=1
    for t in//////
        if t in line[:line.find(',')]:
            line = line.strip().split(',')
           ///////////////write(','.join(line[:3]) + '\n') 
            break

/////////////.close()
/////////////close()
///////////.close()

Eu quero fazer uma otimização adicional. O arquivo é realmente grande. Eu gostaria de excluir as linhas dela que foram correspondidas depois que elas foram correspondidas e escritas com o pequeno arquivo para reduzir a quantidade de tempo necessária para pesquisar o arquivo grande. Alguma sugestão de como devo fazer isso?

Foi útil?

Solução

Você não pode excluir linhas em um arquivo de texto - seria necessário mover todos os dados após a linha excluída para preencher a lacuna e seria massivamente ineficiente.

Uma maneira de fazer isso é escrever um arquivo temp com todas as linhas que você deseja manter no bigfile.txt e quando você terminar o processamento, exclua bigfile.txt e renomeie o arquivo temp para substituí -lo.

Como alternativa, se o bigfile.txt for pequeno o suficiente para caber na memória, você pode ler o arquivo inteiro em uma lista e excluir as linhas da lista e, em seguida, escrever a lista de volta no disco.

Eu também adivinharia no seu código que o bigfile.txt é algum tipo de arquivo CSV. Nesse caso, pode ser melhor convertê -lo em um arquivo de banco de dados e usar o SQL para consultá -lo. O Python vem com o módulo SQLite incorporado e existem bibliotecas de terceiros para a maioria dos outros bancos de dados.

Outras dicas

Como eu disse em um comentário, não me parece que o tamanho do "bigfile" deve estar diminuindo a velocidade com que a contagem incrementa. Quando você itera sobre um arquivo como esse, Python apenas lê uma linha de cada vez em ordem.

As otimizações que você pode fazer neste momento dependem de quão grandes são as linhas correspondentes e em qual relacionamento as strings de linhas correspondentes têm com o texto que você está procurando.

Se as linhas correspondentes forem grandes, você poderá economizar tempo apenas fazendo o 'Localizar' uma vez:

for line in completedataset:
   text = line[:line.find(',')] 
   for t in matchedLines:
        if t in text:
            line = line.strip().split(',')
            smallerdataset.write(','.join(line[:3]) + '\n') 
            break

Nos meus testes, o 'Find' levou cerca de 300 nanossegundos; portanto, se o MatchedLines tiver alguns milhões de itens, há o seu segundo extra ali.

Se você está procurando correspondências exatas, não correspondências de substring, pode acelerar as coisas usando um conjunto:

matchedLines = set(matchedLines)
for line in completedataset:
    target = line[:line.find(',')]
    ## One lookup and you're done!
    if target in matchedLines:
        line = line.strip().split(',')
        smallerdataset.write(','.join(line[:3]) + '\n') 

Se os textos de destino que não correspondem tendem a parecer completamente diferentes dos que o fazem (por exemplo, a maioria dos alvos são strings aleatórios, e linhas correspondentes são um monte de nomes) e as linhas correspondentes estão acima de um determinado comprimento, você pode Tente ficar realmente inteligente, verificando as substâncias. Suponha que todas as linhas correspondentes tenham pelo menos 5 caracteres ...

def subkeys(s):
    ## e.g. if len(s) is 7, return s[0:5], s[1:6], s[2:7].
    return [s[i:i+5] for i in range(len(s) + 1 - 5)]

existing_subkeys = set()
for line in matchedLines:
    existing_subkeys.update(subkeys(line))

for line in completedataset:
    target = line[:line.find(',')]
    might_match = False
    for subkey in subkeys(target):
        if subkey in existing_subkeys:
            might_match = True
            break
    if might_match:
        # Then we have to do the old slow way.
        for matchedLine in matchedLines:
            if matchedLine in target:
                # Do the split and write and so on.

Mas é realmente fácil se enganar tentando fazer coisas assim, e isso depende de como seus dados são.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top