如何使用其他列按条件按行提取数据帧值?

2024-05-14 21:05:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,如下所示:

#values
a=["003C", "003P1", "003P1", "003P1", "004C", "004P1", "004P2", "003C", "003P2", "003P1", "003C", "003P1", "003P2", "003C", "003P1", "004C", "004P2", "001C", "001P1"]
b=["chr18", "chr20", "chr8", "chr8", "chr11", "chr11", "chr11", "chr11", "chr11", "chr11", "chr1", "chr1", "chr1", "chr1", "chr1", "chr11", "chr11", "chr9", "chr9"]
c=[48399,145653,244695,244695,1163940,1163940,1163940,5986513,5986513,5986513,248650751,248650751,248650751,125895,125895,2587895,2587895,14587952,14587952]
d=["C", "G", "C", "C", "C", "C", "C", "G", "G", "G", "T", "T", "T", "T", "T", "C", "C", "T", "T"]
e=["A", "T", "A", "A", "G", "G", "G", "A", "A", "A", "A", "A", "A", "A", "A", "G", "G", "C", "C"]
#Make dataframe
df = pd.DataFrame({'Sample':a, 'CHROM':b, 'POS':c, 'REF':d, 'ALT':e})

df

    Sample  CHROM   POS         REF  ALT
0   003C    chr18   48399       C    A
1   003P1   chr20   145653      G    T
2   003P1   chr8    244695      C    A
3   003P1   chr8    244695      C    A
4   004C    chr11   1163940     C    G
5   004P1   chr11   1163940     C    G
6   004P2   chr11   1163940     C    G
7   003C    chr11   5986513     G    A
8   003P2   chr11   5986513     G    A
9   003P1   chr11   5986513     G    A
10  003C    chr1    248650751   T    A
11  003P1   chr1    248650751   T    A
12  003P2   chr1    248650751   T    A
13  003C    chr1    125895      T    A
14  003P1   chr1    125895      T    A
15  004C    chr11   2587895     C    G
16  004P2   chr11   2587895     C    G
17  001C    chr9    14587952    T   C
18  001P1   chr9    14587952    T   C

我想提取与P1P2P1公共的C匹配df['Sample']'CHROM' 'POS' 'REF' 'ALT'数据帧&P2。 例如003C:将其对应的003P1或003P2与所有匹配值'CHROM' 'POS' 'REF' 'ALT'一起查看索引7,8,913,1410,11,12。我想把它们全部提取出来:

预期产出为:

    Sample  CHROM   POS       REF   ALT
0   003C    chr1    125895     T    A
1   003P1   chr1    125895     T    A
2   004C    chr11   1163940    C    G
3   004P1   chr11   1163940    C    G
4   004P2   chr11   1163940    C    G
5   004C    chr11   2587895    C    G
6   004P2   chr11   2587895    C    G
7   003C    chr11   5986513    G    A
8   003P2   chr11   5986513    G    A
9   003P1   chr11   5986513    G    A
10  001C    chr9    14587952   T    C
11  001P1   chr9    14587952   T    C
12  003C    chr1    248650751  T    A
13  003P1   chr1    248650751  T    A
14  003P2   chr1    248650751  T    A

我尝试了以下代码:

df[['INT','STR']] = df['Sample'].str.extract('(\d+)(.*)')
df = df[df.groupby(['CHROM', 'POS', 'REF', 'ALT', 'INT'])['STR'].transform('size').eq(3)]

但是它只在所有这三种情况下常见,比如C, P1 and P2而不是C, P1 or P2

谢谢你的帮助。谢谢


Tags: 数据sampleposrefdfaltp2chr1
1条回答
网友
1楼 · 发布于 2024-05-14 21:05:40

溶液

c = ['CHROM', 'POS', 'REF', 'ALT', 'INT']
df[['INT','STR']] = df['Sample'].str.extract(r'(\d+)(.*)')

m  = df['STR'].isin(['C', 'P1', 'P2'])
m1 = df['STR'].eq('C').groupby([*df[c].values.T]).transform('any')
m2 = df['STR'].mask(~m).groupby([*df[c].values.T]).transform('nunique').ge(2)

df = df[m & m1 & m2].sort_values('POS', ignore_index=True).drop(['INT', 'STR'], 1)

解释

Extract通过使用带有正则表达式模式的str.extractINTSTR列进行排序

>>> df[['INT','STR']]

    INT STR
0   003   C
1   003  P1
2   003  P1
3   003  P1
4   004   C
5   004  P1
6   004  P2
7   003   C
8   003  P2
9   003  P1
10  003   C
11  003  P1
12  003  P2
13  003   C
14  003  P1
15  004   C
16  004  P2
17  001   C
18  001  P1

使用isin创建布尔掩码,以检查提取列STR仅包含值CP1P2的情况

>>> m

0     True
1     True
2     True
3     True
4     True
5     True
6     True
7     True
8     True
9     True
10    True
11    True
12    True
13    True
14    True
15    True
16    True
17    True
18    True
Name: STR, dtype: bool

STR列与C进行比较以创建布尔掩码,然后将此掩码分组到['CHROM', 'POS', 'REF', 'ALT', 'INT']列上,并使用any进行转换以创建布尔掩码m1

>>> m1
0      True
1     False
2     False
3     False
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13     True
14     True
15     True
16     True
17     True
18     True
Name: STR, dtype: bool

屏蔽列STR中的值,其中布尔屏蔽m1False,然后将该屏蔽列按['CHROM', 'POS', 'REF', 'ALT', 'INT']分组,并使用nunique进行转换,然后与ge链接以创建布尔屏蔽m2

>>> m2

0     False
1     False
2     False
3     False
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13     True
14     True
15     True
16     True
17     True
18     True
Name: STR, dtype: bool

现在使用掩码mm1m2中的logical and,并使用它来过滤数据帧中所需的行

>>> df[m & m1 & m2].sort_values('POS', ignore_index=True).drop(['INT', 'STR'], 1)

   Sample  CHROM        POS REF ALT
0    003C   chr1     125895   T   A
1   003P1   chr1     125895   T   A
2    004C  chr11    1163940   C   G
3   004P1  chr11    1163940   C   G
4   004P2  chr11    1163940   C   G
5    004C  chr11    2587895   C   G
6   004P2  chr11    2587895   C   G
7    003C  chr11    5986513   G   A
8   003P2  chr11    5986513   G   A
9   003P1  chr11    5986513   G   A
10   001C   chr9   14587952   T   C
11  001P1   chr9   14587952   T   C
12   003C   chr1  248650751   T   A
13  003P1   chr1  248650751   T   A
14  003P2   chr1  248650751   T   A

相关问题 更多 >

    热门问题