Gravando um DataFrame do pandas em um arquivo CSV

715

Eu tenho um quadro de dados em pandas que gostaria de gravar em um arquivo CSV. Estou fazendo isso usando:

df.to_csv('out.csv')

E recebendo o erro:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u03b1' in position 20: ordinal not in range(128)

Existe alguma maneira de contornar isso facilmente (ou seja, eu tenho caracteres unicode no meu quadro de dados)? E existe uma maneira de gravar em um arquivo delimitado por tabulação em vez de um CSV usando, por exemplo, um método 'to-tab' (que eu acho que não existe)?

user7289
fonte

Respostas:

1045

Para delimitar por uma guia, você pode usar o separgumento de to_csv:

df.to_csv(file_name, sep='\t')

Para usar uma codificação específica (por exemplo, 'utf-8'), use o encodingargumento:

df.to_csv(file_name, sep='\t', encoding='utf-8')
Andy Hayden
fonte
32
Eu adicionaria index=Falsepara soltar o índice.
Medhat
11
Inicialmente, fiquei confuso sobre como encontrei uma resposta para a pergunta que já havia escrito há 7 anos.
Hayden
251

Quando você está armazenando um DataFrameobjeto em um arquivo csv usando o to_csvmétodo, provavelmente não precisará armazenar os índices anteriores de cada linha do DataFrameobjeto.

Você pode evitar isso passando um Falsevalor booleano para o indexparâmetro

Um pouco como:

df.to_csv(file_name, encoding='utf-8', index=False)

Portanto, se seu objeto DataFrame é algo como:

  Color  Number
0   red     22
1  blue     10

O arquivo csv armazenará:

Color,Number
red,22
blue,10

em vez de (o caso em que o valor padrão True foi passado)

,Color,Number
0,red,22
1,blue,10
Sayan Sil
fonte
E se a indexação for desejada, mas também tiver um título? Você apenas usa df.rename_axis('index_name')? que não altera o arquivo em si
Zap
20

Para gravar um DataFrame do pandas em um arquivo CSV, você precisará DataFrame.to_csv. Essa função oferece muitos argumentos com padrões razoáveis ​​que você precisará substituir com mais freqüência do que o seu caso de uso específico. Por exemplo, convém usar um separador diferente, alterar o formato de data e hora ou soltar o índice ao escrever. to_csvpossui argumentos que você pode passar para atender a esses requisitos.

Aqui está uma tabela listando alguns cenários comuns de gravação em arquivos CSV e os argumentos correspondentes que você pode usar para eles.

Escreva para CSV ma dude

Notas de rodapé

  1. O separador padrão é considerado uma vírgula ( ','). Não mude isso, a menos que você saiba que precisa.
  2. Por padrão, o índice de dfé gravado como a primeira coluna. Se o seu DataFrame não tiver um índice (IOW, o df.indexé o padrão RangeIndex), convém definir index=Falseao escrever. Para explicar isso de uma maneira diferente, se seus dados tiverem um índice, você pode (e deve) usar index=Trueou simplesmente deixá-lo de fora completamente (como o padrão True).
  3. Seria aconselhável definir esse parâmetro se você estiver gravando dados de sequência para que outros aplicativos saibam ler seus dados. Isso também evitará possíveis UnicodeEncodeErrors que você possa encontrar ao salvar.
  4. A compactação é recomendada se você estiver gravando DataFrames grandes (> 100K linhas) no disco, pois isso resultará em arquivos de saída muito menores. OTOH, isso significa que o tempo de gravação aumentará (e, consequentemente, o tempo de leitura desde que o arquivo precisará ser descompactado).
cs95
fonte
18

Outra coisa que você pode tentar se estiver com problemas de codificação para 'utf-8' e quiser ir célula por célula, tente o seguinte.

Python 2

(Onde "df" é seu objeto DataFrame.)

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = unicode(x.encode('utf-8','ignore'),errors ='ignore') if type(x) == unicode else unicode(str(x),errors='ignore')
            df.set_value(idx,column,x)
        except Exception:
            print 'encoding error: {0} {1}'.format(idx,column)
            df.set_value(idx,column,'')
            continue

Então tente:

df.to_csv(file_name)

Você pode verificar a codificação das colunas:

for column in df.columns:
    print '{0} {1}'.format(str(type(df[column][0])),str(column))

Aviso: erros = 'ignorar' apenas omitirá o caracter, por exemplo

IN: unicode('Regenexx\xae',errors='ignore')
OUT: u'Regenexx'

Python 3

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = x if type(x) == str else str(x).encode('utf-8','ignore').decode('utf-8','ignore')
            df.set_value(idx,column,x)
        except Exception:
            print('encoding error: {0} {1}'.format(idx,column))
            df.set_value(idx,column,'')
            continue
Glen Thompson
fonte
11

Às vezes, você enfrenta esses problemas se especificar também a codificação UTF-8. Eu recomendo que você especifique a codificação durante a leitura do arquivo e a mesma codificação durante a gravação no arquivo. Isso pode resolver seu problema.

Harsha Komarraju
fonte
7

Exemplo de exportação em arquivo com caminho completo no Windows e caso seu arquivo tenha cabeçalhos :

df.to_csv (r'C:\Users\John\Desktop\export_dataframe.csv', index = None, header=True) 

Exemplo se você deseja armazenar na pasta no mesmo diretório em que seu script está, com a codificação utf-8 e a guia como separador :

df.to_csv(r'./export/dftocsv.csv', sep='\t', encoding='utf-8', header='true')
Harvey
fonte
7

poderia não ser a resposta para este caso, mas como eu tinha a mesma mensagem de erro com .to_csveu tentei .toCSV('name.csv')e a mensagem de erro era diferente (" SparseDataFrame' object has no attribute 'toCSV'). Portanto, o problema foi resolvido transformando o dataframe em um denso dataframe

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Yury Wallet
fonte
Você recebeu o erro no segundo, pois parece que você usou .toCSVe não .to_csv. Você esqueceu o sublinhado
Kyle C