Сортировка столбцов с помощью pandas / xslxwriter после добавления формул - PullRequest
1 голос
/ 05 октября 2019

У меня есть мой фрейм данных с несколькими столбцами, который на самом деле не имеет отношения к этой проблеме, но я хотел отсортировать свои столбцы в определенном порядке.

Теперь проблема в том, что у меня есть набор формул, которые относятся ктаблицы Excel (которые я создаю с помощью xslxwriter worksheet.add_table), например:

planned_units = '=Table1[@[Spend]]/Table1[@[CP]]'

Так что, если я добавлю эти формулы, просто добавив столбец в pandas:

df['newformula'] = planned_units

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

  • Я добавляю формулы позже (после создания таблицы), но я также хочу отсортировать столбцы, которые я только что добавил
  • если я добавляю формулы, ссылающиеся на таблицу Excel перед add_table, то эти формулы не будут работать в excel

Похоже, что xslxwriter не позволяет мне сортировать столбцы каким-либо образом (может быть, янеправильно?), поэтому я не вижу возможности сортировки столбцов после того, как у меня есть окончательный «продукт» (после добавления всех столбцов с формулами).

Все же лучше иметь рабочие формулы вместо отсортированных столбцов, ноЯ с радостью приветствую любые идеи о том, как их отсортировать на этом этапе.

спасибо!

PS Пример кода:

import pandas as pd
import xlsxwriter


# simple dataframe with 3 columns

input_df = pd.DataFrame({'column_a': ['x', 'y', 'z'],
                         'column_b': ['red', 'white', 'blue'],
                         'column_c': ['a', 'e', 'i'],
                         })

output_file = 'output.xlsx'

# formula I want to add
column_concatenation = '=CONCATENATE(Table1[@[column_a]], " ", Table1[@[column_b]])'

# now if adding formulas with pandas would be possible, I would do it like this:

# input_df['concatenation'] = column_concatenation
# but its not possible since excel gives you errors while opening!

# adding excel table with xlsxwriter:

workbook = xlsxwriter.Workbook(output_file)
worksheet = workbook.add_worksheet("Sheet with formula")

# here I would change column order only IF formulas added with pandas would work! so no-no
'''
desired_column_order = ['columnB', 'concatenation', 'columnC', 'columnA']
input_df = input_df[desired_column_order]
'''
data = input_df

worksheet.add_table('A1:D4', {'data': data.values.tolist(),
                              'columns': [{'header': c} for c in data.columns.tolist()] +
                                         [{'header': 'concatenation',
                                           'formula': column_concatenation}
                                          ],
                              'style': 'Table Style Medium 9'})

workbook.close()

Теперь перед workbook.close () IМне бы очень хотелось использовать эту таблицу «selected_column_order» для изменения порядка столбцов после добавления формул.

спасибо:)

1 Ответ

1 голос
/ 05 октября 2019

Похоже, здесь есть две проблемы: сортировка и формула таблицы.

Сортировка - это то, что Excel выполняет во время выполнения, в приложении Excel, и не является свойством или чем-то, что можетбыть запущенным в формате файла. Поскольку XlsxWriter имеет дело только с форматом файла, он не может выполнять какую-либо сортировку. Однако данные могут быть отсортированы в Python / Pandas до их записи с помощью XlsxWriter.

Проблема с формулой связана с тем, что в Excel был оригинальный синтаксис [#This Row] (Excel 2007) и более поздний * 1006. * синтаксис (Excel 2010+). См. Документы XlsxWriter по Работа с таблицами рабочих таблиц - столбцы :

Структурные ссылки в стиле Excel 2007 [#This Row] и в стиле Excel 2010 @ поддерживаются в формуле. Однако другие добавления Excel 2010 к структурным ссылкам не поддерживаются, и формулы должны соответствовать формулам стиля Excel 2007.

Таким образом, в основном вам необходимо использовать синтаксис Excel 2007, поскольку именно он хранится в формате файла, даже если Excel отображает синтаксис Excel 2010+ извне.

Когда выДобавление формул с помощью метода add_table() XlsxWriter выполняет преобразование за вас, но если вы добавляете формулы другим способом, например с помощью Pandas, вам необходимо использовать синтаксис Excel 2007. Таким образом, вместо формулы, подобной этой:

=CONCATENATE(Table1[@[column_a]], " ", Table1[@[column_b]])

Вам нужно добавить это:

=CONCATENATE(Table1[[#This Row],[column_a]], " ", Table1[[#This Row],[column_b]])

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

Тогда ваша программа будет работать должным образом:

import pandas as pd
import xlsxwriter

input_df = pd.DataFrame({'column_a': ['x', 'y', 'z'],
                         'column_b': ['red', 'white', 'blue'],
                         'column_c': ['a', 'e', 'i'],
                         })

output_file = 'output.xlsx'

column_concatenation = '=CONCATENATE(Table1[[#This Row],[column_a]], " ", Table1[[#This Row],[column_b]])'

input_df['concatenation'] = column_concatenation


workbook = xlsxwriter.Workbook(output_file)
worksheet = workbook.add_worksheet("Sheet with formula")

desired_column_order = ['column_b', 'concatenation', 'column_c', 'column_a']
input_df = input_df[desired_column_order]
data = input_df

# Make the columns wider for clarity.
worksheet.set_column(0, 3, 16)

worksheet.add_table('A1:D4', {'data': data.values.tolist(),
                              'columns': [{'header': c} for c in data.columns.tolist()] +
                                         [{'header': 'concatenation'}],
                              'style': 'Table Style Medium 9'})

workbook.close()

Вывод:

enter image description here

...