我有以下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
分组。但是,a
列中的值b
和v
对应于x
列中的值y
和w
(值{{1} }}不对应任何值)。因此,我不能简单地比较这两列。
我的工作是手动将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
给我一个错误。
答案 0 :(得分:0)
如果你转换' v'你基本上可以做你尝试过的事情。和' w'首先是数字类型。要么' int'或者'漂浮'很好,但是我会使用浮动,因为你将像连续变量一样对待它们,所以不妨对它进行明确说明。
t[['v','w']] = t[['v','w']].astype(float)
对于你的平均计算并不重要,因为你只是生成一个pandas解释为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'的相关系数为1?和' S2'这真的是你想要的,但根据你将字母变量翻译成数字变量,这是正确的结果。