基于Excel工作表中的单元格颜色和文本颜色子集数据框

Posted

技术标签:

【中文标题】基于Excel工作表中的单元格颜色和文本颜色子集数据框【英文标题】:Subsetting a dataframe based on cell color and text color in excel sheet 【发布时间】:2019-02-09 06:14:32 【问题描述】:

我有一个超过 1000 列和 300 行的 Excel 表。其中一些单元格具有正常数据,而某些单元格具有红色背景色,而某些单元格具有正常白色背景,但文本是红色的。例如,我的 Excel 表如下所示:

我正在将这个 Excel 表读入 Python(熊猫),以将其用作数据框并对其执行进一步的操作。但是,红色文本和红色单元格需要与普通单元格区别对待。

因此,我想将上表拆分为 3 个表,这样:表一包含所有单元格,但红色背景单元格为空。表 2 只有文本为红色的那些行和列。表 3 只有背景为红色的行和列。

我猜它不能在 Pandas 中完成。我尝试使用 StyleFrame 但失败了。

任何人都可以在这方面提供帮助吗?在这种情况下是否有任何有用的python包?

【问题讨论】:

您可以使用 StyleFrame.read_excel 和参数 use_openpyxl_styles=False 来使用基于单元格样式的 pandas 样式索引,如文档中所建议的:styleframe.readthedocs.io/en/latest/… 我做到了。现在我将完整的数据框读入了一个变量。现在的问题是如何根据格式过滤掉单元格。 【参考方案1】:

这几乎是实现这一目标的方法。它不漂亮,因为 StyleFrame 并不是真正设计用于这种方式的。

读取源 Excel 文件

import numpy as np
from StyleFrame import StyleFrame, utils

sf = StyleFrame.read_excel('test.xlsx', read_style=True, use_openpyxl_styles=False)

1) 除了红色背景的单元格之外的所有单元格都是空的

def empty_red_background_cells(cell):
    if cell.style.bg_color in utils.colors.red, 'FFFF0000':
        cell.value = np.nan
    return cell

sf_1 = StyleFrame(sf.applymap(empty_red_background_cells))    
print(sf_1)
#      C1       C2 C3    C4      C5      C6
# 0    a1      1.0  s   nan  1001.0  1234.0
# 1    a2     12.0  s   nan  1001.0  4322.0
# 2    a3      nan  s   nan  1001.0  4432.0
# 3    a4    232.0  s   nan  1001.0  4432.0
# 4    a5    343.0  s  99.0     nan     nan
# 5    a6      3.0  s  99.0  1001.0  4432.0
# 6    a7     34.0  s  99.0  1001.0  4432.0
# 7    a8      5.0  s   nan  1001.0  4432.0
# 8    a9      6.0  s  99.0  1001.0  4432.0
# 9   a10    565.0  s  99.0     nan  4432.0
# 10  a11   5543.0  s  99.0  1001.0  4432.0
# 11  a12    112.0  s  99.0  1001.0     nan
# 12  a13  34345.0  s  99.0  1001.0  4432.0
# 13  a14      0.0  s  99.0     nan     nan
# 14  a15    453.0  s  99.0  1001.0     nan

2) 只有带有红色文本的单元格

def only_cells_with_red_text(cell):
    return cell if cell.style.font_color in utils.colors.red, 'FFFF0000' else np.nan

sf_2 = StyleFrame(sf.applymap(only_cells_with_red_text).dropna(axis=(0, 1), how='all'))
# passing a tuple to pandas.dropna is deprecated since pandas 0.23.0, but this can be
# avoided by simply calling dropna twice, once with axis=0 and once with axis=1

print(sf_2)
#         C2      C6
# 7     nan   4432.0
# 8     nan   4432.0
# 9    565.0     nan
# 10  5543.0     nan
# 11   112.0     nan

3) 只有红色背景的单元格

def only_cells_with_red_background(cell):
    return cell if cell.style.bg_color in utils.colors.red, 'FFFF0000' else np.nan

sf_3 = StyleFrame(sf.applymap(only_cells_with_red_background).dropna(axis=(0, 1), how='all'))
# passing a tuple to pandas.dropna is deprecated since pandas 0.23.0, but this can be
# avoided by simply calling dropna twice, once with axis=0 and once with axis=1

print(sf_3)
#        C4      C6
# 0    99.0     nan
# 1    99.0     nan
# 2    99.0     nan
# 3    99.0     nan
# 13    nan  4432.0
# 14    nan  4432.0

【讨论】:

虽然在 sf_3 中有一个错误,因为我得到了一个空数据框,其中包含您指定的列名。我设法通过首先提取 sf_2 和 sf_3 以及最后一个 sf_1 来解决这个问题。不知道为什么会这样,因为我们使用不同的数据框名称将数据复制到。 您对代码进行了一些更改,导致它不再正常工作。问题出现在 (1) 中。代码/函数清空下一行,而不是带有红色文本的行。在对具有 1000x2000 列/行的多个文件运行代码并执行 QC 后,我正在确认它。你能在这里提出什么技巧吗? @Hanif (1) 清空红色背景的单元格,而不是红色文本 @Hanif 您可以看到我的答案here 的编辑历史,但我从未编辑过 (1),而且我不明白为什么它会在之后清空该行,尤其是在您验证它之后在较小的表/不同文件上按预期工作。我怀疑区别在于文件而不是代码。如果你仍然面临同样的问题,我认为我们最好在 Github 上继续讨论 Github issue 感谢您的及时反馈。明天我会再次检查代码,如果问题仍然存在,将继续在 Git 上讨论。

以上是关于基于Excel工作表中的单元格颜色和文本颜色子集数据框的主要内容,如果未能解决你的问题,请参考以下文章

自动设置颜色单元格 - 基于 Excel 中其他列中的十六进制颜色代码

基于背景颜色的Excel公式单元格

在 C# 中获取 Excel 单元格背景颜色的问题

Qt 中 QTableView 中如何设置某一单元格文本的颜色值,希望能贴出代码。

Excel - 编程单元格以根据另一个单元格更改颜色

excel如何设置背景颜色