【问题标题】:Getting each element in Pandas crosstab获取 Pandas 交叉表中的每个元素
【发布时间】:2018-01-14 00:46:26
【问题描述】:

我有一个数据集如下:

a,b,c
1,1,1
1,1,1
1,1,2
2,1,2
2,1,1
2,2,1

我用 pandas 创建了交叉表:

 cross_tab = pd.crosstab(index=a, columns=[b, c], rownames=['a'], colnames=['b', 'c'])

我的交叉表作为输出给出:

b        1     2
c        1  2  1
a        
1        2  1  0
2        1  1  1

我想针对给定的每个 a、b 和 c 值迭代此交叉表。如何获取 cross_tab[a=1][b=1, c=1] 等值?谢谢。

【问题讨论】:

    标签: python pandas crosstab contingency


    【解决方案1】:

    你可以使用slicers:

    a,b,c = 1,1,1
    idx = pd.IndexSlice
    print (cross_tab.loc[a, idx[b,c]])
    2
    

    您也可以通过DataFrame.unstackreorder_levels 重塑df,然后使用loc

    a = cross_tab.unstack().reorder_levels(('a','b','c'))
    print (a)
    a  b  c
    1  1  1    2
    2  1  1    1
    1  1  2    1
    2  1  2    1
    1  2  1    0
    2  2  1    1
    dtype: int64
    
    print (a.loc[1,1,1])
    2
    

    【讨论】:

    • 感谢您的回答。我现在有另一个问题。如果我给出 print(cross_tab2.loc[2,2,2]),它会返回错误。如何在交叉表中获取 a、b 和 c 的值?
    • 你想循环 a 吗?或者如果print(cross_tab2.loc[2,2,2]) 需要什么输出?
    • 我实际上想遍历 a、b、c 的所有可能组合。或者我可以循环查找交叉表中存在的 a、b、c 的所有值。
    • 可以使用for (a,b,c), x in a.iteritems(): print (a,b,c) print (x) 吗?
    【解决方案2】:

    您正在寻找df2.xxx.get_level_values:

    In [777]: cross_tab.loc[cross_tab.index.get_level_values('a') == 1,\
                            (cross_tab.columns.get_level_values('b') == 1)\
                          & (cross_tab.columns.get_level_values('c') == 1)]
    Out[777]: 
    b  1
    c  1
    a   
    1  2
    

    【讨论】:

      【解决方案3】:

      另一种考虑的方法可能是简单地使用.loc 来导航由pandas.crosstab 生成的分层索引,尽管会失去一点可读性。以下示例说明了这一点:

      import pandas as pd
      import numpy as np
      
      np.random.seed(1234)
      
      df = pd.DataFrame(
          {
              "a": np.random.choice([1, 2], 5, replace=True),
              "b": np.random.choice([11, 12, 13], 5, replace=True),
              "c": np.random.choice([21, 22, 23], 5, replace=True),
          }
      )
      df
      

      输出

          a   b   c
      0   2   11  23
      1   2   11  23
      2   1   12  23
      3   2   12  21
      4   1   12  21
      

      crosstab 输出为:

      cross_tab = pd.crosstab(
          index=df.a, columns=[df.b, df.c], rownames=["a"], colnames=["b", "c"]
      )
      cross_tab
      
      b   11  12
      c   23  21  23
      a           
      1   0   1   1
      2   2   1   0
      

      现在假设您想在a==2b==11c==23 时访问值,那么就这样做

      cross_tab.loc[2].loc[11].loc[23]
      
      2
      

      为什么会这样? .loc 允许通过索引标签进行选择。在crosstab 输出的数据框中,我们以前的列值现在变成了索引标签。因此,对于我们所做的每个.loc 选择,它都会给出与该索引标签对应的数据帧切片。让我们一步一步导航cross_tab.loc[2].loc[11].loc[23]

      cross_tab.loc[2]
      

      产量:

      b   c 
      11  23    2
      12  21    1
          23    0
      Name: 2, dtype: int64
      

      下一个:

      cross_tab.loc[2].loc[11]
      

      产量:

      c
      23    2
      Name: 2, dtype: int64
      

      我们终于有了

      cross_tab.loc[2].loc[11].loc[23]
      

      产生:

      2

      为什么我说这会降低可读性?因为要理解这个选择,你必须知道交叉表是如何创建的,即行是a,列的顺序是[b, c]。您必须知道这一点才能解释cross_tab.loc[2].loc[11].loc[23] 会做什么。但我发现这通常是一个很好的权衡。

      【讨论】:

        猜你喜欢
        • 2014-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-05
        • 2019-05-20
        • 2012-03-24
        • 1970-01-01
        • 2011-02-17
        相关资源
        最近更新 更多