将属性(不是函数)传递给 python `pandas.DataFrame.style`
Pass Attributes (not functions) to python `pandas.DataFrame.style`
我有一个 pandas.DataFrame
里面有值,比如说:
df = pd.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
In [160]: df
Out[160]:
a b c
0 -0.316527 -0.721590 1.812285
1 -1.704653 -0.415888 -0.294740
2 -1.126637 0.032084 -1.344484
3 0.081789 -1.311954 1.941496
4 0.617405 0.114212 -0.763610
现在 我已经编写了自己的颜色渐变函数 这样我就得到了一个 pd.DataFrame
相同大小和形状,但每个单元格都有颜色十六进制代码, 说:
df_clrs = pd.DataFrame([
['#bc4700', '#dea380', '#bc4700'],
['#384f69', '#dea380', '#bc4700'],
['#dea380', '#bc4700', '#384f69'],
['#384f69', '#384f69', '#dea380'],
['#dea380', '#bc4700', '#384f69']],
columns=['a', 'b', 'c']
)
In [164]: df_clrs
Out[164]:
a b c
0 #bc4700 #dea380 #bc4700
1 #384f69 #dea380 #bc4700
2 #dea380 #bc4700 #384f69
3 #384f69 #384f69 #dea380
4 #dea380 #bc4700 #384f69
假设我也用文本颜色完成了此操作,所以:
df_fnts = pd.DataFrame([
['#f1f1f1','#f1f1f1','#000000'],
['#000000','#f1f1f1','#f1f1f1'],
['#000000','#f1f1f1','#000000'],
['#f1f1f1','#000000','#f1f1f1'],
['#000000','#000000','#f1f1f1']],
columns=['a', 'b' ,'c']
)
In [167]: df_fnts
Out[167]:
a b c
0 #f1f1f1 #f1f1f1 #000000
1 #000000 #f1f1f1 #f1f1f1
2 #000000 #f1f1f1 #000000
3 #f1f1f1 #000000 #f1f1f1
4 #000000 #000000 #f1f1f1
我的目标是公开 DatFrame.style
功能,如 these tutorials 中所示。
然而,教程中演示的所有函数都专注于传递函数(使用 pd.DataFrame.style.applymap
),但是,我已经创建了所有属性。
我尝试过的事情
因为在文档中看起来您需要为该值附加适当的 属性,我创建了一个这样的函数:
def _apply_prop(df, prop):
return df.applymap(lambda x: prop + ':' + x)
# apply the color mapping
df.style.applymap(
_apply_prop(
df_clrs,
'background-color'
)
).to_excel('~/Desktop/background-colors.xlsx')
但是我得到了 TypeError
TypeError: the first argument must be callable
我知道这不是您想要的,但它确实成功地将颜色应用到 df_clrs DataFrame
def apply_prop(val):
return 'color: %s' % val
df_clrs.style.applymap(apply_prop)
applymap 只能将函数作为对象排除。所以您将无法向函数添加参数。
请记住,样式化的想法是根据正在设置样式的数据框中的数据来设置样式。不是另一个 DataFrame。
df
(5x3) 和 df_clrs
(4x3) 有不同的形状。假设您已更正该问题,请尝试以下操作:
def _apply_prop(_, style, prop):
return style.applymap(lambda x: prop + ':' + x)
df.style.apply(_apply_prop, axis=None, style=df_clrs, prop='background-color')
输出:
一些注意事项:
- 不要打电话给
style.applymap
。它遍历 个单元格 。使用 apply(..., axis=...)
遍历列/行/table。无论您迭代什么,return 一个具有相同形状的对象。
- 您没有在
apply / applymap
中执行样式功能。您提供函数的名称及其参数
- 样式函数的第一个参数始终是要设置样式的数据框。
apply / applymap
将数据框隐式传递给样式函数。您可以通过关键字传递额外的参数。
我最终想出了一个不同的解决方案:
- 避免使用
applymap
(我记得应用到所有元素是一个较慢的操作)
- 利用
apply
函数中的 "column name" 来引用样式矩阵的适当列。
def _apply_format(srs, df, prop):
"""
Parameters
----------
srs : :class:`Series`
This is the column that will be passed automatically in the `apply` function
df : :class:`DataFrame`
The matrix of styling attributes with the same shape as the matrix to be styled
prop : str
The property to style, e.g. 'background-color'
"""
nm = srs.name
row = df[nm]
return (prop + ': ' + row).tolist()
现在我可以将背景颜色和字体颜色的样式功能链接在一起,如下所示:
(df.style.
apply(_apply_format, axis=0, subset=subset, **{'df': df_clrs, 'prop': 'background-color'}).
apply(_apply_format, axis=0, subset=subset, **{'df': df_fnts, 'prop': 'color'}).
to_excel('~/Desktop/pretty-table.xlsx', engine='openpyxl')
)
我有一个 pandas.DataFrame
里面有值,比如说:
df = pd.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
In [160]: df
Out[160]:
a b c
0 -0.316527 -0.721590 1.812285
1 -1.704653 -0.415888 -0.294740
2 -1.126637 0.032084 -1.344484
3 0.081789 -1.311954 1.941496
4 0.617405 0.114212 -0.763610
现在 我已经编写了自己的颜色渐变函数 这样我就得到了一个 pd.DataFrame
相同大小和形状,但每个单元格都有颜色十六进制代码, 说:
df_clrs = pd.DataFrame([
['#bc4700', '#dea380', '#bc4700'],
['#384f69', '#dea380', '#bc4700'],
['#dea380', '#bc4700', '#384f69'],
['#384f69', '#384f69', '#dea380'],
['#dea380', '#bc4700', '#384f69']],
columns=['a', 'b', 'c']
)
In [164]: df_clrs
Out[164]:
a b c
0 #bc4700 #dea380 #bc4700
1 #384f69 #dea380 #bc4700
2 #dea380 #bc4700 #384f69
3 #384f69 #384f69 #dea380
4 #dea380 #bc4700 #384f69
假设我也用文本颜色完成了此操作,所以:
df_fnts = pd.DataFrame([
['#f1f1f1','#f1f1f1','#000000'],
['#000000','#f1f1f1','#f1f1f1'],
['#000000','#f1f1f1','#000000'],
['#f1f1f1','#000000','#f1f1f1'],
['#000000','#000000','#f1f1f1']],
columns=['a', 'b' ,'c']
)
In [167]: df_fnts
Out[167]:
a b c
0 #f1f1f1 #f1f1f1 #000000
1 #000000 #f1f1f1 #f1f1f1
2 #000000 #f1f1f1 #000000
3 #f1f1f1 #000000 #f1f1f1
4 #000000 #000000 #f1f1f1
我的目标是公开 DatFrame.style
功能,如 these tutorials 中所示。
然而,教程中演示的所有函数都专注于传递函数(使用 pd.DataFrame.style.applymap
),但是,我已经创建了所有属性。
我尝试过的事情
因为在文档中看起来您需要为该值附加适当的 属性,我创建了一个这样的函数:
def _apply_prop(df, prop):
return df.applymap(lambda x: prop + ':' + x)
# apply the color mapping
df.style.applymap(
_apply_prop(
df_clrs,
'background-color'
)
).to_excel('~/Desktop/background-colors.xlsx')
但是我得到了 TypeError
TypeError: the first argument must be callable
我知道这不是您想要的,但它确实成功地将颜色应用到 df_clrs DataFrame
def apply_prop(val):
return 'color: %s' % val
df_clrs.style.applymap(apply_prop)
applymap 只能将函数作为对象排除。所以您将无法向函数添加参数。
请记住,样式化的想法是根据正在设置样式的数据框中的数据来设置样式。不是另一个 DataFrame。
df
(5x3) 和 df_clrs
(4x3) 有不同的形状。假设您已更正该问题,请尝试以下操作:
def _apply_prop(_, style, prop):
return style.applymap(lambda x: prop + ':' + x)
df.style.apply(_apply_prop, axis=None, style=df_clrs, prop='background-color')
输出:
一些注意事项:
- 不要打电话给
style.applymap
。它遍历 个单元格 。使用apply(..., axis=...)
遍历列/行/table。无论您迭代什么,return 一个具有相同形状的对象。 - 您没有在
apply / applymap
中执行样式功能。您提供函数的名称及其参数 - 样式函数的第一个参数始终是要设置样式的数据框。
apply / applymap
将数据框隐式传递给样式函数。您可以通过关键字传递额外的参数。
我最终想出了一个不同的解决方案:
- 避免使用
applymap
(我记得应用到所有元素是一个较慢的操作) - 利用
apply
函数中的 "column name" 来引用样式矩阵的适当列。
def _apply_format(srs, df, prop):
"""
Parameters
----------
srs : :class:`Series`
This is the column that will be passed automatically in the `apply` function
df : :class:`DataFrame`
The matrix of styling attributes with the same shape as the matrix to be styled
prop : str
The property to style, e.g. 'background-color'
"""
nm = srs.name
row = df[nm]
return (prop + ': ' + row).tolist()
现在我可以将背景颜色和字体颜色的样式功能链接在一起,如下所示:
(df.style.
apply(_apply_format, axis=0, subset=subset, **{'df': df_clrs, 'prop': 'background-color'}).
apply(_apply_format, axis=0, subset=subset, **{'df': df_fnts, 'prop': 'color'}).
to_excel('~/Desktop/pretty-table.xlsx', engine='openpyxl')
)