найти имя гена из списка в датафрейм - PullRequest
0 голосов
/ 09 мая 2018

Я действительно должен знать, получил ли я какой-нибудь ген, если мой результат, для этого у меня есть один список с именами моих генов и фрейм данных с теми же самыми:

Например,

liste["gene1","gene2","gene3","gene4","gene5"]

и датафрейм:

name1          name2
gene1_0035     gene1_0042
gene56_0042    gene56_0035
gene4_0042     gene4_0035
gene2_0035     gene2_0042
gene57_0042    gene57_0035

тогда я сделал:

df=pd.read_csv("dataframe_not_max.txt",sep='\t')
df=df.drop(columns=(['Unnamed: 0', 'Unnamed: 0.1']))
#print(df)
print(list(df.columns.values))
name1=df.ix[:,1]
name2=df.ix[:,2]


liste=[]
for record in SeqIO.parse(data, "fasta"):
    liste.append(record.id)

print(liste)
print(len(liste))

count=0
for a, b in zip(name1, name2):

    if a in liste:
        count+=1

    if b in liste: 
        count+=1
print(count)

И я хочу знать, сколько раз я нахожу ген в ма датафрейме из моего списка, но у него нет точно одинакового идентификатора, поскольку в списке нет _number после имени гена, тогда если я в листе не воссоздает ID.

Можно ли сказать что-то вроде:

if a without_number in liste: 

В приведенном выше примере это будет: count = 3, потому что только ген 1,2 и 4 присутствуют как в списке, так и в datafra.

Вот более сложный пример, чтобы увидеть, действительно ли ваш скрипт работает для моих данных: Допустим, у меня есть датафрейм такой:

  cluster_name  qseqid  sseqid  pident_x
15  cluster_016607  EOG090X00GO_0035_0035   EOG090X00GO_0042_0035
16  cluster_016607  EOG090X00GO_0035_0035   EOG090X00GO_0042_0042
18  cluster_016607  EOG090X00GO_0035_0042   EOG090X00GO_0042_0035
19  cluster_016607  EOG090X00GO_0035_0042   EOG090X00GO_0042_0042
29  cluster_015707  EOG090X00LI_0035_0035   EOG090X00LI_0042_0042
30  cluster_015707  EOG090X00LI_0035_0035   EOG090X00LI_0042_0035
34  cluster_015707  EOG090X00LI_0042_0035   g1726.t1_0035_0042
37  cluster_015707  EOG090X00LI_0042_0042   g1726.t1_0035_0042

и список: ["EOG090X00LI_","EOG090X00GO_","EOG090X00BA_"]

здесь я получаю 6, но я должен получить 2, потому что у меня есть только 2 последовательности в моих данных EOG090X00LI и EOG090X00GO

на самом деле, здесь я хочу сосчитать, когда последовательность присутствует только тогда, когда она появляется один раз, даже если она для примера: EOG090X00LI vs seq123454

Не знаю, понятно ли?

Я использовал для примера:

df=pd.read_csv("test_busco_augus.csv",sep=',')
#df=df.drop(columns=(['Unnamed: 0', 'Unnamed: 0.1']))
print(df)
print(list(df.columns.values))
name1=df.ix[:,3]
name2=df.ix[:,4]

liste=["EOG090X00LI_","EOG090X00GO_","EOG090X00BA_"]

print(liste)


#get boolean mask for each column    
m1 = name1.str.contains('|'.join(liste))
m2 = name2.str.contains('|'.join(liste))

#chain masks and count Trues

a = (m1 & m2).sum()
print (a)

Ответы [ 4 ]

0 голосов
/ 09 мая 2018

Использование isin

df.apply(lambda x : x.str.split('_').str[0],1).isin(l).sum(1).eq(2).sum()
Out[923]: 3

Добавление value_counts

df.apply(lambda x : x.str.split('_').str[0],1).isin(l).sum(1).value_counts()
Out[925]: 
2    3
0    2
dtype: int64
0 голосов
/ 09 мая 2018

Я думаю, что нужно:

#add _ to end of values
liste =  [record.id + '_' for record in SeqIO.parse(data, "fasta")]
#liste = ["gene1_","gene2_","gene3_","gene4_","gene5_"]

#get boolean mask for each column    
m1 = df['name1'].str.contains('|'.join(liste))
m2 = df['name2'].str.contains('|'.join(liste))

#chain masks and count Trues
a = (m1 & m2).sum()
print (a)
3

EDIT:

liste=["EOG090X00LI","EOG090X00GO","EOG090X00BA"]

#extract each values before _, remove duplicates and compare by liste   
a = name1.str.split('_').str[0].drop_duplicates().isin(liste)
b = name2.str.split('_').str[0].drop_duplicates().isin(liste)

#compare a with a for equal and sum Trues
c = a.eq(b).sum()
print (c)
2
0 голосов
/ 09 мая 2018

С поправкой на обновленный OP

найти, где сумма равна 1

df.stack().str.split('_').str[0].isin(liste).sum(level=0).eq(1).sum()

2

Старый ответ

stack и str accessor

Вы можете использовать split на '_', чтобы очистить первую часть, а затем использовать isin, чтобы определить членство.Я также использую stack и all с параметром level=0, чтобы увидеть, является ли членство True для всех столбцов

df.stack().str.split('_').str[0].isin(liste).all(level=0).sum()

3

applymap

df.applymap(lambda x: x.split('_')[0] in liste).all(1).sum()

3

sum / all с генераторами

sum(all(x.split('_')[0] in liste for x in r) for r in df.values)

3

Два много map

sum(map(lambda r: all(map(lambda x: x.split('_')[0] in liste, r)), df.values))

3
0 голосов
/ 09 мая 2018

Вы можете преобразовать ваш фрейм данных в серию (объединяющую все столбцы), используя stack(), затем найти имена генов в liste, за которым следует подчеркивание _, используя Series.str.match():

s = df.stack()

sum([s.str.match(i+'_').any() for i in liste])

Что возвращает 3

Подробности:

df.stack() возвращает следующее Series:

0  name1     gene1_0035
   name2     gene1_0042
1  name1    gene56_0042
   name2    gene56_0035
2  name1     gene4_0042
   name2     gene4_0035
3  name1     gene2_0035
   name2     gene2_0042
4  name1    gene57_0042
   name2    gene57_0035

Поскольку все ваши гены в этой серии сопровождаются подчеркиванием, вам просто нужно посмотреть, входит ли в эту серию gene_name, за которой следует _. s.str.match(i+'_').any() возвращает True, если это так. Затем вы получаете сумму True значений, и это ваш счет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...