添加公式后使用 pandas / xlsxwriter 对列进行排序

Sorting columns with pandas / xslxwriter after adding formulas

我的数据框只有几列,这实际上与这个问题无关,但我想按特定顺序对我的列进行排序。

现在,问题是我有一堆引用 excel tables 的公式(我正在使用 xslxwriter worksheet.add_table 创建),例如:

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

因此,如果我通过简单地在 pandas 中添加一列来添加这些公式:

df['newformula'] = planned_units

它不会起作用,我想是因为我在实际添加 table 之前添加了一个引用 table 的公式。所以在添加公式之前对这些列进行排序是行不通的,因为:

似乎 xslxwriter 不允许我以任何方式对列进行排序(也许我错了?)所以在我完成最终 'product' 之后(添加之后)我看不到任何对列进行排序的可能性所有带公式的列)。

使用工作公式而不是排序列更好,但我很乐意欢迎任何关于此时如何对它们进行排序的想法。

谢谢!

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() 之前,我很想在添加公式后使用 table 'desired_column_order' 重新排序我的列。

谢谢:)

这里似乎有两个问题:排序和 table 公式。

排序是 Excel 在运行时在 Excel 应用程序中执行的操作,它不是文件格式的 属性 或可以触发的操作.由于 XlsxWriter 仅处理文件格式,因此无法进行任何排序。但是,在使用 XlsxWriter 写入数据之前,可以在 Python/Pandas 中对数据进行排序。

公式问题是由于 Excel 有一个原始的 [#This Row] 语法(Excel 2007)和后来的 @ 语法(Excel 2010+)。请参阅 Working with Worksheet Tables - Columns:

上的 XlsxWriter 文档

The Excel 2007 style [#This Row] and Excel 2010 style @ structural references are supported within the formula. However, other Excel 2010 additions to structural references aren’t supported and formulas should conform to Excel 2007 style formulas.

所以基本上你需要使用 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()

输出: