检查Pandas数据框索引中是否存在某个值。

221

我相信有一种明显的方法可以做到这一点,但现在想不出什么巧妙的方法。

基本上,我想要得到TrueFalse来判断一个值是否存在于pandas df索引中,而不是引发异常。

import pandas as pd
df = pd.DataFrame({'test':[1,2,3,4]}, index=['a','b','c','d'])
df.loc['g']  # (should give False)

我现在正在使用的是以下内容

sum(df.index == 'g')

1
任何(df.index == 'g')怎么样? - luffe
7个回答

368

这应该可以解决问题

'g' in df.index

9
当多个条目共享相同的索引值时,这似乎无法正常工作。 - MaximG
2
@MaximG 你是什么意思?这对于非唯一索引也适用。 - joris
1
还适用于多索引。如果您的索引长度为n,则可以检查任意长度为1..n的元组。 - Minh Triet
3
对于其他需要使用列标题而不是索引定义数据框的用户,可能需要使用 'g' in df.columns。例如:df = pandas.DataFrame({'test':[1,2,3,4]}, columns=['a','b','c','d'])。请注意,翻译过程中不会添加解释或其他内容,并且保持原文意思不变。 - Tahlor
11
这是常数时间还是线性时间? - Lokesh
显示剩余2条评论

50

多重索引和单一索引有些不同。下面是一些适用于多重索引数据框的方法。

df = pd.DataFrame({'col1': ['a', 'b','c', 'd'], 'col2': ['X','X','Y', 'Y'], 'col3': [1, 2, 3, 4]}, columns=['col1', 'col2', 'col3'])
df = df.set_index(['col1', 'col2'])

in df.index 仅在检查单个索引值时对第一级有效。

'a' in df.index     # True
'X' in df.index     # False

检查 df.index.levels 是否存在其他级别。

'a' in df.index.levels[0] # True
'X' in df.index.levels[1] # True

df.index 中查找索引组合元组。

('a', 'X') in df.index  # True
('a', 'Y') in df.index  # False

45

仅供参考,因为这是我正在寻找的内容,您可以通过追加".values"方法来测试值或索引中的存在性,例如:

g in df.<your selected field>.values
g in df.index.values

我发现加上".values"将数据转化为简单的列表或者ndarray,使存在性检查和其他Python工具的运行更加顺畅。只是想为大家提供这个提示。


但是 AttributeError: 'DataFrame' 对象没有属性 'field'。 - Gank
2
嗨Gank。 "field"应该向您展示可以将".values"方法应用于数据框的各个字段,例如列或选定的列。 ".index"是将"field"替换为实际可用字段的示例 :) 我想这可能更清晰... - Ezekiel Kruglick
2
这真的很有帮助。我有一个分层案例,其中in g in df.index 返回 true,而 in g in df.index.values 返回 false。有趣。 - watsonic
@watsonic - 有一个需要注意的地方是要看看它们是否由于层次结构而返回元组。一定要查看两者输出的内容(例如在ipython或命令行中),以确保您了解正在进行比较的内容。使用分层索引的另一件事是df.index.get_level_values(<level name>),以使事情更易于理解-当然取决于您的应用程序。 - Ezekiel Kruglick
3
这将显著增加查找时间,因为您正在遍历列表而不是使用 pandas 优化的搜索索引器。对于格式问题表示歉意,data = [{'a': random.random(), 'b': random.randint(0, 10), 'c': i} for i in range(10000)] data2 = [{'a': random.random(), 'b': random.randint(0, 10), 'c': i} for i in range(100)] df1 = pd.DataFrame.from_records(data) df2 = pd.DataFrame.from_records(data2) timeit 99999 in df2.index # 442ns timeit 99999 in df1.index # 476ns timeit 99999 in df2.index.values # 3310ns timeit 99999 in df1.index.values # 63900ns - G.S

4
以下代码不打印布尔值,但允许按索引对数据框进行子集处理......我明白这可能不是解决问题的最有效方法,但我(1)喜欢这种读法和(2)可以轻松地对 df1 索引存在于 df2 中的子集进行处理:
df3 = df1[df1.index.isin(df2.index)]

或者在 df2 中没有 df1 的索引...

df3 = df1[~df1.index.isin(df2.index)]

2
最初的回答:使用数据框DataFrame:df_data
>>> df_data
  id   name  value
0  a  ampha      1
1  b   beta      2
2  c     ce      3

我尝试了:

>>> getattr(df_data, 'value').isin([1]).any()
True
>>> getattr(df_data, 'value').isin(['1']).any()
True

but:

>>> 1 in getattr(df_data, 'value')
True
>>> '1' in getattr(df_data, 'value')
False

最初的回答
这太有趣了 :D

isin 不会检查数据类型。尝试使用 df['value'].isin([True]).any(),它也会返回 True,因为它与 1 匹配。True -> 1 - Mohamed Thasin ah

1
df = pandas.DataFrame({'g':[1]}, index=['isStop'])

#df.loc['g']

if 'g' in df.index:
    print("find g")

if 'isStop' in df.index:
    print("find a") 

什么是isStop? - Nabin

0

我喜欢使用:

if 'value' in df.index.get_level_values(0):
    print(True)

get_level_values 方法非常好用,因为它允许您获取索引中的值,无论您的索引是简单的还是复合的。

如果您的数据框只有一个索引[或者您想要检查多个索引级别中的第一个索引],请使用0(零)。使用1表示第二个索引,以此类推...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接