классификация данных excel строка за строкой в столбцах n уровней

#python #python-3.x #excel #pandas #dataset

Вопрос:

У меня проблема с файлом excel для классификации данных в некоторых столбцах и строках, мне нужно расположить ячейки слияния в следующем столбце в виде 1 строки, а следующий столбец перейти рядом с ними, как на этих рисунках:

Ввод:

пример ввода в excel

Продукция для молочных продуктов:

вывод примера excel

Краткие сведения:

сначала мы взяли Dairy строку, затем мы переходим ко второму столбцу перед Dairy и получаем данные перед Dairy , затем мы переходим ко второму столбцу и перед Milk to Mr. 1 нами получаем Butter to Mrs. 1 и Butter to Mrs. 2 и так далее …

После этого мы хотим экспортировать его в файл Excel, как на картинке.

Я написал код, который получает данные первого столбца и находит все данные перед ним, но мне нужно изменить его, чтобы получить данные строка за строкой, как на выходном изображении:

 import pandas
import openpyxl
import xlwt
from xlwt import Workbook

df = pandas.read_excel('excel.xlsx')

result_first_level = []

for i, item in enumerate(df[df.columns[0]].values, 2):
    if pandas.isna(item):
        result_first_level[-1]['index'] = i
    else:
        result_first_level.append(dict(name=item, index=i, levels_name=[]))

for level in df.columns[1:]:
    move_index = 0
    for i, obj in enumerate(result_first_level):
        if i == 0:
            for item in df[level].values[0:obj['index'] - 1]:
                if pandas.isna(item):
                    move_index  = 1
                    continue
                else:
                    obj['levels_name'].append(item)
                move_index  = 1
        else:
            for item in df[level].values[move_index:obj['index'] - 1]:
                if pandas.isna(item):
                    move_index  = 1
                    continue
                else:
                    obj['levels_name'].append(item)
                move_index  = 1

# Workbook is created
wb = Workbook()

# add_sheet is used to create sheet.
sheet1 = wb.add_sheet('Sheet 1')
style = xlwt.easyxf('font: bold 1')

move_index = 0
for item in result_first_level:
    for member in item['levels_name']:
        sheet1.write(move_index, 0, item['name'], style)
        sheet1.write(move_index, 1, member)
        move_index  = 1

wb.save('test.xls')

 

загрузите входной файл excel отсюда

Спасибо за помощь!

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

1. Проверьте библиотеку xlwings и, если это может быть вам полезно, импортируйте данные в виде фрейма данных pandas, docs.xlwings.org/en/stable/datastructures.html

2. @LorenzoBassetti Я получаю фрейм данных pandas в начале, но у меня проблема с упорядочением данных в 2 столбца

3. Возможно, было бы полезно повторить «Дневник» для A1-A12… а затем «Фриц» с A13 по A18 и т. Д., Таким образом, вы могли бы просто прочитать строку. Объединенные ячейки, которые вы используете, в основном являются просто «визуальным» трюком Excel, но значение A1 — «Дневник» , а значение A2… A12 является «нулевым». Я бы посоветовал не использовать объединенные ячейки.

4. @LorenzoBassetti Базовые данные-это объединенные ячейки, с которыми я ничего не могу поделать, поэтому не могли бы вы добавить ответ и добавить код, чтобы я мог лучше вас понять?

5. Пожалуйста, не могли бы вы поделиться своим образцом файла excel? Используйте networkx для решения этой проблемы.

Ответ №1:

Сначала заполните данные, чтобы заполнить пустые ячейки последним допустимым значением, которое используется для создания упорядоченной коллекции pd.CategoricalDtype для сортировки product столбца. Наконец, вам нужно просто попарно перебирать столбцы и переименовывать столбцы, чтобы разрешить объединение. Последний шаг-отсортировать строки по product значению.

 import pandas as pd

# Prepare your dataframe
df = pd.read_excel('input.xlsx').dropna(how='all')
df.update(df.iloc[:, :-1].ffill())
df = df.drop_duplicates()

# Get keys to sort data in the final output
cats = pd.CategoricalDtype(df.T.melt()['value'].dropna().unique(), ordered=True)

# Group pairwise values
data = []
for cols in zip(df.columns, df.columns[1:]):
    col_mapping = dict(zip(cols, ['product', 'subproduct']))
    data.append(df[list(cols)].rename(columns=col_mapping))

# Merge all data
out = pd.concat(data).drop_duplicates().dropna() 
        .astype(cats).sort_values('product').reset_index(drop=True)
 

Выход:

 >>> cats
CategoricalDtype(categories=['Dairy', 'Milk to Mr.1', 'Butter to Mrs.1',
                  'Butter to Mrs.2', 'Cheese to Miss 2 ', 'Cheese to Mr.2',
                  'Milk to Miss.1', 'Milk to Mr.5', 'yoghurt to Mr.3',
                  'Milk to Mr.6', 'Fruits', 'Apples to Mr.6',
                  'Limes to Miss 5', 'Oranges to Mr.7', 'Plumbs to Miss 5',
                  'apple for mr 2', 'Foods amp; Drinks', 'Chips to Mr1',
                  'Jam to Mr 2.', 'Coca to Mr 5', 'Cookies to Mr1.',
                  'Coca to Mr 7', 'Coca to Mr 6', 'Juice to Miss 1',
                  'Jam to Mr 3.', 'Ice cream to Miss 3.', 'Honey to Mr 5',
                  'Cake to Mrs. 2', 'Honey to Miss 2',
                  'Chewing gum to Miss 7.'], ordered=True)

>>> out
             product              subproduct
0              Dairy            Milk to Mr.1
1              Dairy          Cheese to Mr.2
2       Milk to Mr.1         Butter to Mrs.1
3       Milk to Mr.1         Butter to Mrs.2
4    Butter to Mrs.2       Cheese to Miss 2 
5     Cheese to Mr.2          Milk to Miss.1
6     Cheese to Mr.2         yoghurt to Mr.3
7     Milk to Miss.1            Milk to Mr.5
8    yoghurt to Mr.3            Milk to Mr.6
9             Fruits          Apples to Mr.6
10            Fruits         Oranges to Mr.7
11    Apples to Mr.6         Limes to Miss 5
12   Oranges to Mr.7        Plumbs to Miss 5
13  Plumbs to Miss 5          apple for mr 2
14    Foods amp; Drinks            Chips to Mr1
15    Foods amp; Drinks         Juice to Miss 1
16    Foods amp; Drinks          Cake to Mrs. 2
17      Chips to Mr1            Jam to Mr 2.
18      Chips to Mr1         Cookies to Mr1.
19      Jam to Mr 2.            Coca to Mr 5
20   Cookies to Mr1.            Coca to Mr 6
21   Cookies to Mr1.            Coca to Mr 7
22   Juice to Miss 1           Honey to Mr 5
23   Juice to Miss 1            Jam to Mr 3.
24      Jam to Mr 3.    Ice cream to Miss 3.
25    Cake to Mrs. 2  Chewing gum to Miss 7.
26    Cake to Mrs. 2         Honey to Miss 2
 

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

1. @Масуд. Камяб, я надеюсь, что это решит вашу проблему, и мое объяснение будет достаточно ясным.

2. Спасибо, но это раздавливание в середине данных, таких как строка 8, неверно, я мало что знаю о пандах, поэтому, если вы сможете исправить эту ошибку, и я приму ваш ответ

3. Я обновил свой ответ, но я не могу получить правильный порядок вашего фрейма данных. Это похоже на дерево DFS (Глубина первого поиска), но не потому, что ваша вторая строка (Молочные продукты, Сыр для мистера 2) находится не в том месте.