来自两列的特定于颜色的单元格,不带';t匹配,使用python.where(或其他)并导出到excel

来自两列的特定于颜色的单元格,不带';t匹配,使用python.where(或其他)并导出到excel,python,excel,pandas,dataframe,styleframe,Python,Excel,Pandas,Dataframe,Styleframe,我正在寻找两列中颜色不匹配的特定单元格,但希望将其与python pandas一起使用,并使用openpyxl在excel中导出 到目前为止,我的代码是: df = pd.DataFrame({ 'config_dummy1': ["dummytext"] * 100, 'config_size_x': ["textstring"] * 100, 'config_size_y': ["textstring"] * 100, 'config_dummy2': ["d

我正在寻找两列中颜色不匹配的特定单元格,但希望将其与python pandas一起使用,并使用openpyxl在excel中导出

到目前为止,我的代码是:

df = pd.DataFrame({
    'config_dummy1': ["dummytext"] * 100,
    'config_size_x': ["textstring"] * 100,
    'config_size_y': ["textstring"] * 100,
    'config_dummy2': ["dummytext"] * 100
})
df.at[50, 'config_size_x'] = "xandydontmatch"
df.at[99, 'config_size_y'] = "xandydontmatch"
print(df)
df.style.where(
    df['config_size_x'] != df['config_size_y'],
    'color: #ffffff; background-color: #ba3018',
    other=''
).to_excel('styled.xlsx', engine='openpyxl')
我被卡住了,因为它会产生一个错误:

Traceback (most recent call last):
  File "python-match-csv.py", line 205, in <module>
    main2()
  File "python-match-csv.py", line 131, in main2
    ).to_excel('styled.xlsx', engine='openpyxl')
  File "F:\Python36\lib\site-packages\pandas\io\formats\style.py", line 175, in to_excel
    engine=engine)
  File "F:\Python36\lib\site-packages\pandas\io\formats\excel.py", line 652, in write
    freeze_panes=freeze_panes)
  File "F:\Python36\lib\site-packages\pandas\io\excel.py", line 1390, in write_cells
    for cell in cells:
  File "F:\Python36\lib\site-packages\pandas\io\formats\excel.py", line 617, in get_formatted_cells
    self._format_body()):
  File "F:\Python36\lib\site-packages\pandas\io\formats\excel.py", line 529, in _format_regular_rows
    for cell in self._generate_body(coloffset):
  File "F:\Python36\lib\site-packages\pandas\io\formats\excel.py", line 601, in _generate_body
    styles = self.styler._compute().ctx
  File "F:\Python36\lib\site-packages\pandas\io\formats\style.py", line 514, in _compute
    r = func(self)(*args, **kwargs)
  File "F:\Python36\lib\site-packages\pandas\io\formats\style.py", line 604, in _applymap
    result = self.data.loc[subset].applymap(func)
  File "F:\Python36\lib\site-packages\pandas\core\frame.py", line 6072, in applymap
    return self.apply(infer)
  File "F:\Python36\lib\site-packages\pandas\core\frame.py", line 6014, in apply
    return op.get_result()
  File "F:\Python36\lib\site-packages\pandas\core\apply.py", line 318, in get_result
    return super(FrameRowApply, self).get_result()
  File "F:\Python36\lib\site-packages\pandas\core\apply.py", line 142, in get_result
    return self.apply_standard()
  File "F:\Python36\lib\site-packages\pandas\core\apply.py", line 248, in apply_standard
    self.apply_series_generator()
  File "F:\Python36\lib\site-packages\pandas\core\apply.py", line 277, in apply_series_generator
    results[i] = self.f(v)
  File "F:\Python36\lib\site-packages\pandas\core\frame.py", line 6070, in infer
    return lib.map_infer(x.astype(object).values, func)
  File "pandas/_libs/src\inference.pyx", line 1472, in pandas._libs.lib.map_infer
  File "F:\Python36\lib\site-packages\pandas\io\formats\style.py", line 671, in <lambda>
    return self.applymap(lambda val: value if cond(val) else other,
TypeError: ("'Series' object is not callable", 'occurred at index config_dummy1')
回溯(最近一次呼叫最后一次):
文件“python match csv.py”,第205行,在
main 2()
main2中第131行的文件“python match csv.py”
).to_excel('styled.xlsx',engine='openpyxl')
文件“F:\Python36\lib\site packages\pandas\io\formats\style.py”,第175行,在excel中
发动机=发动机)
文件“F:\Python36\lib\site packages\pandas\io\formats\excel.py”,第652行,写入
冻结窗格=冻结窗格)
文件“F:\Python36\lib\site packages\pandas\io\excel.py”,第1390行,位于写单元中
对于单元中的单元:
文件“F:\Python36\lib\site packages\pandas\io\formats\excel.py”,第617行,在get\u formatted\u单元格中
self.\格式\正文()):
文件“F:\Python36\lib\site packages\pandas\io\formats\excel.py”,第529行,格式为常规行
对于自生成体中的单元格(coloffset):
文件“F:\Python36\lib\site packages\pandas\io\formats\excel.py”,第601行,在\u generate\u正文中
styles=self.styler.\u compute().ctx
文件“F:\Python36\lib\site packages\pandas\io\formats\style.py”,第514行,在\u compute中
r=func(self)(*args,**kwargs)
文件“F:\Python36\lib\site packages\pandas\io\formats\style.py”,第604行,在\u applymap中
结果=self.data.loc[subset].applymap(func)
applymap中的文件“F:\Python36\lib\site packages\pandas\core\frame.py”,第6072行
返回自我。应用(推断)
文件“F:\Python36\lib\site packages\pandas\core\frame.py”,第6014行,在apply中
返回操作获取结果()
文件“F:\Python36\lib\site packages\pandas\core\apply.py”,第318行,在get\U结果中
返回super(FrameRowApply,self).get_result()
文件“F:\Python36\lib\site packages\pandas\core\apply.py”,第142行,在get\U结果中
返回self.apply_标准()
文件“F:\Python36\lib\site packages\pandas\core\apply.py”,第248行,在apply\u标准中
自应用_系列_生成器()
文件“F:\Python36\lib\site packages\pandas\core\apply.py”,第277行,在apply\u series\u生成器中
结果[i]=self.f(v)
文件“F:\Python36\lib\site packages\pandas\core\frame.py”,第6070行,在Infre中
返回lib.map\u推断(x.astype(object).values,func)
文件“pandas/_libs/src\expression.pyx”,第1472行,在pandas._libs.lib.map\u expert中
文件“F:\Python36\lib\site packages\pandas\io\formats\style.py”,第671行,在
返回self.applymap(lambda val:cond(val)else other时的值,
TypeError:(“'Series'对象不可调用”,“在索引配置_dummy1'处发生”)
TypeError:(“'Series'对象不可调用”,“在索引配置_dummy1处发生”

我愿意接受除.where()之外的其他建议,我也尝试使用.apply()执行此操作,但失败了

注意:列索引位置不是固定的,它可以是
config\u size\u x、config\u dummy1、config\u dummy2、config\u size\u y
或任何其他组合


注2:使用windows和python 3.6(如果有必要)

可以使用
apply
创建样式的数据框架:

def color(x):
    c1 = 'color: #ffffff; background-color: #ba3018'
    m = x['config_size_x'] != x['config_size_y']
    df1 = pd.DataFrame('', index=x.index, columns=x.columns)
    df1.loc[m, ['config_size_x', 'config_size_y']] = c1
    return df1

df.style.apply(color, axis=None)
一般解决方案:

df = pd.DataFrame({
    'config_dummy1': ["dummytext"] * 10,
    'a_y': ["a"] * 10,
    'config_size_x': ["textstring"] * 10,
    'config_size_y': ["textstring"] * 10,
    'config_dummy2': ["dummytext"] * 10,
    'a_x': ["a"] * 10
})
df.at[5, 'config_size_x'] = "xandydontmatch"
df.at[9, 'config_size_y'] = "xandydontmatch"
df.at[0, 'a_x'] = "xandydontmatch"
df.at[3, 'a_y'] = "xandydontmatch"
print(df)

def color(x):
    c1 = 'color: #ffffff; background-color: #ba3018'
    df1 = pd.DataFrame('', index=x.index, columns=x.columns)

    #select only columns ends with _x and _y and sorting
    cols = sorted(x.filter(regex='_x$|_y$').columns)
    #loop by pairs and assign style by mask
    for i, j in zip(cols[::2],cols[1::2]):
        #pairs columns 
        #print (i, j)
        m = x[i] != x[j]
        df1.loc[m, [i, j]] = c1
    return df1

df.style.apply(color, axis=None).to_excel('styled.xlsx', engine='openpyxl')

由于此问题用
样式框标记

from StyleFrame import StyleFrame, Styler

df = pd.DataFrame({'a': [1, 2], 'b': [1, 3]})

sf = StyleFrame(df)
sf.apply_style_by_indexes(sf[sf['a'] != sf['b']], styler_obj=Styler(bg_color='red'))
sf.to_excel('test.xlsx').save()
将产生

如果只想为不匹配行的子集着色,只需使用
cols_to_样式
param:

sf.apply_style_by_indexes(sf[sf['a'] != sf['b']], styler_obj=Styler(bg_color='red'),
                          cols_to_style=['a', 'b'])

列索引位置不是固定的,它可以是config_size_x、config_dummy1、config_dummy2、config_size_y或任何其他组合
-因此需要将
config_dummy1
config_dummy2
进行比较,并且每对都类似?数据框总是包含列对?数据框包含很多列(大约50-60列)每次都不在同一索引位置的config_COLNAME_y和config_COLNAME_x。config_size_x和config_size_y是其中之一,但如果我做对了,我可以从那里开始构建我的方法。是的,它们总是成对的谢谢你的快速回复,我看到了apply()方法,但不幸的是它给整行着色。有没有办法只给config_size_x和config_size_y的特定单元格着色?是的,它们最终被排序了。我钦佩你的热情!:)@SavvasRadevic-刚刚添加了非排序输入数据的解决方案,请检查:)谢谢!我对NaN值有一个小问题,因为某些原因,它们被着色了(我可能是在用NaN检查空的“”字符串)<代码>df.fillna(“”)做到了,一切都很好!速度是需要提高的,437行和90列大约需要40秒(而应用样式之前需要几秒)。但据我所知,数据帧中的
apply()
存在一个问题。我会玩它,看看能不能改进它DI也用
df.index=pd.RangeIndex(len(df.index))
修复了索引,现在它需要20秒,这至少对我来说是可以忍受的。我愿意接受任何解决方案建议:)我忘了提到我也尝试过样式框,也没有给特定的单元格着色D不幸的是,你的回答把整排都涂上了颜色。有没有办法只对config_size_x和config_size_y的特定单元格着色?@SavvasRadevic是的,非常容易。见我的最新答案这个答案也是有效的!非常感谢你!我的索引有一个问题,它抱怨
索引器:单位置索引器在cols\u-to\u样式上是出界的。我在styleframe之前使用
df.index=pd.RangeIndex(len(df.index))
解决了这个问题。另外,它需要的时间与另一个答案差不多(在列对上有一个foreach循环)。