如何解决单个单元格中多个数据的相关分析
我有一个数据集,其中一些行包含单一答案,而另一些行包含多个答案。像这样:
year length Animation
0 1971 121 1,2,3
1 1939 71 1,3
2 1941 7 0,2
3 1996 70 1,0
4 1975 71 3,0
通过单一答案,我设法使用 df.corr() 创建了一个热图,但我无法弄清楚多行答案的最佳方法是什么。
我可以拆分它们并为每个答案添加额外的列,例如:
year length Animation
0 1971 121 1
1 1971 121 2
2 1971 121 3
3 1939 71 1
4 1939 71 3 ...
然后执行完全相同的 dr.corr(),或添加额外的 Animation_01、Animation_02 ... 列,但必须有更聪明的方法来解决此问题吗?
解决方法
您应该使用 pd.crosstab() 计算两个分类变量之间的频率表,并基于此表执行后续分析。当 df.corr(x,y)
和 x
之一是分类时,y
在数学上没有意义,无论是否编码为数字。
N.B.1 如果 x
是分类的,而 y
是数字的,有两个选项可以描述它们之间的联系:
- 将
y
分组为分位数(bins)并将其视为分类的 - 对
y
的单热编码虚拟变量执行x
的线性回归
选项 2 总体上更精确,但统计数据超出了本问题的范围。这篇文章将重点讨论两个分类变量的情况。
N.B.2 对于稀疏矩阵输出,请参见 this post。
示例解决方案
数据和预处理
import pandas as pd
import io
import matplotlib.pyplot as plt
from seaborn import heatmap
df = pd.read_csv(io.StringIO("""
year length Animation
0 1971 121 1,2,3
1 1939 71 1,3
2 1941 7 0,2
3 1996 70 1,0
4 1975 71 3,0
"""),sep=r"\s{2,}",engine="python")
# convert string to list
df["Animation"] = df["Animation"].str.split(',')
# expand list column into new rows
df = df.explode("Animation")
# (optional)
df["Animation"] = df["Animation"].astype(int)
频率表
注意:为简单起见,忽略 length
的分组
ct = pd.crosstab(df["Animation"],df["length"])
print(ct)
# Out[65]:
# length 7 70 71 121
# Animation
# 0 1 1 1 0
# 1 0 1 1 1
# 2 1 1 1 1
# 3 0 0 2 1
可视化
ax = heatmap(ct,cmap="viridis",yticklabels=df["Animation"].drop_duplicates().sort_values(),xticklabels=df["length"].drop_duplicates().sort_values(),)
ax.set_title("Title",fontsize=20)
plt.show()
示例分析
根据频率表,您可以询问给定某个(子集)y
值的 x
的分布,反之亦然。这应该更好地描述两个分类变量之间的联系,因为分类变量没有顺序。
例如
Q: What length does Animation=3 produces?
A: 66.7% chance to give 71
33.3% chance to give 121
otherwise unobserved
,
您希望将 Animation
(或数据片段中的 Preferred_positions
)分解为一系列单热列,原始列中的每个唯一字符串对应一个单热列。具有 0 或 1 的每一列的值,一个对应于该字符串出现在原始列中的行。
首先,您需要获取 Preferred_positions
中的所有唯一子字符串(有关如何处理一列列表的信息,请参阅此 answer)。
positions = df.Preferred_positions.str.split(',').sum().unique()
然后,您可以根据给定的位置是否在每行的 Preferred_positions
中,在循环中创建位置列。
for position in positions:
df[position] = df.Preferred_positions.apply(
lambda x: 1 if position in x else 0
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。