单个单元格中多个数据的相关性分析

Correlation analysis with multiple data in a single cell

我有一个数据集,其中一些行包含单个答案,而其他行包含多个答案。像这样:

       year  length  Animation
0      1971     121       1,2,3
1      1939      71       1,3
2      1941       7       0,2
3      1996      70       1,2,0
4      1975      71       3,2,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 ... 列,但必须有更聪明的方法来解决此问题?

编辑:实际数据片段

您想将 Animation(或数据片段中的 Preferred_positions)分解为一系列单热列,原始列中的每个唯一字符串对应一个单热列。每列的值为零或一,一个对应于该字符串在原始列中出现的行。

首先,您需要获取 Preferred_positions 中的所有唯一子字符串(有关如何处理列表列的信息,请参阅此 )。

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
    )

您应该使用 pd.crosstab() 计算两个分类变量之间的 频率 table,并根据此 table 执行后续分析。当 xy 之一是分类时,df.corr(x, y) 在数学上没有意义,无论它是否编码为数字。

N.B.1 如果 x 是分类的而 y 是数值的,则有两个选项可以描述它们之间的联系:

  1. y 分组为分位数(箱)并将其视为分类
  2. x
  3. 的单热编码虚拟变量执行 y 的线性回归

选项2一般来说更精确,但统计数据超出了这个问题的范围。 post 将重点关注两个分类变量的情况。

N.B.2 稀疏矩阵输出请见.

示例解决方案

数据和预处理

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,2,0
4      1975      71       3,2,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)

频率Table

注意:为简单起见,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()

实例分析

根据频率 table,您可以询问有关 y 给定特定(子集)x 值的分布的问题,反之亦然。这应该更好地描述两个分类变量之间的联系,因为分类变量没有顺序。

例如,

Q: What length does Animation=3 produces? 

A: 66.7% chance to give 71
   33.3% chance to give 121
   otherwise unobserved