【问题标题】:Cross tab on one column where third column is matched与第三列匹配的一列上的交叉表
【发布时间】:2019-05-18 02:38:27
【问题描述】:

我正在尝试根据第三列匹配的一列进行交叉表。以示例数据为例:

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

【问题讨论】:

  • 你能重新检查一下输出吗?这些值是否正确?
  • 对我来说看起来不错,52 来自表的前四行:10 + 10 + 16 + 16,其中 id 在四行中匹配两次,并且两个匹配实例对应于 A / B .2来自26的id_match,时间相加得到我2
  • 嗯,好吧...我以为是 26。也许我错了。
  • 这是我想出的:pastebin.com/raw/h9ztsz8L也许你可以修改它以满足你的需要。
  • @coldspeed 感谢您的帮助,这很有效。如果您发表评论作为答案,我会接受

标签: python python-3.x pandas dataframe crosstab


【解决方案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 我明白了。这更有意义。让我稍后编辑。
猜你喜欢
  • 2021-12-23
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多