我有以下Pandas数据帧:
t = pd.DataFrame({"u": ["S1", "S1", "S1", "S2", "S2", "S2", "S5", "S5", "S5"],
"v": ["a", "b", "a", "a", "b", "b", "b", "a", "a"],
"w": ["x", "z", "x", "x", "y", "y", "z", "x", "y"]})
我想计算列v
和w
之间的一致性(类似于分类精度),按列u
分组。然而,列v
中的值a
和b
对应于列w
中的值x
和y
(值z
不对应于任何值)。因此,我不能简单地比较这两列。
我所做的是手动将列v
和w
中的值设置为0
(a
和x
)、1
(b
和y
)和2
(z
):
t.loc[t["v"] == "a", "v"] = 0
t.loc[t["v"] == "b", "v"] = 1
t.loc[t["w"] == "x", "w"] = 0
t.loc[t["w"] == "y", "w"] = 1
t.loc[t["w"] == "z", "w"] = 2
现在我可以比较这两列,按列u
分组,如下所示:
t.groupby("u").agg(lambda x: np.mean(x["v"] == x["w"]))
这给了我想要的结果,但我想知道是否有更简单的方法来实现同样的事情。
此外,如果我想计算np.corrcoef
而不是np.mean
,即,则我的解决方案不起作用
t.groupby("u").agg(lambda x: np.corrcoef(x["v"], x["w"]))
给了我一个错误。
如果先将'v'和'w'转换为数字类型,基本上可以完成您尝试的操作。"int"或"float"都可以,但我会选择float,因为你将把它们当作连续变量来处理,所以最好明确它。
t[['v','w']] = t[['v','w']].astype(float)
这对你的平均值计算来说并不重要,因为你只是生成了一个panda解释为0/1的布尔值。但对于相关系数,你需要提供数字。您还需要在此处使用apply
而不是agg
:
t.groupby("u").apply(lambda x: np.corrcoef(x["v"], x["w"]))
但这会给您带来很多额外的输出(2x2,其中标量就足够了),所以我在这里使用pandas corr
方法:
t.groupby('u')['v'].corr(t['w'])
u
S1 1.000000
S2 1.000000
S5 0.866025
根据你对问题的描述,我不确定"S1"one_answers"S2"的相关系数1是否真的是你想要的,但根据你将字母变量转换为数字变量的结果,这是正确的结果。