熊猫:解析两个条件问题

时间:2018-01-09 14:52:36

标签: python pandas conditional

我有一个名为transcripts的数据框和一个名为genes的numpy数组。 genes只是geneID transcripts列的唯一值。对于genes的每个值,我希望找到最长的记录(transcriptLength中的transcripts列),并从transcripts数据框中删除所有其他记录。我以为我会使用下面的代码,然后循环遍历genes

#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的成绩单。我之前已经进行了子集化(并查看了其他类似的堆栈问题),我的代码似乎是正确的,所以我无法理解问题是什么。这里有什么东西不见了吗?

FYI geneID列是字符串,而transcriptLength列是整数。 以下是transcripts的第一行:

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也已删除,这是不正确的。

2 个答案:

答案 0 :(得分:2)

您需要z=df.loc[(df['geneID'] != 'g2') | (df['transcriptLength'] == y)].copy(),即您需要'或'而不是'和'。所以g2以外的任何东西,你保留,如果它在g2中,你希望它不具有transcriptLength y。正如目前所写,你拒绝任何东西,除非它不在g2中并且没有那个transcriptLength。

答案 1 :(得分:2)

您的布尔逻辑不正确。您可以将其更改为:

z=df.loc[~((df['geneID'] == 'g2') & (df['transcriptLength'] != y))].copy()

~not运算符的位置。该逻辑表示丢弃geneID == g2transcriptLength != y的所有行。

您希望将这些行保留在以下两个条件下:

(df['geneID'] == 'g2') & (df['transcriptLength'] == y)
df['geneID'] != 'g2'

您编写的代码正在消除df['geneID'] == 'g2'所有行。

如果您仍然不清楚,请尝试写出真相表。