Python 熊猫:使用两个条件进行解析问题
我有一个名为Python 熊猫:使用两个条件进行解析问题,python,pandas,conditional,Python,Pandas,Conditional,我有一个名为转录本的数据框和一个名为基因的numpy数组genes只是转录本的geneID列的唯一值。对于基因的每个值,我想在转录本中找到最长的转录本(列转录本长度),并从转录本数据框中删除所有其他值。我想我会使用下面的代码,然后通过基因循环 #subset transcripts, leaving only rows with id of genes[20000] x=transcripts.loc[(transcripts['geneID'] == genes[20000])].copy()
转录本的数据框和一个名为基因的numpy数组genes
只是转录本的geneID
列的唯一值。对于基因
的每个值,我想在转录本
中找到最长的转录本(列转录本长度
),并从转录本
数据框中删除所有其他值。我想我会使用下面的代码,然后通过基因
循环
#subset transcripts, leaving only rows with id of genes[20000]
x=transcripts.loc[(transcripts['geneID'] == genes[20000])].copy()
#Find longest transcript
y = x.transcriptLength.max()
#subset transcripts df to remove all transcripts that are shorter for that gene
z=transcripts.loc[(transcripts['geneID'] != genes[20000]) & (transcripts['transcriptLength'] != y)].copy()
然而,出于某种原因,该代码删除了所有带有该geneID
的转录本。我以前也这样做过(并研究了其他类似的堆栈问题),我的代码似乎是正确的,所以我无法理解问题是什么。这里少了什么东西吗
FYIgeneID
列是字符串,而transcriptLength
列是整数。
以下是成绩单的第一行:
geneID transcriptID transcriptLength
0 ENSPTRG00000042638 ENSPTRT00000076395 71
1 ENSPTRG00000042646 ENSPTRT00000076407 949
2 ENSPTRG00000042654 ENSPTRT00000076381 69
3 ENSPTRG00000042645 ENSPTRT00000076409 1558
4 ENSPTRG00000042644 ENSPTRT00000076406 75
编辑:下面是一个玩具示例,我们试图找到基因g2的最长转录本,并删除任何较短的转录本:
#Create dataframe (akin to transcripts above)
d = {'transcriptID' : pd.Series(['t1', 't2', 't3', 't4'], index=['a', 'b', 'c', 'd']),
'geneID' : pd.Series(['g1', 'g2', 'g3', 'g2'], index=['a', 'b', 'c', 'd']),
'transcriptLength' : pd.Series([212, 715, 213, 984], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
#Subset df to include only values where geneID = g2
x=df.loc[(df['geneID'] == 'g2')].copy()
#Find max transcriptLength
y = x.transcriptLength.max()
#Subset main df to remove all g2 values except the maximum one
z=df.loc[(df['geneID'] != 'g2') & (df['transcriptLength'] != y)].copy()
这将产生:
geneID transcriptID transcriptLength
a g1 t1 212
c g3 t3 213
它已删除了geneID
为g2
的所有行。它只应该删除行b
(该行在所有g2
geneIDs中的值最低)。行d
也已被删除,这是不正确的。您需要z=df.loc[(df['geneID'!='g2')|(df['transcriptLength']==y)].copy()
,即您需要'or'而不是'and'。所以g2之外的任何东西,你保留,如果它在g2中,你希望它没有转录长度y。正如目前所写的,您拒绝任何内容,除非它不在g2中并且没有该转录本长度。您需要z=df.loc[(df['geneID'!='g2')|(df['transcriptLength']==y)].copy()
,即您想要'or'而不是'and'。所以g2之外的任何东西,你保留,如果它在g2中,你希望它没有转录长度y。正如目前所写,您拒绝任何内容,除非它不在g2中并且没有该长度。您的布尔逻辑不正确。您可以将其更改为:
z=df.loc[~((df['geneID'] == 'g2') & (df['transcriptLength'] != y))].copy()
其中,~
是非
运算符。此逻辑表示放弃geneID==g2
和transcriptLength!=y
您希望在以下两种情况下保留行:
(df['geneID'] == 'g2') & (df['transcriptLength'] == y)
df['geneID'] != 'g2'
您编写的代码正在删除df['geneID']='g2'
中的所有行
如果您仍然不清楚,请尝试写出真值表。您的布尔逻辑不正确。您可以将其更改为:
z=df.loc[~((df['geneID'] == 'g2') & (df['transcriptLength'] != y))].copy()
其中,~
是非
运算符。此逻辑表示放弃geneID==g2
和transcriptLength!=y
您希望在以下两种情况下保留行:
(df['geneID'] == 'g2') & (df['transcriptLength'] == y)
df['geneID'] != 'g2'
您编写的代码正在删除df['geneID']='g2'
中的所有行
如果你还不清楚,试着写出真相表。是因为你有z=…!=基因[20000])&…
你的意思是z=…=基因[20000])&…
?但我正在尝试子集,以便只有转录本不是基因[20000],也不是该基因的最大长度?所以我需要基因[20000]),否则我只剩下我应该删除的行,而不是我想保留的行。我不确定我是否遵循。你说“出于某种原因,该代码删除了所有带有该geneID的转录本”?我认为您需要提供一个最简单的工作示例:一个小样本输入和所需的输出。谢谢。是因为你有z=…!=基因[20000])&…
你的意思是z=…=基因[20000])&…
?但我正在尝试子集,以便只有转录本不是基因[20000],也不是该基因的最大长度?所以我需要基因[20000]),否则我只剩下我应该删除的行,而不是我想保留的行。我不确定我是否遵循。你说“出于某种原因,该代码删除了所有带有该geneID的转录本”?我认为您需要提供一个最简单的工作示例:一个小样本输入和所需的输出。谢谢,谢谢,这几乎奏效了。我将第二条语句更改为==:z=df.loc[(df['geneID']!='g2')|(df['transcriptLength']==y)]。copy()否则将被拒绝的语句将被保留。@spiral01哦,非常正确,我已编辑了答案以反映这一更改谢谢,这几乎有效。我将第二条语句更改为==:z=df.loc[(df['geneID']!='g2')|(df['transcriptLength']==y)]。copy()否则保留的是将被拒绝的语句。@spiral01哦,非常正确,我已编辑了答案以反映该更改抱歉~?此外,此语句更改初始数据帧的顺序。有什么原因吗?我更新了答案来解释~
。我对订货情况不太确定。另外,我认为您不需要.copy()
对不起,~做什么?此外,此语句更改初始数据帧的顺序。有什么原因吗?我更新了答案来解释~
。我对订货情况不太确定。另外,我认为您不需要.copy()