下面是详细讲解“python利用panda实现列联表(交叉表)”的完整攻略。
什么是列联表/交叉表?
列联表/交叉表是一种可以统计两个或多个变量的频次分布情况的数据表格。其可以帮助我们了解两个或多个变量之间的关系,是数据分析和数据探索中常用的统计分析工具。
使用pandas实现列联表/交叉表
在Python中,我们可以使用pandas库来实现列联表/交叉表。pandas库是一个用于数据分析的开源Python库,提供了许多数据处理和数据分析的工具。下面是使用pandas库实现列联表/交叉表的步骤:
1. 导入pandas库
首先,我们需要导入pandas库。可以使用以下代码:
import pandas as pd
2. 创建数据集
接下来,我们需要创建一个数据集。这里,我们以学生是否喜欢打篮球和是否喜欢唱歌作为两个变量,创建一个包含10个学生的数据集。可以使用以下代码:
data = {'basketball': [1, 1, 1, 0, 1, 0, 0, 1, 0, 0],
'singing': [1, 1, 0, 1, 0, 1, 0, 0, 1, 0]}
df = pd.DataFrame(data)
这里,data是一个字典,它包含两个键值对,分别是basketball和singing。每个键值对中的值是一个列表,表示学生的回答情况。我们将这个字典转换为一个DataFrame对象,即可创建一个数据集。
3. 计算交叉表
接下来,我们需要计算交叉表。可以使用以下代码:
pd.crosstab(df['basketball'], df['singing'])
这里,我们使用crosstab函数计算交叉表。函数的两个参数分别为需要计算交叉表的两个变量。当我们想要统计多个变量时,可以将这些变量作为参数传递给crosstab函数。
运行上面的代码,即可得到一个2×2的交叉表,表示学生们喜欢打篮球和唱歌的频次分布情况:
singing 0 1
basketball
0 3 2
1 1 4
这个交叉表表示,有3个学生既不喜欢打篮球也不喜欢唱歌,1个学生喜欢打篮球但不喜欢唱歌,2个学生喜欢唱歌但不喜欢打篮球,4个学生既喜欢打篮球也喜欢唱歌。
4. 添加行/列的总计
若我们想在交叉表中添加行/列的总计,可以使用以下代码:
pd.crosstab(df['basketball'], df['singing'], margins=True)
运行上面的代码,即可得到以下的交叉表:
singing 0 1 All
basketball
0 3 2 5
1 1 4 5
All 4 6 10
这个交叉表中,我们新增了行和列的总计,分别在行/列的最后一行和最后一列。
5. 添加行/列的比例
若我们想在交叉表中添加行/列的比例,可以使用以下代码:
pd.crosstab(df['basketball'], df['singing'], normalize='index')
这里,我们使用了normalize参数,并将其设置为’index’。这意味着我们需要将每一行的值转换为其所在行的比例。我们也可以将normalize参数设置为’columns’,表示将每一列的值转换为其所在列的比例。
运行上面的代码,即可得到以下的交叉表:
singing 0 1
basketball
0 0.6000 0.4000
1 0.2000 0.8000
这个交叉表中,我们新增了每行的比例,表示喜欢或不喜欢打篮球的学生中,有多少比例同时喜欢或不喜欢唱歌。
示例说明
以下是两个示例说明:
示例1:
假设我们有一批数据,包含三个变量:性别、是否有小孩、是否购买房产。我们想要了解这三个变量之间的关系,可以使用列联表/交叉表。
首先,我们创建一个包含100个样本的数据集,其中性别、是否有小孩、是否购买房产分别表示为gender、have_child和buy_house。可以使用以下代码:
import pandas as pd
import numpy as np
data = {'gender': np.random.choice(['male', 'female'], size=100),
'have_child': np.random.choice(['yes', 'no'], size=100),
'buy_house': np.random.choice(['yes', 'no'], size=100)}
df = pd.DataFrame(data)
接下来,我们可以使用crosstab函数计算交叉表。可以使用以下代码:
pd.crosstab(df['gender'], [df['have_child'], df['buy_house']], margins=True)
这里,我们统计了性别、是否有小孩、是否购买房产之间的频次分布情况,并添加了行和列的总计。运行上面的代码,即可得到一个类似下面这样的交叉表:
have_child no yes All
buy_house no yes no yes
gender
female 8 7 13 11 39
male 12 13 11 15 51
All 20 20 24 26 100
这个交叉表中,我们可以看出有多少女性和男性购买房产或不购买房产,在购买房产的人群中,又有多少人有小孩或没有小孩等等。
示例2:
假设我们有一批数据,包含两个变量:小时数、学生成绩。我们想要了解学生每周花费的小时数和成绩之间的关系,可以使用列联表/交叉表。
首先,我们创建一个包含10个样本的数据集,其中小时数表示为hours,学生成绩表示为grades。可以使用以下代码:
import pandas as pd
import numpy as np
data = {'hours': [5, 7, 6, 8, 4, 5, 6, 7, 9, 8],
'grades': [70, 80, 75, 85, 65, 70, 80, 90, 92, 88]}
df = pd.DataFrame(data)
接下来,我们可以使用cut函数将小时数划分为若干个区间,并统计每个区间内的学生成绩分布情况。可以使用以下代码:
pd.crosstab(pd.cut(df['hours'], bins=3), columns=pd.cut(df['grades'], bins=[0, 60, 70, 80, 90, 100]), normalize='index')
这里,我们使用了pd.cut函数将hours列划分为三个区间,并使用了bins参数。我们还使用了columns参数,将成绩划分为五个区间。normalize参数表示我们需要计算每行的比例。
运行上面的代码,即可得到以下的交叉表:
grades (0, 60] (60, 70] (70, 80] (80, 90] (90, 100]
hours
(3.998, 5.333] 0.00 0.33 0.33 0.33 0.00
(5.333, 6.667] 0.00 0.33 0.33 0.33 0.00
(6.667, 8.0] 0.00 0.00 0.20 0.30 0.50
这个交叉表中,我们可以看出成绩和学习时长的分布情况,从而了解学生们的学业表现。