我的数据框只有很少的列,实际上与这个问题无关,但是我想按特定顺序对列进行排序。
现在,问题是我有很多引用excel表的公式(例如,我正在使用xslxwriter worksheet.add_table创建的公式):
planned_units = '=Table1[@[Spend]]/Table1[@[CP]]'
因此,如果我要通过简单地在pandas中添加一列来添加这些公式:
df['newformula'] = planned_units
这是行不通的,我想是因为我在实际添加表格之前添加了引用表格的公式。因此,在添加公式之前对这些列进行排序将不起作用,因为:]
似乎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()之前,我很乐意使用该表'desired_column_order'在添加公式后对列进行重新排序。
感谢:)
看来这里有两个问题:排序和表公式。
排序是Excel在运行时在Excel应用程序中执行的操作,不是文件格式的属性,也不是文件格式可以触发的内容。由于XlsxWriter仅处理文件格式,因此无法进行任何排序。但是,在使用XlsxWriter编写数据之前,可以在Python / Pandas中对数据进行排序。
公式问题是由于Excel具有原始[#This Row]
语法(Excel 2007)和更高的@
语法(Excel 2010+)。请参阅Working with Worksheet Tables - Columns上的XlsxWriter文档:
Excel 2007样式
[#This Row]
和Excel 2010样式@
结构引用在公式中受支持。但是,不支持其他Excel 2010对结构参考的添加,并且公式应符合Excel 2007样式公式。
因此,基本上,您需要使用Excel 2007语法,因为即使文件在外部显示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()
输出: