我有一张患者诊断代码表,其中每一行代表一名患者的所有诊断:
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&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方式来做到这一点?
答案 0 :(得分:3)
让我们创建一个较小的示例,以便更容易看到每个步骤的效果并验证结果的正确性:
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