在 Pandas 数据框中查找排序列中缺失的数字

4
我有下面的数据框,我想检测每个受试者的缺失访问次数,如何按受试者对访问进行排序并提取仅具有缺失值的记录? 请检查所需的两种输出类型。
第1部分:因此,根据“Visit”列中所有主题的最高数字,所有主题的缺失记录都需要显示出来:
    Subject  Visit      X1      X2
       A       1    1647143  1672244
       A       2    1672244  1689707
       A       4    1689707  1713090
       B       1    1735352  1760283
       B       2    1760283  1788062
       B       7    1788062  1789885
       B       9    1789885  1790728

输出结果为:
    Subject  Visit      X1      X2
       A       3    1647143  1672244
       A       5    1672244  1689707
       A       6    1689707  1713090
       A       7    1647143  1672244
       A       8    1672244  1689707
       A       9    1689707  1713090
       B       3    1735352  1760283
       B       4    1760283  1788062
       B       5    1788062  1789885
       B       6    1789885  1790728
       B       8    1789885  1790728

第二部分:因此,对于每个具体主题中“Visit”列中的最高数字,需要显示访问序列中缺失的记录: 示例输出:

    Subject  Visit      X1      X2
       A       3    1647143  1672244
       B       3    1735352  1760283
       B       4    1760283  1788062
       B       5    1788062  1789885
       B       6    1789885  1790728
       B       8    1789885  1790728

你能否分享一下上述数据框的样本输出? - Devarshi Mandal
@Devarshi Mandal,请看一下,我刚刚完成了。 - Shahine Greene
在结果中填写X1和X2的要求是什么? - Jorge
不需要看 X1 和 X2 Jorge - Shahine Greene
当您创建缺失行时,行数据、X1和X2来自哪里? - Malo
3个回答

1
你需要找到每个受试者缺失的访问记录,每个受试者的最大访问次数为Visit列中的最大值。你可以创建所有可能的(subject, visit)对集合,然后取出观察到的对之外的差异部分。
from itertools import product

all_pairs = set(product(sorted(set(df.Subject)), range(1, df.Visit.max()+1)))
observed_pairs = set(tuple(x) for x in df[['Subject', 'Visit']].to_numpy())

# create a data frame from the missing pairs
pd.DataFrame(sorted(all_pairs.difference(observed_pairs)), columns=['Subject', 'Visit'])
# returns:
   Subject  Visit
0        A      3
1        A      5
2        A      6
3        A      7
4        A      8
5        A      9
6        B      3
7        B      4
8        B      5
9        B      6
10       B      8

在每个受试者的最大访问范围内查找缺失的访问。您可以执行以下操作:
def missing_visits(s):
    all_v = set(range(1, s.max()+1))
    obs_v = set(s)
    return sorted(all_v.difference(obs_v))


df.groupby('Subject')['Visit'].apply(missing_visits).explode()
# returns:
Subject
A    3
B    3
B    4
B    5
B    6
B    8

你的代码结果数据框中只显示了A和B这两个科目,但实际上不仅仅只有A和B两个科目。 - Shahine Greene

1
 #Use the min, max in the visit column for each group to reindex df and fillna
    g=df.groupby('Subject',group_keys=False).apply(lambda x:x.reindex(np.arange(x['Visit'].min(),x['Visit'].max())).ffill().bfill())

#Update the visit column
g['Visit']=g.index

print(g)
# First outcome



Subject  Visit         X1         X2
1       A      1  1672244.0  1689707.0
2       A      2  1689707.0  1713090.0
3       A      3  1689707.0  1713090.0
1       B      1  1735352.0  1760283.0
2       B      2  1735352.0  1760283.0
3       B      3  1735352.0  1760283.0
4       B      4  1760283.0  1788062.0
5       B      5  1788062.0  1789885.0
6       B      6  1789885.0  1790728.0
7       B      7  1789885.0  1790728.0
8       B      8  1789885.0  1790728.0


#Filtered outcome

    #Create and compare tuples of ['Subject','Visit'] of the original and new dataframes
g[~g[['Subject','Visit']].agg(tuple,1).isin(df[['Subject','Visit']].agg(tuple,1))]



    Subject  Visit    X1         X2
3       A      3  1689707.0  1713090.0
3       B      3  1735352.0  1760283.0
4       B      4  1760283.0  1788062.0
5       B      5  1788062.0  1789885.0
6       B      6  1789885.0  1790728.0
8       B      8  1789885.0  1790728.0

@Shahine Greene,这有帮助吗?很乐意提供进一步的帮助。 - wwnde

1

以下是R中的data.table选项:

  • Part1
> setDT(df)[, .(Visit = setdiff(seq(max(df[, "Visit"])), Visit)), Subject]
    Subject Visit
 1:       A     3
 2:       A     5
 3:       A     6
 4:       A     7
 5:       A     8
 6:       A     9
 7:       B     3
 8:       B     4
 9:       B     5
10:       B     6
11:       B     8
  • 第二部分
> setDT(df)[, .(Visit = setdiff(seq(max(Visit)), Visit)), Subject]
   Subject Visit
1:       A     3
2:       B     3
3:       B     4
4:       B     5
5:       B     6
6:       B     8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接