Как преобразовать это в фрейм данных и сохранить в формате csv?

#python #pandas #dataframe #data-wrangling

Вопрос:

1

Эти данные ранее были предоставлены в виде .txt файла. Я преобразовал его в .csv формат и попытался отсортировать в нужную форму, но потерпел неудачу. Я пытаюсь найти способы преобразования этой структуры данных (как показано ниже).:

 bakeryA
77300 Baker Street
bun: [10,20,30,10]
donut: [20,10,40,0]
bread: [0,10,15,10]
bakery B
78100 Cerabut St
data not available
bakery C
80300 Sulkeh St
bun: [29,50,20,30]
donut: [10,10,30,10]
bread: [10,15,10,20]
 

в этот фрейм данных:

Имя Адрес Тип соль сахар вода мука
Пекарня А 77300 Бейкер-стрит булочка 10 20 30 10
Пекарня А 77300 Бейкер-стрит пончик 20 10 40 0
Пекарня А 77300 Бейкер-стрит хлеб 0 10 15 10
Пекарня B 78100 ул. Керамут Nan Nan Nan Nan Nan
Пекарня C 80300 ул. Сулке булочка 29 50 20 30
Пекарня C 80300 ул. Сулке пончик 10 10 30 10
Пекарня C 80300 ул. Сулке хлеб 10 15 10 20

Спасибо!

Комментарии:

1. Данные, которые вы предоставили, не являются CSV, так как значения не разделены запятыми…

2. @prnvbn, Извините! файл был открыт в Excel, но сохранен в формате .csv. Я изменил свой вопрос. Спасибо вам за комментарий!

3. Не могли бы вы подробнее остановиться на этой структуре данных? Что это за формат файла?

4. @ДерекО, я обновил свой пост скриншотом данных. Данные ранее были предоставлены в виде txt-файла. Я преобразовал его в формат csv и попытался отсортировать в нужную форму, но потерпел неудачу.

Ответ №1:

Это имеет очень мало общего с пандами и больше с анализом неструктурированного источника в структурированные данные. Попробуй это:

 from ast import literal_eval
from enum import IntEnum

class LineType(IntEnum):
    BakeryName = 1
    Address = 2
    Ingredients = 3

data = []
with open('data.txt') as fp:
    line_type = LineType.BakeryName
    for line in fp:
        line = line.strip()

        if line_type == LineType.BakeryName:
            name = line # the current line contains the Bakery Name
            line_type = LineType.Address # the next line is the Bakery Address
        elif line_type == LineType.Address:
            address = line # the current line contains the Bakery Address
            line_type = LineType.Ingredients # the next line contains the Ingredients
        elif line_type == LineType.Ingredients and line == 'data not available':
            data.append({
                'Name': name,
                'Address': address
            }) # no Ingredients info available
            line_type = LineType.BakeryName # next line is Bakery Name
        elif line_type == LineType.Ingredients:
            # if the line does not follow the ingredient's format, we
            # overstepped into the Bakery Name line. Then the next line
            # is Bakery Address
            try:
                bakery_type, ingredients = line.split(':')
                ingredients = literal_eval(ingredients.strip())
                data.append({
                    'Name': name,
                    'Address': address,
                    'type': bakery_type,
                    'salt': ingredients[0],
                    'sugar': ingredients[1],
                    'water': ingredients[2],
                    'flour': ingredients[3],
                })
            except:
                name = line
                line_type = LineType.Address

df = pd.DataFrame(data)
 

Это предполагает, что ваш файл данных находится в указанном формате. Небольшое отклонение (например, пустые строки) сбросит его.