从数据框中检索行,以便使用列表

时间:2016-06-16 18:43:10

标签: python pandas filter dataframe

我有一个数据帧df:

df:  
    chr          gene_name

    1           ARF3
    1           ABC
    1           ARF3,ENSG123
    1           ENSG1245,ARF3, ENSG89
    1           ENSG,ARF3
    1           ANG
    2           XVY
    2           PQR
    3           RST
    4           TAC 

gene_list

gene_list = ['ARF3','ABC' ]

现在,我需要从数据框(df)中获取基因名称与gene_list中的元素完全匹配的行。

所以,我试过了:

df2 = df1[df.gene_name.isin(gene_list)]

我检索到:         chr gene_name

    1           ARF3
    1           ABC

但我期待的是:         chr gene_name

     1           ARF3
     1           ABC
     1           ARF3, ENSG123
     1           ENSG1245,ARF3, ENSG89
     1           ENSG,ARF3
     1           ABC

所以基本上是数据框中的所有行,其中gene_list中的元素是数据框中gene_name的子字符串。

我想过使用".contains()"如果我正在寻找另一种方式,数据框中的gene_name将成为gene_list中元素的子字符串。

所有帮助赞赏

3 个答案:

答案 0 :(得分:2)

str.splitDataFrame.isinboolean indexing的另一个更简单的解决方案:

gene_list = ['ARF3', 'ABC']

df1 = df.gene_name.str.split(',', expand=True)
mask = df1.isin(gene_list)
s = df1[mask].dropna(how='all').apply(lambda x: x[x.first_valid_index()], axis=1)
s.name='new'

print (s)
0    ARF3
1     ABC
2    ARF3
3    ARF3
4    ARF3
Name: new, dtype: object

print (df.join(s).dropna(subset=['new']))
   chr             gene_name   new
0    1                  ARF3  ARF3
1    1                   ABC   ABC
2    1          ARF3,ENSG123  ARF3
3    1  ENSG1245,ARF3,ENSG89  ARF3
4    1             ENSG,ARF3  ARF3

另一种解决方案:

gene_list = ['ARF3', 'ABC']

#new dafarame with splited values
df1 = df.gene_name.str.split(',', expand=True)
#mask - True where is desired value
mask = df1.isin(gene_list)
#find first valid value in dataframe and create serie by these values
s = df1[mask].dropna(how='all').apply(lambda x: x[x.first_valid_index()], axis=1)
s.name='new'
print (s)
0    ARF3
1     ABC
2    ARF3
3    ARF3
4    ARF3
Name: new, dtype: object

#join series to filtered dataframe - create new column
print (df[mask.any(1)].join(s))
   chr             gene_name   new
0    1                  ARF3  ARF3
1    1                   ABC   ABC
2    1          ARF3,ENSG123  ARF3
3    1  ENSG1245,ARF3,ENSG89  ARF3
4    1             ENSG,ARF3  ARF3

答案 1 :(得分:1)

解决方案

df = pd.DataFrame([[1, 'ARF3'],
                   [1, 'ABC'],
                   [1, 'ARF3,ENSG123'],
                   [1, 'ENSG1245,ARF3,ENSG89'],
                   [1, 'ENSG,ARF3'],
                   [1, 'ANG'],
                   [2, 'XVY'],
                   [2, 'PQR'],
                   [3, 'RST'],
                   [4, 'TAC']], columns=['chr', 'gene_name'])

gene_list = ['ARF3', 'ABC']

df.loc[df.gene_name.str.split(',', expand=True).isin(gene_list).any(1)]

   chr             gene_name
0    1                  ARF3
1    1                   ABC
2    1          ARF3,ENSG123
3    1  ENSG1245,ARF3,ENSG89
4    1             ENSG,ARF3

解释

  • str.split(',', expand=True)按逗号分割,创建新的DataFrame
  • isin(gene_list)我希望这个很明显
  • any(1)告诉我上面系列中的任何值是否在列表中。

答案 2 :(得分:0)

尝试:

X3,Y3,X4,Y4

如果您有更多问题,请告诉我。