Pandas: 解析两个条件问题
Pandas: Parsing with two conditions issue
我有一个名为 transcripts
的数据框和一个名为 genes
的 numpy 数组。 genes
只是 transcripts
的 geneID
列的唯一值。对于 genes
的每个值,我想找到最长的转录本(transcripts
中的 transcriptLength
列),并从 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
的成绩单。我以前像这样子集(并查看了其他类似的堆栈问题)并且我的代码似乎是正确的所以我无法理解问题是什么。这里有什么遗漏吗?
仅供参考 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
geneID 中的最低值)。 d
行也已删除,这是不正确的。
您需要 z=df.loc[(df['geneID'] != 'g2') | (df['transcriptLength'] == y)].copy()
,即您想要 'or' 而不是 'and'。所以 g2 之外的任何东西,你保留,如果它在 g2 中,你不希望它有 transcriptLength y。正如目前所写,你拒绝任何东西,除非它不在 g2 中并且没有那个 transcriptLength。
您的布尔逻辑不正确。您可以将其更改为:
z=df.loc[~((df['geneID'] == 'g2') & (df['transcriptLength'] != y))].copy()
其中 ~
是 not
运算符。此逻辑表示丢弃 geneID == g2
和 transcriptLength != y
.
的所有行
您希望在以下两种情况下保留行:
(df['geneID'] == 'g2') & (df['transcriptLength'] == y)
df['geneID'] != 'g2'
您编写的代码消除了 df['geneID'] == 'g2'
.
的所有行
如果你还不清楚,试着写出真值表。
我有一个名为 transcripts
的数据框和一个名为 genes
的 numpy 数组。 genes
只是 transcripts
的 geneID
列的唯一值。对于 genes
的每个值,我想找到最长的转录本(transcripts
中的 transcriptLength
列),并从 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
的成绩单。我以前像这样子集(并查看了其他类似的堆栈问题)并且我的代码似乎是正确的所以我无法理解问题是什么。这里有什么遗漏吗?
仅供参考 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
geneID 中的最低值)。 d
行也已删除,这是不正确的。
您需要 z=df.loc[(df['geneID'] != 'g2') | (df['transcriptLength'] == y)].copy()
,即您想要 'or' 而不是 'and'。所以 g2 之外的任何东西,你保留,如果它在 g2 中,你不希望它有 transcriptLength y。正如目前所写,你拒绝任何东西,除非它不在 g2 中并且没有那个 transcriptLength。
您的布尔逻辑不正确。您可以将其更改为:
z=df.loc[~((df['geneID'] == 'g2') & (df['transcriptLength'] != y))].copy()
其中 ~
是 not
运算符。此逻辑表示丢弃 geneID == g2
和 transcriptLength != y
.
您希望在以下两种情况下保留行:
(df['geneID'] == 'g2') & (df['transcriptLength'] == y)
df['geneID'] != 'g2'
您编写的代码消除了 df['geneID'] == 'g2'
.
如果你还不清楚,试着写出真值表。