#python #python-3.x #regex #loops #csv
#python #python-3.x #регулярное выражение #циклы #csv
Вопрос:
Введение
Поскольку я работал со scrapy последние два месяца, я сделал перерыв и начал изучать форматирование текста с помощью python. Я получил некоторые данные, доставленные моим webcrawler, которые хранятся в файле .CSV, как вы можете видеть ниже:
Мой CSV-файл .CSV
SKU
"
Article nr. : 560821800 / D26 x H10 cm
"
"
Article nr. : 560828100 / D14 x H11 cm
"
"
Article nr. : 560821400 / D13 x H10 cm
"
"
Article nr. : 560821900 / L17 x W17 x H14
"
"
Article nr. : 560828900 / L17 x W17 x H14
"
"
Article nr. : 560821600 / D16 x H13 cm
"
"
Article nr. : 560828300 / D16 x H13 cm
"
"
Article nr. : 560827900 / D13 x H10 cm
"
"
Article nr. : 560829000 / L17 x W17 x H14
"
Есть так много пробелов и других вещей, которые я не хочу иметь, поэтому я прочитал о «RegularExpression».
Теперь я немного поиграл, и мне удалось удалить все пробелы и другие ненужные цифры, поэтому у меня есть только f.e 560821800
, который обозначает идентификаторы определенных продуктов.
Теперь я открыл файл .csv, отредактировал значения и попытался записать его в новый файл .csv, который я назвал output .
«Выходной» файл содержит только один столбец, который я хотел назвать «SKU».
Код
import csv
import re
with open(r'C:Usersy.yOneDrive - company namePython3_Textformatierungsku.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in csv_reader:
sku = row.pop()
sku = re.sub(r'[stn] |(.) |(:)', '', sku)
sku = sku.replace('Articlenr', '')
print(sku)#string splitted to ['560827900', 'D13xH10cm']
string_to_list = sku.split('/')#splits string to list
print(string_to_list)
sku_string = string_to_list.pop(0)
print(sku_string)#only value of sku remains
После запуска этого кода я получил следующий вывод:
SKU
['SKU']
SKU
560821800/D26xH10cm
['560821800', 'D26xH10cm']
560821800
560828100/D14xH11cm
['560828100', 'D14xH11cm']
560828100
560821400/D13xH10cm
['560821400', 'D13xH10cm']
560821400
560821900/L17xW17xH14
['560821900', 'L17xW17xH14']
560821900
560828900/L17xW17xH14
['560828900', 'L17xW17xH14']
560828900
560821600/D16xH13cm
['560821600', 'D16xH13cm']
560821600
560828300/D16xH13cm
['560828300', 'D16xH13cm']
560828300
560827900/D13xH10cm
['560827900', 'D13xH10cm']
560827900
560829000/L17xW17xH14
['560829000', 'L17xW17xH14']
560829000
Моя проблема
Я хочу собрать каждое отдельное значение sku_string
и записать их в output.csv-файл, но в новый файл передается только имя поля.
Я попробовал эту задачу со следующим кодом:
#write data to csv with fieldname['SKU']
with open(r'C:PathtoOutput.csv', 'w') as csv_file:
fieldname = ['SKU']
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldname, delimiter=',')
csv_writer.writeheader()
print(sku_string)
for s in row:
csv_writer.writerow(['SKU', sku_string])
Я также признал, что последний оператор печати, который я использовал (только для тестирования), содержит только одно значение, чего мне не хватает?
Я настоящий новичок, я много читал о циклах здесь, в stackoverflow, но я не мог перенести решения своей проблемы, потому что большинство из них были слишком высокими для моего фактического уровня квалификации
Обновить
Я переработал свой код, но он по-прежнему записывает только последний вывод в файл Output.csv ._.
import csv
import re
with open(r'Pathtosku.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in csv_reader:
row = row.pop()#convert from list to str
row = row.split('/')#convert str to list with 2 elements, splitted by '/'
sku_string = row.pop(0)#string with Articlenr SKU
sku_string = sku_string.split(':')
only_sku = sku_string.pop()
#every string contains only sku now
print(only_sku)
with open(r'C:PathtoOutput.csv', 'w') as csv_file:
fieldname = ['SKU']
writer = csv.DictWriter(csv_file, delimiter=',', fieldnames=fieldname)
writer.writeheader()
for x in only_sku:
writer.writerow({'SKU' : only_sku})
Output.csv
Комментарии:
1. Почему вы используете csvreader? Ваш файл не является csv или, если на то пошло, файлом с разделенными значениями <anything> .
2. @PranavHosangadi Это исходный результат, который предоставил мне мой поисковый робот. Как вы думаете, почему это не файл csv? Как вы думаете, pandas будет лучше, чем csvreader?
3. Это не файл csv, потому что csv обозначает значения, разделенные запятыми, что означает, что он похож на лист Excel, за исключением того, что столбцы разделены запятыми. Файл csv с одним столбцом — это, по сути, обычный файл с одной записью в строке.
4. хорошо, я проверяю это, он взял некоторые значения из моего «реального csv» просто для практики, но я никогда не думал об этом, что это может вызвать мою ошибку, спасибо за это, приятель!
Ответ №1:
Я использовал немного другой подход и изменил ваш .csv
файл на .txt
файл, поскольку, честно говоря, все, что у вас там есть, не похоже на структуру CSV.
Вот что я придумал:
import csv
with open("sample.txt") as f:
lines = f.readlines()
parsed_lines = [l for l in [l.strip() for l in lines] if l != '"' and l != "SKU"]
parsed_lines = [l.replace("Article nr. : ", "").split("/") for l in parsed_lines]
with open("output.csv", "w") as output:
w = csv.writer(output)
w.writerow(["Article nr.", "Dimensions"])
w.writerows(parsed_lines)
Вывод:
Article nr. Dimensions
------------- ---------------
560821800 D26 x H10 cm
560828100 D14 x H11 cm
560821400 D13 x H10 cm
560821900 L17 x W17 x H14
560828900 L17 x W17 x H14
560821600 D16 x H13 cm
560828300 D16 x H13 cm
560827900 D13 x H10 cm
560829000 L17 x W17 x H14
Или в .csv
файле:
Комментарии:
1. эй, бадукер, ваше предложение также сработало для меня 🙂 Мне никогда не приходила в голову мысль, что мой csv сломан. Ваше решение сделано хорошо, но для моего уровня квалификации на данный момент, я думаю, слишком высоко:> ваша биография забавная, теперь мне жаль, что я не могу поставить вам галочку:(
2. @y.y рад, что это сработало. Если это кажется немного подавляющим, взгляните на список понимания Python, это может многое объяснить.
3. мне определенно нужно подробно изучить некоторые функции python. хорошего дня 🙂
Ответ №2:
Новые значения из каждой строки записываются в вашу only_sku
строку внутри for row in csv_reader:
цикла. Если вы хотите получить доступ к этим значениям вне цикла, вам нужно будет где-то их собрать, например, добавив их в список.
Таким образом, ваш цикл чтения становится:
all_sku = []
with open(r'Pathtosku.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in csv_reader:
row = row.pop()#convert from list to str
row = row.split('/')#convert str to list with 2 elements, splitted by '/'
sku_string = row.pop(0)#string with Articlenr SKU
sku_string = sku_string.split(':')
only_sku = sku_string.pop().strip()
#every string contains only sku now
print(only_sku)
all_sku.append(only_sku)
Обратите внимание, как мы добавляем последнее значение, которое мы читаем, в наш список всех используемых значений all_sku.append()
. Мы также хотим удалить начальные и конечные пробелы из наших значений.
И затем вы можете написать в другом цикле следующим образом:
with open(r'C:PathtoOutput.csv', 'w') as csv_file:
fieldname = ['SKU']
writer = csv.DictWriter(csv_file, delimiter=',', fieldnames=fieldname)
writer.writeheader()
for x in all_sku:
writer.writerow({'SKU' : x})
Обратите внимание, что теперь мы перебираем all_sku
и записываем каждый элемент этого списка.
Теперь, если вы хотите, чтобы измерения также были записаны в ваш новый файл csv, вам также нужно будет отслеживать это значение. Вместо создания списка строк, как мы делали ранее, проще создать список dict
строк, к которым мы хотим перейти writer.writerow()
позже. Таким образом, у нас было бы:
all_rows = []
with open(r'Pathtosku.csv', 'r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in csv_reader:
row = row.pop() #convert from list to str
row = row.split('/')#convert str to list with 2 elements, splitted by '/'
sku_string = row[0]
dims_string = row[1].strip()
sku_string = sku_string.split(':')
only_sku = sku_string[1].strip()
all_sku.append({'SKU': only_sku, 'Dimensions': dims_string})
А затем напишите так:
with open(r'C:PathtoOutput.csv', 'w') as csv_file:
fieldname = ['SKU', 'Dimensions']
writer = csv.DictWriter(csv_file, delimiter=',', fieldnames=fieldname)
writer.writeheader()
for row_dict in all_rows:
writer.writerow(row_dict)
Комментарии:
1. я также пытался передать значения в список раньше, но я неправильно записал его в своем цикле. Спасибо за все и добрый день!