为pandas交叉表应用颜色渐变时触发IndexError求助
问题:交叉表应用颜色渐变时触发IndexError
我用pd.crosstab(data['EducationField'],data['Department'])成功生成交叉表,但执行pd.crosstab(data['EducationField'],data['Department']).style.bar(color=['gold'])时触发IndexError,完整报错信息如下:
IndexError Traceback (most recent call last) File D:\COMMON SOFTWARE\lib\site-packages\IPython\core\formatters.py:342, in BaseFormatter.__call__(self, obj) 340 method = get_real_method(obj, self.print_method) 341 if method is not None: ---> 342 return method() 343 return None 344 else: File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:385, in Styler._repr_html_(self) 380 """ 381 Hooks into Jupyter notebook rich display system, which calls _repr_html_ by 382 default if an object is returned at the end of a cell. 383 """ 384 if get_option("styler.render.repr") == "html": ---> 385 return self.to_html() 386 return None File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:1377, in Styler.to_html(self, buf, table_uuid, table_attributes, sparse_index, sparse_columns, bold_headers, caption, max_rows, max_columns, encoding, doctype_html, exclude_styles, **kwargs) 1374 obj.set_caption(caption) 1376 # Build HTML string.. -> 1377 html = obj._render_html( 1378 sparse_index=sparse_index, 1379 sparse_columns=sparse_columns, 1380 max_rows=max_rows, 1381 max_cols=max_columns, 1382 exclude_styles=exclude_styles, 1383 encoding=encoding or get_option("styler.render.encoding"), 1384 doctype_html=doctype_html, 1385 **kwargs, 1386 ) 1388 return save_to_buffer( 1389 html, buf=buf, encoding=(encoding if buf is not None else None) 1390 ) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style_render.py:206, in StylerRenderer._render_html(self, sparse_index, sparse_columns, max_rows, max_cols, **kwargs) 194 def _render_html( 195 self, 196 sparse_index: bool, (...) 200 **kwargs, 201 ) -> str: 202 """ 203 Renders the ``Styler`` including all applied styles to HTML. 204 Generates a dict with necessary kwargs passed to jinja2 template. 205 """ -> 206 d = self._render(sparse_index, sparse_columns, max_rows, max_cols, " ") 207 d.update(kwargs) 208 return self.template_html.render( 209 **d, 210 html_table_tpl=self.template_html_table, 211 html_style_tpl=self.template_html_style, 212 ) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style_render.py:163, in StylerRenderer._render(self, sparse_index, sparse_columns, max_rows, max_cols, blank) 149 def _render( 150 self, 151 sparse_index: bool, (...) 155 blank: str = "", 156 ): 157 """ 158 Computes and applies styles and then generates the general render dicts. 159 160 Also extends the `ctx` and `ctx_index` attributes with those of concatenated 161 stylers for use within `_translate_latex` 162 """ -> 163 self._compute() 164 dxs = [] 165 ctx_len = len(self.index) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style_render.py:258, in StylerRenderer._compute(self) 256 r = self 257 for func, args, kwargs in self._todo: -> 258 r = func(self)(*args, **kwargs) 259 return r File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:1736, in Styler._apply(self, func, axis, subset, **kwargs) 1734 axis = self.data._get_axis_number(axis) 1735 if axis == 0: -> 1736 result = data.apply(func, axis=0, **kwargs) 1737 else: 1738 result = data.T.apply(func, axis=0, **kwargs).T # see GH 42005 File D:\COMMON SOFTWARE\lib\site-packages\pandas\core\frame.py:9568, in DataFrame.apply(self, func, axis, raw, result_type, args, **kwargs) 9557 from pandas.core.apply import frame_apply 9559 op = frame_apply( 9560 self, 9561 func=func, (...) 9566 kwargs=kwargs, 9567 ) -> 9568 return op.apply().__finalize__(self, method="apply") File D:\COMMON SOFTWARE\lib\site-packages\pandas\core\apply.py:764, in FrameApply.apply(self) 761 elif self.raw: 762 return self.apply_raw() -> 764 return self.apply_standard() File D:\COMMON SOFTWARE\lib\site-packages\pandas\core\apply.py:891, in FrameApply.apply_standard(self) 890 def apply_standard(self): -> 891 results, res_index = self.apply_series_generator() 893 # wrap results 894 return self.wrap_results(results, res_index) File D:\COMMON SOFTWARE\lib\site-packages\pandas\core\apply.py:907, in FrameApply.apply_series_generator(self) 904 with option_context("mode.chained_assignment", None): 905 for i, v in enumerate(series_gen): 906 # ignore SettingWithCopy here in case the user mutates -> 907 results[i] = self.f(v) 908 if isinstance(results[i], ABCSeries): 909 # If we have a view on v, we need to make a copy because 910 # series_generator will swap out the underlying data 911 results[i] = results[i].copy(deep=False) File D:\COMMON SOFTWARE\lib\site-packages\pandas\core\apply.py:142, in Apply.__init__.<locals>.f(x) 141 def f(x): -> 142 return func(x, *args, **kwargs) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:4237, in _bar(data, align, colors, cmap, width, height, vmin, vmax, base_css) 4235 assert isinstance(align, str) # mypy: should now be in [left, right, mid, zero] 4236 if data.ndim == 1: -> 4237 return [ 4238 css_calc( 4239 x - z, left - z, right - z, align, colors if rgbas is None else rgbas[i] 4240 ) 4241 for i, x in enumerate(values) 4242 ] 4243 else: 4244 return np.array( 4245 [ 4246 [ (...) 4257 ] 4258 ) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:4238, in <listcomp>(.0) 4235 assert isinstance(align, str) # mypy: should now be in [left, right, mid, zero] 4236 if data.ndim == 1: 4237 return [ -> 4238 css_calc( 4239 x - z, left - z, right - z, align, colors if rgbas is None else rgbas[i] 4240 ) 4241 for i, x in enumerate(values) 4242 ] 4243 else: 4244 return np.array( 4245 [ 4246 [ (...) 4257 ] 4258 ) File D:\COMMON SOFTWARE\lib\site-packages\pandas\io\formats\style.py:4154, in _bar.<locals>.css_calc(x, left, right, align, color) 4151 return base_css 4153 if isinstance(color, (list, tuple)): -> 4154 color = color[0] if x < 0 else color[1] 4155 assert isinstance(color, str) # mypy redefinition 4157 x = left if x < left else x IndexError: list index out of range <pandas.io.formats.style.Styler at 0x1c63635ffd0>
报错原因
style.bar的color参数若传入列表,pandas默认会将列表第一个元素对应负值颜色,第二个对应正值颜色。但交叉表数据全为非负数,且你只传了一个颜色值的列表,代码尝试访问color[1]时触发索引越界。
解决方案
方法1:传入单个颜色字符串
如果只需要单一颜色的条形,直接传字符串(无需列表):
pd.crosstab(data['EducationField'],data['Department']).style.bar(color='gold')
方法2:传入双元素颜色列表
坚持用列表格式的话,需传入两个颜色值(即使无负值):
pd.crosstab(data['EducationField'],data['Department']).style.bar(color=['gold', 'gold'])
方法3:用cmap实现渐变效果
想要真正的颜色渐变,用cmap指定颜色映射:
pd.crosstab(data['EducationField'],data['Department']).style.bar(cmap='YlOrBr')
内容的提问来源于stack exchange,提问作者Bhargavi
相关产品推荐
相关产品推荐

