Создать DataFrame из csv файлов с разной кодировкой, указанной в первой строке файла
Есть 1000 csv файлов. Они все с разными кодировками. Хочу сделать из них один DataFrame, но получаю ошибку
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x84 in position 37: invalid start byte
csv файл устроен таким образом
то есть в первой строке указана кодировка, но непонятно как её передать pandas что бы он корректно считывал данные.
Пробовал так, но не работает
import pandas as pd
from pathlib import Path
data_dir = Path("data/")
df = pd.concat([pd.read_csv(f) for f in data_dir.glob("*.csv")])
print(df)
На выходе нужно получить файл csv со столбцами entity, value, string. Эти данные надо брать из этих 1000 файлов(разделитель запятая).
Ответы (1 шт):
Просто делайте не однострочником, а старым добрым циклом for. В цикле считываете первую строку файла, потом передаете ее как кодировку в read_csv. Все собирайте в список. После цикла уже делайте pd.concat.
import pandas as pd
from pathlib import Path
data_dir = Path("data/")
result = []
for f in data_dir.glob("*.csv"):
print("File:", f)
with open(f, "rb") as file:
# В перовой строке файла убираем пробельные символы,
# берем текст после символа "="
encoding = file.readline().decode().strip().partition("=")[2]
print("Encoding:", encoding)
# skiprows=1 - пропускаем первую строку файла, она не должна попадать в данные
# encoding_errors="replace" - при ошибках кодировки (не удалось декодировать указанной кодировкой) заменять символы на "?"
# header=None - указываем, что в файле нет строки с заголовками колонок
# on_bad_lines="warn" - выводим предупреждение, например, если в какой-то строке 4 колонки вместо 3 (а не падаем с исключением)
result.append(pd.read_csv(f, skiprows=1, encoding=encoding, on_bad_lines="warn", encoding_errors="replace", header=None))
df = pd.concat(result)
print(df)
Upd.: Полная строка для чтения csv такая:
result.append(pd.read_csv(f, skiprows=1, encoding=encoding, encoding_errors="replace", header=None, names=list("12345")))
Добавил имена колонок - 1,2,3,4,5, чтобы по умолчанию считало, что колонок 5 (в файле test-684.csv почему-то определяет, что в одной из строк их пять, почему - пока не понял).
