pandas Python:绘制同一天的观测值组合

uqcuzwp8  于 2022-12-10  发布在  Python
关注(0)|答案(2)|浏览(129)

我有以下数据集:

id test date
1  A    2000-01-01
1  B    2000-01-01
1  C    2000-01-08

2  A    2000-01-01
2  A    2000-01-01
2  B    2000-01-08

3  A    2000-01-01
3  C    2000-01-01
3  B    2000-01-08

4  A    2000-01-01
4  B    2000-01-01
4  C    2000-01-01

5  A    2000-01-01
5  B    2000-01-01
5  C    2000-01-01

我想创建一个矩阵图,其中包含在同一天进行测试的人数。
例如:

由于我们可以看到,1次(对于一个个体,id=1)测试A和B都是在当天进行的;同样对于一个个体(id = 3),测试A和B在同一天进行;对于两个个体(ID=4和5),在同一天进行三次测试。
到目前为止,我正在做以下工作:

df_tests = df.groupby(['id', 'date']).value_counts().reset_index(name='count')

df_tests_unique = df_tests[df_tests_re.duplicated(subset=['id','date'], keep=False)]

df_tests_unique = df_tests_unique[["id", "date", "test"]]

因此,剩下的唯一事情就是计算同一日期内不同测试发生的次数

wwtsj6pe

wwtsj6pe1#

谢谢你的有趣练习:)下面给出了一个可能的解决方案。我创建了一个numpy数组,并使用seaborn绘制了它。注意,对于只有A,B,C的情况,这是相当硬的编码,但我相信你将能够概括这一点。此外,seaborn的默认配色方案带来了相反的颜色比你想要的,但这是很容易修复的。希望我能帮助!
以下是脚本生成的图:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame({
    'id': [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5],
    'test': ['A', 'B', 'C', 'A', 'A', 'B', 'A', 'C', 'B', 'A', 'B', 'C', 'A', 'B', 'C'],
    'date': ['2000-01-01', '2000-01-01', '2000-01-08', '2000-01-01', '2000-01-01', '2000-01-08', '2000-01-01', '2000-01-01', '2000-01-08', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01']
})
df_tests = df.groupby(['id', 'date']).value_counts().reset_index(name='count')
df_test_with_patterns = (df_tests[df_tests.duplicated(subset=['id', 'date'], keep=False)]
                         .groupby(['id', 'date'])
                         .agg({'test': 'sum'})
                         .reset_index().groupby('test').count().reset_index()
                         .assign(pattern=lambda df: df.test.apply(lambda tst: [1 if x in tst else 0 for x in ['A', 'B', 'C']]))
                         )
pattern_mat = np.vstack(df_test_with_patterns.pattern.values.tolist())
ax = sns.heatmap(pattern_mat, xticklabels=['A', 'B', 'C'], yticklabels=df_test_with_patterns.id.values)
ax.set(xlabel='Test Type', ylabel='# of individuals that took in a single day')
plt.show()
print
7gs2gvoe

7gs2gvoe2#

在Erap回答的基础上,这个方法也能奏效,也许速度会稍快一些:

out = pd.get_dummies(df.set_index(['date', 'id'], drop=True).sort_index()).groupby(level=[0,1]).sum()

然后遍历不同的日期以得到不同的图表

for i in out.index.levels[0]:
    d = out.loc[i]
    plt.figure()
    plt.title(f'test for date {i}')
    sns.heatmap(d.gt(0))

相关问题