python 利用panda 实现列联表(交叉表)


Posted in Python onFebruary 06, 2021

交叉表(cross-tabulation,简称crosstab)是⼀种⽤于计算分组频率的特殊透视表。

语法详解:

pd.crosstab(index, # 分组依据
   columns, # 列
   values=None, # 聚合计算的值
   rownames=None, # 列名称
   colnames=None, # 行名称
   aggfunc=None, # 聚合函数
   margins=False, # 总计行/列
   dropna=True, # 是否删除缺失值
   normalize=False # 
   )

1 crosstab() 实例1

1.1 读取数据

import os
import numpy as np
import pandas as pd

file_name = os.path.join(path, 'Excel_test.xls')
df = pd.read_excel(io=file_name, # 工作簿路径
     sheetname='透视表', # 工作表名称
     skiprows=1, # 要忽略的行数
     parse_cols='A:D' # 读入的列
     )
df

python 利用panda 实现列联表(交叉表)

1.2 pd.crosstab() 默认生成以行和列分类的频数表

pd.crosstab(df['客户名称'], df['产品类别'])

python 利用panda 实现列联表(交叉表)

1.3 设置跟多参数实现分类汇总

pd.crosstab(index=df['客户名称'],
   columns=df['产品类别'],
   values=df['销量'],
   aggfunc='sum',
   margins=True
   ).round(0).fillna(0).astype('int')

python 利用panda 实现列联表(交叉表)

注:因为交叉表示透视表的特例,所以交叉表可以用透视表的函数实现。又因为透视表可以用更 python 的方式 groupby-apply 实现,所以,交叉表完全可以用 groupby-apply 的方式实现。

2 用分类汇总的方法实现 交叉表

df.groupby(['客户名称', '产品类别']).apply(sum)

python 利用panda 实现列联表(交叉表)

2.1 分类汇总、重新索引、设置数值格式综合应用

c_tbl = df.groupby(['客户名称', '产品类别']).apply(sum)['销量'].unstack()
c_tbl['总计'] = c_tbl.sum(axis=1) # 添加总计列
c_tbl.fillna(0).round(0).astype('int')

python 利用panda 实现列联表(交叉表)

软件信息:

python 利用panda 实现列联表(交叉表)

补充:使用python(pandas)将数据处理成交叉分组表

交叉分组表是汇总两种变量数据的方法, 在很多场景可以用到, 本文会介绍如何使用pandas将包含两个变量的数据集处理成交叉分组表.

环境

pandas

python 2.7

原理

用坐标轴来进行比喻, 其中一个变量作为x轴, 另一个作为y轴, 如果定位到数据则累加一, 将所有数据遍历一遍, 最后的坐标轴就是一张交叉分组表(使用坐标轴展示的数据一般是连续的, 交叉分组表的数据是离散的).

具体实现

示例数据:

quality price
0  bad 18
1  bad 17
2  great  52
3  good  28
4  excellent  88
5  great  63
6  bad 8
7  good  22
8  good  68
9  excellent  98
10 great  53
11 bad 13
12 great  62
13 good  48
14 excellent  78
15 great  63
16 good  37
17 great  69
18 good  28
19 excellent  81
20 great  43
21 good  32
22 great  62
23 good  28
24 excellent  82
25 great  53

代码:

import pandas as pd
  from pandas import DataFrame, Series
  #生成数据
  df = DataFrame([['bad', 18], ['bad', 17], ['great', 52], ['good', 28], ['excellent', 88], ['great', 63]
        , ['bad', 8], ['good', 22], ['good', 68], ['excellent', 98], ['great', 53]
        , ['bad', 13], ['great', 62], ['good', 48], ['excellent', 78], ['great', 63]
        , ['good', 37], ['great', 69], ['good', 28], ['excellent', 81], ['great', 43]
        , ['good', 32], ['great', 62], ['good', 28], ['excellent', 82], ['great', 53]], columns = ['quality', 'price'])
#广播使用的函数
def quality_cut(data):
  s = Series(pd.cut(data['price'], np.arange(0, 100, 10)))
  return pd.groupby(s, s).count()
#进行分组处理
df.groupby(df['quality']).apply(quality_cut)

结果:

python 利用panda 实现列联表(交叉表)

交叉分组

详细分析

从逻辑上来看, 为了达到对示例数据的交叉分组, 需要完成以下工作:

将数据以quality列进行分组.

将每个分组的数据分别进行cut, 以10为间隔.

将cut过的数据, 以cut的范围为列进行分组

将所有数据组合到一起, row为quality, columns为cut的范围

步骤1, pandasgroupby(...)接口, 会按照指定的列进行分组处理, 每一个分组, 存储相同类别的数据

<class 'pandas.core.frame.DataFrame'>
  quality price
0   bad   18
1   bad   17
6   bad   8
11   bad   13

而我们需要的, 只是price这列的数据, 所以单独将这列拿出来, 进行cut, 最后得到我们要的series(步骤2, 步骤3)

price
(0, 10]   1
(10, 20]  3
(20, 30]  0
(30, 40]  0
(40, 50]  0
(50, 60]  0
(60, 70]  0
(70, 80]  0
(80, 90]  0

使用pandas

apply()的广播特性, 每一个分组的数据都会经过上述几个步骤的处理, 最后与第一次分组row进行组合.

后记

估计能力有限, 这个问题想了很长时间, 没想到pandas这么可以这么方便达成交叉分组的效果. 思考的时候主要是卡在数据组合上, 当数据量很大时通过多个步骤进行数据组合, 肯定是低效而且错误的. 最后仔细研究了groupby, dataframe, series, dataframeIndex等数据模型, 使用广播特性用几句代码就完成了. 证明了pandas的高性能, 也提醒自己遇见问题一定要耐心分析。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Python 相关文章推荐
python获取指定网页上所有超链接的方法
Apr 04 Python
Python socket编程实例详解
May 27 Python
在Python中marshal对象序列化的相关知识
Jul 01 Python
Python冲顶大会 快来答题!
Jan 17 Python
Python 打印中文字符的三种方法
Aug 14 Python
Python判断以什么结尾以什么开头的实例
Oct 27 Python
使用python 打开文件并做匹配处理的实例
Jan 02 Python
python使用正则筛选信用卡
Jan 27 Python
python爬虫简单的添加代理进行访问的实现代码
Apr 04 Python
基于python实现把json数据转换成Excel表格
May 07 Python
python判断是空的实例分享
Jul 06 Python
Python wordcloud库安装方法总结
Dec 31 Python
jupyter 添加不同内核的操作
Feb 06 #Python
解决import tensorflow导致jupyter内核死亡的问题
Feb 06 #Python
PyCharm常用配置和常用插件(小结)
Feb 06 #Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
Feb 06 #Python
python反扒机制的5种解决方法
Feb 06 #Python
Python 爬取淘宝商品信息栏目的实现
Feb 06 #Python
解决pytorch下出现multi-target not supported at的一种可能原因
Feb 06 #Python
You might like
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
基于php在各种web服务器的运行模式详解
2013/06/03 PHP
PHP 如何利用phpexcel导入数据库
2013/08/24 PHP
PHP中常用的字符串格式化函数总结
2014/11/19 PHP
Yii不依赖Model的表单生成器用法实例
2014/12/04 PHP
PHP的Yii框架的基本使用示例
2015/08/21 PHP
Yii2 GridView实现列表页直接修改数据的方法
2016/05/16 PHP
PHP基于自定义函数实现的汉字转拼音功能实例
2017/09/30 PHP
使用jQuery避免鼠标双击的解决方案
2013/08/21 Javascript
jquery得到font-size属性值实现代码
2013/09/30 Javascript
MyEclipse取消验证Js的两种方法
2013/11/14 Javascript
使用JQuery快速实现Tab的AJAX动态载入(实例讲解)
2013/12/11 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
2014/06/29 Javascript
jQuery的:parent选择器定义和用法
2014/07/01 Javascript
javascript里使用php代码实例
2014/12/13 Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
2015/08/28 Javascript
BootStrap 获得轮播中的索引和当前活动的焦点对象
2017/05/11 Javascript
利用JavaScript如何查询某个值是否数组内
2017/07/30 Javascript
Angularjs实现下拉框联动的示例代码
2017/08/22 Javascript
使用Angular自定义字段校验指令的方法示例
2019/02/01 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
Vue实现简单的拖拽效果
2020/08/25 Javascript
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
教你用Python创建微信聊天机器人
2020/03/31 Python
python excel使用xlutils类库实现追加写功能的方法
2018/05/02 Python
浅谈Python中的全局锁(GIL)问题
2019/01/11 Python
Skip Hop官网:好莱坞宝宝挚爱品牌
2018/06/17 全球购物
几道数据库的面试题或笔试题
2014/05/31 面试题
旅游管理专业大学生职业规划书
2014/02/27 职场文书
艺术学院毕业生自我评价
2014/03/02 职场文书
环境保护标语
2014/06/20 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
详解MySQL的半同步
2021/04/22 MySQL
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python
win10搭建配置ftp服务器的方法
2022/08/05 Servers