一列交叉表,第三列匹配

5

我正在尝试基于一个列进行交叉表,其中第三列匹配。以以下数据为例:

df = pd.DataFrame({'demographic' : ['A', 'B', 'B', 'A', 'C', 'C'],
                'id_match' : ['101', '101', '201', '201', '26', '26'],
                'time' : ['10', '10', '16', '16', '1', '1']})

当id_match匹配时,我想找到人口统计列的交叉表时间的结果总和。输出将如下所示:

  A  B  C
A 0  52 0
B 52 0  0
C 0  0  2

希望这些内容能够清晰易懂,如有疑问请评论。谢谢J。

2
请您重新检查一下输出结果,这些数值是否正确? - cs95
看起来没问题,52来自表格的前四行:10 + 10 + 16 + 16,其中id匹配两次且两个匹配实例都对应A / B。2来自26的id_match,将时间相加得到2。 - JDraper
嗯,好吧...我原以为应该是26。也许我错了。 - cs95
这是我想出来的代码:https://pastebin.com/raw/h9ztsz8L ,也许你可以根据自己的需要进行修改。 - cs95
@coldspeed,感谢您的帮助,它起作用了。如果您将您的评论发布为答案,我会接受它。 - JDraper
1个回答

1
您可以使用mergecrosstab来解决此问题:
u = df.reset_index()
v = u.merge(u, on='id_match').query('index_x != index_y')
r = pd.crosstab(v.demographic_x, 
                v.demographic_y, 
                v.time_x.astype(int) + v.time_y.astype(int), 
                aggfunc='sum')

print(r)
demographic_y     A     B    C
demographic_x                 
A               NaN  52.0  NaN
B              52.0   NaN  NaN
C               NaN   NaN  4.0

如果您需要用零填充NaN值,可以使用fillna
r.fillna(0, downcast='infer')

demographic_y   A   B  C
demographic_x           
A               0  52  0
B              52   0  0
C               0   0  4

我认为我的原始输出是正确的。这取决于用户想要什么。在您提供给我的代码中,我添加了一个额外的步骤来对time_x和time_y进行求和,以便为每个id_match提供总时间。感谢您的帮助!J - JDraper
@JDraper 我明白了,这样更有意义。让我稍微编辑一下。 - cs95

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接