Pandas:编写一个包含所有列的数据透视表以表现出色

Posted

技术标签:

【中文标题】Pandas:编写一个包含所有列的数据透视表以表现出色【英文标题】:Pandas: writing a Pivot Table with all its columns to excel 【发布时间】:2017-09-24 09:01:58 【问题描述】:

我想将 pandas 中的数据透视表写入 Excel 工作表,但我丢失了一个单元格级别的信息,并且在浏览网页时找不到解决方案。

这是我在由 DataFrame 制成的数据透视表中得到的:

T-Class     <00.5   <01.0
ZIP         
0   1375.0  762.0
1   2177.0  913.0

当我将它写入 excel 时,我丢失了单元格“T-Class”及其对应的“ZIP”空行,这就是我使用 xlsx 编写器得到的结果:

ZIP <00.5   <01.0
0   1375    762
1   2177    913

写入excel的示例代码:

writer = pd.ExcelWriter('data.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='pivottable',header = True,index=True)
writer.save()

如何解决这个问题?

【问题讨论】:

T-Classcolumns 对象的名称。 to_excel 不会费心写出 columns 对象的名称。如果你想要这种确切的格式,你需要做一些自定义的写作。完全可行,但通过to_excel 选项不容易实现。 您能否提供示例代码或提示如何执行此确切格式? 【参考方案1】:

现在我回到了 pandas 数据帧数据透视表的导出主题,我找到了一个更好的导出库。打开pyxl!使用 openpyxl 可以打开预定义的 excel 模板,将数据帧数据写入预定义的漂亮表头下方,这样就不需要处理不必要的 xlsxwriter 错误。这是openpyxl中的示例代码:

import openpyxl
from openpyxl import load_workbook
workbook.active = 0
worksheet = workbook.active
worksheet.title = 'XYZ'
#check length of df
depth_df_2 = len(merged_plz_all)
#call special method to comfortably write the dataframe below your
#predefined header
update_range(workbook.active,merged_plz_all,cell_range =
'A18:'+str(spaltenindex[len(merged_plz_all.columns)])+str(depth_df_2+17))
workbook.save('yourNicelyLookingPivotTable.xlsx')

这是我在另一个 *** 线程中找到的必需的 update_range 方法。不幸的是,我没有为它添加书签,所以我请求原谅我没有提供 update_range 方法的来源。我个人觉得这个方法应该是库 openpyxl 本身的一部分!

def update_range(worksheet, data, cell_range=None, named_range=None):
"""
Updates an excel worksheet with the given data.
:param worksheet: an excel worksheet
:param data: data used to update the worksheet cell range (list, tuple, np.ndarray, pd.Dataframe)
:param cell_range: a string representing the cell range, e.g. 'AB12:XX23'
:param named_range: a string representing an excel named range
"""

def clean_data(data):
    if not isinstance(data, (list, tuple, np.ndarray, pd.DataFrame)):
        raise TypeError('Invalid data, data should be an array type iterable.')

    if not len(data):
        raise ValueError('You need to provide data to update the cells')

    if isinstance(data, pd.DataFrame):
        data = data.values

    elif isinstance(data, (list, tuple)):
        data = np.array(data)

    return np.hstack(data)

def clean_cells(worksheet, cell_range, named_range):
    # check that we can access a cell range
    if not any((cell_range, named_range) or all((cell_range, named_range))):
        raise ValueError('`cell_range` or `named_range` should be provided.')

    # get the cell range
    if cell_range:
        try:
            cells = np.hstack(worksheet[cell_range])
        except (CellCoordinatesException, AttributeError):
            raise ValueError('The cell range provided is invalid, cell range must be in the form XX--[:YY--]')

    else:
        try:
            cells = worksheet.get_named_range(named_range)
        except (TypeError):
            raise ValueError('The current worksheet  does not contain any named range .'.format(
                worksheet.title,
                named_range))

    # checking that we have cells to update, and data
    if not len(cells):
        raise ValueError('You need to provide cells to update.')

    return cells

cells = clean_cells(worksheet, cell_range, named_range)
data = clean_data(data)

# check that the data has the same dimension as cells
if len(cells) != data.size:
    raise ValueError('Cells() should have the same dimension as the data().'.format(len(cells), data.size))

for i, cell in enumerate(cells):
    cell.value = data[i]

【讨论】:

虽然它看起来是一个很好的答案,但它是对一个完全不同的问题的答案。这不是 op 要求的。

以上是关于Pandas:编写一个包含所有列的数据透视表以表现出色的主要内容,如果未能解决你的问题,请参考以下文章

Pandas:如何在数据透视表数据框中仅添加最新日期

为熊猫数据透视表中的每个值列定义 aggfunc

pandas筛选dataframe数据中指定数据列的内容包含在指定列表中的所有数据列

pandas筛选dataframe数据中指定数据列的内容包含在指定列表中的所有数据列

Pandas - 计算所有列的 z 分数

pandas编写自定义函数将同一行指定列的数据相加使用apply函数调用自定义函数把所有行指定的数据进行相加