crosstab汇总_Python之sidetable - 在pandas中创建简单的汇总表

b3d7e3a4827027676d1be5f592afb83c.png
fd1088e71e8fc66df9724c4d18a2a543.png

介绍

今天,我很高兴地宣布发布一个名为sidetable的新pandas实用程序库。 该库使构建频率表变得容易,并简化了DataFrame中缺失值的简单汇总。 我发现它在开始对新数据集进行数据探索时是一个有用的工具,我希望其他人也发现它也有用。

该项目也是说明如何使用pandas新API注册自定义DataFrame访问器的机会。 此API允许您构建用于处理pandas DataFrames和Series的自定义函数,并且对于构建自己的自定义pandas访问器函数库可能非常有用。

sidetable

sidetable 的核心是带有一些交叉表(crosstab)的pandas的 value_counts的超级版本。例如,让我们看一下“学校改善补助金”的一些数据,以便我们了解sidetable 如何帮助我们探索新的数据集和 找出进行更复杂分析的方法。

唯一的外部依赖关系是 pandas 版本> = 1.0。 确保已安装,然后安装sidetable:

python -m pip install sidetable

一旦安装了sidetable,您需要将其导入以注册pandas访问器。

import pandas as pdimport sidetabledf = pd.read_csv('https://github.com/chris1610/pbpython/blob/master/data/school_transform.csv?raw=True', index_col=0)
31942ec0630d09c0dc31c5be57ce1f5d.png

现在已经导入了sidetable ,您在所有DataFrame上都有一个新的访问器-stb,可用于构建汇总表。 例如,我们可以使用.stb.freq()来构建频率表,以显示各州包括多少所学校,以及其总数和百分比:

df.stb.freq(['State'])
a6a74b0792cd410ef9a6a7c102326f26.png

此示例表明,CA发生了92次,占学校总数的12.15%。 如果将FL包括在内,则您现在共有163所学校,占总数的21.5%。

从0.6版开始,sidetable 可以正确显示百分比。 此处显示的示例是比例而不是百分比。 较新的版本会将结果乘以100-这是表示百分比的正确方法。 sidetable 的最新版本也将小写标题用作列名。 鼓励用户使用最新版本。

我们比较一下,value_counts(normalize = True).stb.freq()

70d6d4c697a7c42b74c286825508ab03.png
ebed938ed4993fde9d1ab21aec4da5ff.png

我想您会同意sidetable 无需花费更多精力即可提供更多数据汇总。

但是,等等,还有更多!

如果我们想快速查看占总数约50%的州怎么办? 使用thresh参数将所有其余部分归为“其他”类别:

df.stb.freq(['State'], thresh=.5)
be19504308edf774247e9c0fae6e3906.png

这很方便。 现在我们可以看到,有8个州几乎贡献了总数的50%,其他所有州则占了剩余的份额。

如果需要,我们可以使用other_label重命名catch-all类别

df.stb.freq(['State'], thresh=.5, other_label='Rest of states')

sidetable 的有用功能之一是可以将列分组在一起以进一步了解分布。 例如,如果我们想看看如何将各种“转换模型”(Transformation Models)应用到整个地区,该怎么办?

df.stb.freq(['Region', 'Model Selected'])
1eabfdb3dd61ee0616c868a9aec3d9d1.png

此视图是了解各种数据元素的交互和分布的快速方法。 我发现这是一种探索数据并获得可能需要进一步分析的见解的简便方法。 这样的表也很容易与他人共享,因为它相对容易理解。

您绝对可以使用标准pandas (毕竟是幕后所有东西)执行此分析。 但是,记住代码很麻烦。 我的经验是,如果很难记住,那么您这样做的可能性就较小。 simpletable试图使这种类型的摘要非常容易实现。

到目前为止,我们一直在计算实例数。 可能更有趣的是按Award Amount查看总细分。 sidetable 允许您传递可以求和的value列(而不是对出现的次数进行计数)。

df.stb.freq(['Region'], value='Award_Amount')
83a04fc19a0c23192b6c600dc3b6a8b0.png

这种观点使我们了解到,东北地区在这些项目上花费的资金最少,而且总支出中的37%用于了南部地区的学校。

最后,我们可以查看所选模型的类型并确定分配的美元的80/20细分:

df.stb.freq(['Region', 'Model Selected'],             value='Award_Amount', thresh=.82,             other_label='Remaining')
18bb358225e09a622a1f77032c62ea11.png

如果您熟悉pandas crosstab,那么查看sidetable的一种方法是,它是crosstab的扩展版本,具有一些方便的功能,可以更轻松地查看数据:

99bde83e1c90b5a7ff3f653ccffa8191.png
c7726bae86a2b9419900fd47dbab3756.png

sidetable的目标之一是其输出易于解释。 如果您想利用 pandas style 熊猫样式的函数来格式化输出以提高可读性,则sidetable可以将Percentage和Amount列格式化为更具可读性。 默认情况下不使用它,但是可以通过将style = True传递给函数来看到:

df.stb.freq(['Region'], value='Award_Amount', style=True)
aab15be84fd5b9d195650b8b3d80ecab.png

到目前为止,我只展示了freq函数,但是为了展示如何向库中添加其他函数,下面是构建简单缺失值表的示例:

df.stb.missing()
0e029be16e2b96b28d9dad5e83dd7c33.png

在此表中,“Region”列中有10个缺失值,占该列总值的1.3%略少。

您可以使用df.info()获得类似的信息,但是在快速识别缺失值时,我发现此表更易于解释:

9bdec5218cad2fbf9bcbe70f8842df36.png

该文档显示了有关用法和其他选项的更多信息。 请检查一下,让我知道它是否对您有用。

我要做的一件事就是感谢三个人对sidetable 所做的贡献。

Peter Baumgartner - 对于sidetable 的原始灵感(For the original inspiration in this tweet thread)Steve Miller - 对于说明频率分布价值的文章(For an article that illustrates the value of looking at frequency distribution article)Ted Petrou - 发表了sidetable,展示了如何在DataFrame中计算空值(Made this post showing how to count null values in a DataFrame.)

最后,missing这个功能并不意味着可以替代出色的missingno模块。 sidetable 中包含的实现是一个快速的摘要版本,在missingno中未包含任何有用的可视化。

pandas访问器API简介

如果您想学习如何构建自己的访问器,则实际上相对简单。 作为参考,您可以在此处查看完成所有工作的文件。

以下是有关入门的简短摘要。 在文件顶部,导入熊猫以访问装饰器:

import pandas as pd@pd.api.extensions.register_dataframe_accessor("stb")class SideTableAccessor:    def __init__(self, pandas_obj):        self._validate(pandas_obj)        self._obj = pandas_obj

这部分代码创建访问器类并定义我选择为stb的访问器值。 一旦安装到位,任何时候导入包含此代码的python模块,您都将获得访问器的注册,并在所有DataFrame上可用。

当实例化该类时,将通过_validate()方法验证当前的熊猫DataFrame,然后在随后的函数中使用self._obj引用该DataFrame。

在这种情况下,我对validate方法的工作并不多,但是您可以选择添加更多逻辑:

@staticmethoddef _validate(obj):    # verify this is a DataFrame    if not isinstance(obj, pd.DataFrame):        raise AttributeError("Must be a pandas DataFrame")

所有工作都在freq and missing函数中完成。 在大多数情况下,这都是标准的pandas 代码。 您只需要确保返回有效的DataFrame。

例如,这里是本文撰写时missing功能的完整版本:

def missing(self, clip_0=False, style=False):    """ Build table of missing data in each column.        clip_0 (bool):     In cases where 0 counts are generated, remove them from the list        style (bool):     Apply a pandas style to format percentages    Returns:        DataFrame with each Column including total Missing Values, Percent Missing        and Total rows    """    missing = pd.concat([self._obj.isna().sum(),                         self._obj.isna().mean()],                        axis='columns').rename(columns={                            0: 'Missing',                            1: 'Percent'                        })    missing['Total'] = len(self._obj)    if clip_0:        missing = missing[missing['Missing'] > 0]    results = missing[['Missing', 'Total',                       'Percent']].sort_values(by=['Missing'],                                               ascending=False)    if style:        format_dict = {'Percent': '{:.2%}', 'Total': '{0:,.0f}'}        return results.style.format(format_dict)    else:        return results

在您的“normal”pandas 代码中,您将使用df引用DataFrame,但是在这里,使用self._obj作为DataFrame来执行串联和排序。

我认为这是构建您自己的熊猫函数自定义样式的非常有用的方法。 如果您要进行某些转换,清除或汇总数据,则可以考虑采用这种方法-而不是仅在文件之间复制和粘贴代码。

摘要

Pandas具有非常丰富的API,但有时可能需要大量的输入和拼写才能以易于理解的格式获取数据。 sidetable 可以通过在数据组合上建立频率表并确定数据中的差距来简化其中的一些摘要任务。

sidetable 不会取代您可能需要做的任何复杂分析来回答复杂问题。 但是,它是一种方便的工具,可用于快速分析数据并确定您可能需要进一步调查的模式。

另外,我希望sidetable 作为如何构建自己的Pandas访问器的示例,以简化常规分析过程。

我希望sidetable 对您有所帮助。 如果您有改进或错误报告的想法,请转到github并告诉我。 我希望它可以随着时间的流逝而发展,并成为对许多其他人有用的有用工具。 我很好奇社区对此有何看法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值