#python #python-3.x #excel #pandas #dataset
Вопрос:
У меня проблема с файлом excel для классификации данных в некоторых столбцах и строках, мне нужно расположить ячейки слияния в следующем столбце в виде 1 строки, а следующий столбец перейти рядом с ними, как на этих рисунках:
Ввод:
Продукция для молочных продуктов:
Краткие сведения:
сначала мы взяли 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) находится не в том месте.