【问题标题】:Pairwise Frequency Table for Multiple Columns in PythonPython中多列的成对频率表
【发布时间】:2016-12-07 05:34:46
【问题描述】:

我有一个患者诊断代码表,其中每一行代表一个患者的所有诊断:

      D0             D1        D2       D3       D4        D5       D6  
0          0              0         0        0        0         0        0   
1     I48.91          R60.9    M19.90    Z87.2        0         0        0   
2        496         564.00     477.9        0    J44.9     J30.9      I10   
3        I96          R63.0     Z51.5        0  L97.909    I69.90   F01.50   
4     491.21          428.0    427.31   V58.61        0    I48.91   Z79.01   
5          0              0         0        0        0         0        0   
6      J44.9          F41.9       I10   H61.22        0       Z23        0   
7          0              0         0        0        0         0        0   
8     M48.00          I12.9     N18.9   K59.00        0     N39.0      Z23   
9      I11.9         R41.82     R56.9   E11.49   K59.00         0  J45.901   
10     I11.9          N40.0    F01.50        0    N40.1     J18.9    J44.1   
11     R31.9         M19.90         0   R53.81        0         0        0   
12         0              0         0        0        0         0        0   
13    M48.02         M48.06     I27.2        0   R53.81         0        0   
14     I50.9         M19.90     F41.9   I25.10        0         0        0   
15         0              0         0        0        0         0        0   
16   I69.359         I48.91     R74.8      I10        0  T50.901A    I95.9   

... 超过 600 名患者,每名患者最多有 15 个诊断。 (0 代表没有诊断)。 我想创建一个成对频率表来计算患者有不同诊断对的次数:

            I48.91                 R60.9                  M19.90
I48.91  count(I48.91)        count(I48.91, R60.9)    count(I48.91, M19.90)
R60.9   count(R60.9, 148.91)
M19.9 ...

我已经创建了这样的表:

FreqTable = pd.DataFrame(columns=UniqueCodes['DCODE'], index=UniqueCodes['DCODE'])
FreqTable = FreqTable.fillna(0)

Table of Pairwise frequency counts in Python 使用嵌套的 for 循环对一列数据执行此操作,但对于多列这会变得复杂。任何人都有一个很好的pythonese方式来做到这一点?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    让我们创建一个更小的示例,以便更容易看到每个步骤的效果并验证结果的正确性:

    df = pd.DataFrame({'D0': ['0', 'A', 'B', 'C'],
                       'D1': ['B', '0', 'C', 'D'],
                       'D2': ['C','D','0','A']})
    #   D0 D1 D2
    # 0  0  B  C
    # 1  A  0  D
    # 2  B  C  0
    # 3  C  D  A
    

    由于 0 将被忽略,让我们将它们更改为 NaN:

    df = df.replace('0', np.nan)
    

    列标签D0、D1、D2 也可以忽略。重要的是行。 所以让我们stack 列做一个系列:

    code = df.stack()
    0  D1    B
       D2    C
    1  D0    A
       D2    D
    2  D0    B
       D1    C
    3  D0    C
       D1    D
       D2    A
    dtype: object
    

    再一次,列标签无关紧要,让我们删除第二级索引:

    code.index = code.index.droplevel(1)
    code.name = 'code'
    

    这样我们就结束了

    0    B
    0    C
    1    A
    1    D
    2    B
    2    C
    3    C
    3    D
    3    A
    Name: code, dtype: object
    

    请注意,此系列的索引是指df 中的原始行标签。如果我们要join code 与它自己,那么我们将获得同一行中所有代码对的列表,对于每一行:

    code = code.to_frame()
    pair = code.join(code, rsuffix='_2')
        #   code code_2
    # 0    B      B
    # 0    B      C
    # 0    C      B
    # 0    C      C
    # 1    A      A
    # 1    A      D
    # 1    D      A
    # 1    D      D
    # 2    B      B
    # 2    B      C
    # 2    C      B
    # 2    C      C
    # 3    C      C
    # 3    C      D
    # 3    C      A
    # 3    D      C
    # 3    D      D
    # 3    D      A
    # 3    A      C
    # 3    A      D
    # 3    A      A
    

    现在问题解决了,使用pd.crosstab根据这个数据制作频率表:

    freq = pd.crosstab(pair['code'], pair['code_2'])
    

    把它们放在一起:

    import numpy as np
    import pandas as pd
    df = pd.DataFrame({'D0': ['0', 'A', 'B', 'C'],
                       'D1': ['B', '0', 'C', 'D'],
                       'D2': ['C','D','0','A']})
    #   D0 D1 D2
    # 0  0  B  C
    # 1  A  0  D
    # 2  B  C  0
    # 3  C  D  A
    
    df = df.replace('0', np.nan)
    code = df.stack()
    code.index = code.index.droplevel(1)
    code.name = 'code'
    code = code.to_frame()
    pair = code.join(code, rsuffix='_2')
    freq = pd.crosstab(pair['code'], pair['code_2'])
    

    产量

    code_2  A  B  C  D
    code              
    A       2  0  1  2
    B       0  2  2  0
    C       1  2  3  1
    D       2  0  1  2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多