Pandas:获取重复的索引

Posted

技术标签:

【中文标题】Pandas:获取重复的索引【英文标题】:Pandas: Get duplicated indexes 【发布时间】:2013-12-10 12:52:46 【问题描述】:

给定一个数据框,我想获取重复的索引,这些索引在列中没有重复的值,并查看哪些值不同。

具体来说,我有这个数据框:

import pandas as pd
wget https://www.dropbox.com/s/vmimze2g4lt4ud3/alt_exon_repeatmasker_intersect.bed
alt_exon_repeatmasker = pd.read_table('alt_exon_repeatmasker_intersect.bed', header=None, index_col=3)

In [74]: alt_exon_repeatmasker.index.is_unique
Out[74]: False

并且有些索引在第 9 列有重复值(这个位置的 DNA 重复元素的类型),我想知道各个位置的重复元素的不同类型是什么(每个索引 = 一个基因组位置)。

我猜这需要某种groupby 并希望一些groupby ninja 可以帮助我。

为了进一步简化,如果我们只有索引和重复类型,

genome_location1    MIR3
genome_location1    AluJb
genome_location2    Tigger1
genome_location3    AT_rich

所以我想查看所有重复索引及其重复类型的输出,例如:

genome_location1    MIR3
genome_location1    AluJb

编辑:添加玩具示例

【问题讨论】:

嗨,通常最好的做法是尽可能简化问题并创建带有输入和所需输出的玩具示例。这样的问题得到了更快的回答,对未来的读者很有用。 【参考方案1】:
>>> df[df.groupby(level=0).transform(len)['type'] > 1]
                   type
genome_location1   MIR3
genome_location1  AluJb

【讨论】:

或者,非常类似地,filter 就像这样:df.groupby(level=0).filter(lambda x: len(x) > 1)['type']。将比转换和屏蔽更快。 @DanAllan 太好了,您可以添加另一个答案并且 OP 会接受吗? 谢谢!我会接受这个答案,因为它可以保证与pandas 的当前版本一起使用。 我认为这是正确的选择。有用的对话,无处不在。【参考方案2】:
df.groupby(level=0).filter(lambda x: len(x) > 1)['type']

我们为这种操作添加了filter 方法。您也可以使用遮罩和转换来获得等效结果,但这更快,并且更具可读性。

重要:

filter 方法是在 0.12 版本中引入的,但它无法在具有非唯一索引的 DataFrames/Series 上工作。该问题 - 以及与系列上的 transform 相关的问题 - 已在 0.13 版中得到修复,现在应该随时发布。

显然,非唯一索引是这个问题的核心,所以我应该指出,在您拥有 pandas 0.13 之前,这种方法将无济于事。与此同时,transform 解决方法是可行的方法。请注意,如果您在具有非唯一索引的 Series 上尝试这样做,它也会失败。

没有充分的理由不将filtertransform 应用于非唯一索引;只是一开始实施得不好。

【讨论】:

这个对我不起作用,我什至试过df.groupby(level=0).filter(lambda x: True),收到Exception: Reindexing only valid with uniquely valued Index objects 好收获!这种特殊用途遇到了一个为 v0.13 修复的错误,显然许多用户没有。答案已更新。 谢谢!我仍然在 0.12 上,并且会坚持到 v0.13 完全发布,因为我正在共享一个代码库,virtualenv 把一切都搞砸了。升级后我会切换到这个!谢谢!我已经使用pandas 一年了,但我仍然在思考groupbys 在查看效率时,我怀疑这是否比 df.set_index('type').index.duplicates 更快 - 因为它必须遍历每个组才能执行,而不是“从组外”查看它。 我不知道index.duplicates。将其添加为答案;那肯定更好。【参考方案3】:

更简洁:

df[df.groupby(level=0).type.count() > 1]

仅供参考:多索引:

df[df.groupby(level=[0,1]).type.count() > 1]

【讨论】:

【参考方案4】:

也很有用,非常简洁:

df[df.index.duplicated()]

请注意,这只会返回其中一个重复的行,因此要查看所有重复的行,您需要这样:

df[df.index.duplicated(keep=False)]

【讨论】:

docs中有一个很好的例子 使用示例:1.idx = pd.Index(['lama', 'cow', 'lama', 'beetle', 'lama']) 2.idx.duplicated() 3.array([False, False, True, False, True])【参考方案5】:

更快更好:

df.index.get_duplicates()

【讨论】:

不错的答案,但它带有对熊猫 0.23.4 'get_duplicates' is deprecated and will be removed in a future release. You can use idx[idx.duplicated()].unique() instead987654322@的未来警告【参考方案6】:

截至 2018 年 9 月 21 日,Pandas 表示 FutureWarning: 'get_duplicates' is deprecated and will be removed in a future release,而是建议以下内容:

df.index[df.index.duplicated()].unique()

【讨论】:

【参考方案7】:

这为您提供索引值以及重复行的预览

def dup_rows_index(df):
  dup = df[df.duplicated()]
  print('Duplicated index loc:',dup[dup == True ].index.tolist())
  return dup

【讨论】:

以上是关于Pandas:获取重复的索引的主要内容,如果未能解决你的问题,请参考以下文章

使用索引值列表对 pandas 多索引数据框进行切片 [重复]

在 Pandas DataFrame 中删除重复索引的最快方法 [重复]

从 pd.DataFrame [重复] 获取列标签索引的有效方法

Pandas +不按索引删除特定行[重复]

pandas中基于MultiIndex的索引[重复]

Pandas 在 groupby 和 nlargest 之后创建额外(重复)索引