Запись DataFrame для панд в файл CSV

717

У меня есть данные в пандах, которые я хотел бы записать в файл CSV. Я делаю это с помощью:

df.to_csv('out.csv')

И получаю ошибку:

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

Есть ли способ обойти это легко (то есть у меня есть символы Юникода в моем фрейме данных)? И есть ли способ записи в файл с разделителями табуляции вместо CSV, используя, например, метод «to-tab» (который, я думаю, не существует)?

user7289
источник

Ответы:

1047

Чтобы разделить вкладку, вы можете использовать sepаргумент to_csv:

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

Чтобы использовать определенную кодировку (например, 'utf-8'), используйте encodingаргумент:

df.to_csv(file_name, sep='\t', encoding='utf-8')
Энди Хейден
источник
32
Я бы добавил, index=Falseчтобы уронить индекс.
Медхат,
12
Сначала я был смущен тем, как я нашел ответ на вопрос, который я уже написал 7 лет назад.
Хайден
251

При сохранении DataFrameобъекта в файл CSV , используя to_csvметод, вы , вероятно , не будет необходимости хранить предыдущие показатели каждой строки из DataFrameобъекта.

Вы можете избежать этого, передав Falseбулево значение indexпараметру.

Что-то вроде:

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

Так что, если ваш объект DataFrame выглядит примерно так:

  Color  Number
0   red     22
1  blue     10

CSV-файл будет хранить:

Color,Number
red,22
blue,10

вместо (случай, когда было передано значение по умолчаниюTrue )

,Color,Number
0,red,22
1,blue,10
Саян Сил
источник
Что делать, если индексирование желательно, но также должно иметь заголовок? Вы просто используете df.rename_axis('index_name')? это не изменяет сам файл
Зап
21

Чтобы записать pandas DataFrame в файл CSV, вам потребуется DataFrame.to_csv. Эта функция предлагает множество аргументов с разумными значениями по умолчанию, которые вам чаще всего придется переопределять в соответствии с вашим конкретным вариантом использования. Например, вы можете использовать другой разделитель, изменить формат даты и времени или удалить индекс при записи. to_csvесть аргументы, которые вы можете передать, чтобы удовлетворить эти требования.

Вот таблица, в которой перечислены некоторые распространенные сценарии записи в файлы CSV и соответствующие аргументы, которые вы можете использовать для них.

Написать в CSV ma чувак

Сноски

  1. Разделителем по умолчанию считается запятая ( ','). Не меняйте это, если не знаете, что вам нужно.
  2. По умолчанию индекс dfзаписывается как первый столбец. Если ваш DataFrame не имеет индекса (IOW, df.indexпо умолчанию RangeIndex), то вы захотите установить его index=Falseпри записи. Чтобы объяснить это по-другому, если ваши данные имеют индекс, вы можете (и должны) использовать его index=Trueили просто не указывать его (по умолчанию True).
  3. Было бы разумно установить этот параметр, если вы пишете строковые данные, чтобы другие приложения знали, как читать ваши данные. Это также позволит избежать любых потенциальных проблем, UnicodeEncodeErrorс которыми вы можете столкнуться при сохранении.
  4. Сжатие рекомендуется, если вы записываете большие DataFrames (> 100K строк) на диск, так как это приведет к гораздо меньшим выходным файлам. OTOH, это будет означать, что время записи увеличится (и, следовательно, время чтения, так как файл необходимо будет распаковать).
cs95
источник
18

Что-то еще, что вы можете попробовать, если у вас есть проблемы с кодировкой 'utf-8' и вы хотите переходить по ячейкам, вы можете попробовать следующее.

Python 2

(Где "df" - это ваш объект 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

Тогда попробуйте:

df.to_csv(file_name)

Вы можете проверить кодировку столбцов:

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

Предупреждение: error = 'ignore' просто пропустит символ, например

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
Глен Томпсон
источник
11

Иногда вы сталкиваетесь с этими проблемами, если указать также кодировку UTF-8. Я рекомендую указывать кодировку при чтении файла и ту же кодировку при записи в файл. Это может решить вашу проблему.

Харша Комарраджу
источник
7

Пример экспорта в файл с полным путем в Windows, и если ваш файл имеет заголовки :

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

Пример, если вы хотите сохранить в папке в том же каталоге, где находится ваш скрипт, с кодировкой utf-8 и табуляцией в качестве разделителя :

df.to_csv(r'./export/dftocsv.csv', sep='\t', encoding='utf-8', header='true')
Харви
источник
7

это может быть не ответом для этого случая, но поскольку у меня было одно и то же сообщение об ошибке, с которым .to_csvя пытался, .toCSV('name.csv')и сообщение об ошибке было другим (" SparseDataFrame' object has no attribute 'toCSV'). Таким образом, проблема была решена путем преобразования фрейма данных в плотный фрейм данных

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Юрий Кошелек
источник
Вы получили ошибку во втором, так как похоже, что вы использовали .toCSVи нет .to_csv. Вы забыли подчеркивание
Кайл C