Импортировать грязный CSV-файл с нежелательными символами, строками

Я хотел бы импортировать CSV-файлы с пандами. Обычно мои данные задаются в виде:

a,b,c,d
a1,b1,c1,d1
a2,b2,c2,d2

где a,b,c,d — заголовок. Здесь я могу легко использовать pandas.read_csv. Однако теперь у меня есть данные, хранящиеся так:

"a;b;c;d"
"a1;\"b1\";\"c1\";\"d1\""
"a2;\"b2\";\"c2\";\"d2\""

Как я могу очистить это наиболее эффективным способом? Как я могу удалить строку вокруг всей строки, чтобы она могла обнаруживать столбцы? И тогда как удалить все "?

Большое спасибо за любую помощь!!

Я не уверен что делать. введите здесь описание изображения

Что вы сделали, чтобы получить файл в этом формате? Лучше исправить это вверх по течению

mozway 04.04.2023 17:07

@mozway, к сожалению, я не могу. Это старый файл, созданный в прошлом

Anna 04.04.2023 17:09

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

John Bollinger 04.04.2023 17:16

Есть ли какие-либо кавычки (") или экранированные кавычки (\"), которые вам нужно сохранить? Вам нужно изменить разделители с точки с запятой (;) на запятую (,)?

John Bollinger 04.04.2023 17:18

@JohnBollinger нет, я не хочу оставлять экранированные кавычки. Мне не обязательно менять ; чтобы, как я мог бы использовать; как разделитель, я думаю, при использовании pandas.read_csv

Anna 04.04.2023 17:29

Этот вопрос кажется дубликатом: Игнорировать символ при импорте с пандами

Luuk 04.04.2023 17:35
1
6
65
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать sed, чтобы разбить файл на выбранный вами формат.

Для простого примера, соответствующего вашей проблеме, используйте sed:

$ cat file 
"a1a1;"a1a1";"a1a1";"a1a1""
$ cat file | sed 's/"//g'
a1a1;a1a1;a1a1;a1a1

sed 's/"//g' Это заменит все " символы ничем, g в конце говорит sed сделать это для каждого " символа, а не только для первого найденного.

Я вижу, вы отредактировали вопрос, вот обновление нового текстового вывода:

$ cat file
"a1;\"b1\";\"c1\";\"d1\""
"a2;\"b2\";\"c2\";\"d2\""
$ cat file | sed 's/"//g' | sed 's|\\||g' 
a1;b1;c1;d1
a2;b2;c2;d2

Или cat file | sed -e 's/"//g' -e 's|\\||g', не нужно дважды трубить.

Luuk 04.04.2023 17:31

@crabpeople Большое спасибо за быстрый ответ!! Я не совсем уверен, как реализовать ваше предложение. Кроме того, есть ли способ сделать это напрямую в python, а не через терминал? Потому что мне нужно сделать это примерно для 150 наборов данных, и в python я их перебираю.

Anna 04.04.2023 17:33

Последнее потенциально проблематично, поскольку оно удалит обратную косую черту, которая не используется для экранирования кавычек, если таковые имеются.

John Bollinger 04.04.2023 17:33

Вы можете зациклить в bash

juanpa.arrivillaga 04.04.2023 18:27

Когда вам нужно/хотите сделать это на Python:

Просто удалите начальные и конечные кавычки:



file1 = open('abcd.csv',"r")
file2 = open('abcd-new.csv',"w")
lines = file1.readlines()

for line in lines:
    if (line.startswith("\"") and line.endswith("\"")):
         line = line[1:len(line)-1] 
    print(line)
    file2.write(line)
file2.close()

и когда вам также нужно заменить \":



file1 = open('abcd.csv',"r")
file2 = open('abcd-new.csv',"w")
lines = file1.readlines()

for line in lines:
    if (line.startswith("\"") and line.endswith("\"")):
         line = line[1:len(line)-1] 
    line = line.replace("\"","")
    line = line.replace("\\","")
    print(line)
    file2.write(line)
file2.close()

не используйте readlines

juanpa.arrivillaga 04.04.2023 18:09

@juanpa.arrivillaga: Извините, мне не хватает причины не использовать строки чтения 😉

Luuk 04.04.2023 18:10

Просто перебирайте файловый объект напрямую

juanpa.arrivillaga 04.04.2023 18:26
Ответ принят как подходящий

Вот один из вариантов с read_csv (и я уверен, что мы сможем сделать его лучше):

df = (
        pd.read_csv("input.csv", sep=r";|;\\?", engine = "python")
            .pipe(lambda df_: df_.set_axis(df_.columns.str.strip('"'), axis=1))
            .replace(r'[\\"]', "", regex=True)

     )

Выход :

​
print(df)
​
    a   b   c   d
0  a1  b1  c1  d1
1  a2  b2  c2  d2
pipe здесь вроде бы лишнее
juanpa.arrivillaga 04.04.2023 18:27

Я так не думаю. В противном случае вы получите ошибку. Попробуй ;)

Timeless 04.04.2023 18:30

А, понял, пропустил, что ты использовал df_.columns в качестве аргумента для .set_axis

juanpa.arrivillaga 04.04.2023 19:30

Другие вопросы по теме