Pandas 熊猫。loc无键错误

Pandas 熊猫。loc无键错误,pandas,Pandas,我想要两种方法都不失败的东西 >>> pd.DataFrame([1], index=['1']).loc['2'] # KeyError >>> pd.DataFrame([1], index=['1']).loc[['2']] # KeyError >>> pd.DataFrame([1], index=['1']).loc[['1','2']] # Succeeds, as in the answer below. 有没有像l

我想要两种方法都不失败的东西

>>> pd.DataFrame([1], index=['1']).loc['2']  # KeyError
>>> pd.DataFrame([1], index=['1']).loc[['2']]  # KeyError
>>> pd.DataFrame([1], index=['1']).loc[['1','2']]  # Succeeds, as in the answer below. 

有没有像
loc
这样的函数可以优雅地处理这个问题,或者用其他方式表达这个查询

@AlexLenail评论的更新 这是一个公平的点,这将是缓慢的大名单。我做了更多的挖掘,并且
交叉点
方法可用于
索引
和列。我不确定算法的复杂性,但从经验上看,它要快得多

你可以这样做

>>> pd.DataFrame([1], index=['1']).loc['2']  # KeyError
>>> pd.DataFrame([1], index=['1']).loc[['2']]  # KeyError
或者像你的例子

good_keys = df.index.intersection(all_keys)
df.loc[good_keys]
下面是一个小实验

df = pd.DataFrame([1], index=['1'])
df.loc[df.index.intersection(['2'])]
原始答案

我不确定pandas是否有一个内置函数来处理这个问题,但是您可以使用Python列表理解来过滤有效的索引

给定数据帧
df2

n = 100000

# Create random values and random string indexes
# have the bad indexes contain extra values not in DataFrame Index
rand_val = np.random.rand(n)
rand_idx = []
for x in range(n):
    rand_idx.append(str(x))

bad_idx = []
for x in range(n*2):
    bad_idx.append(str(x))

df = pd.DataFrame(rand_val, index=rand_idx)
df.head()

def get_valid_keys_list_comp():
    # Return filtered DataFrame using list comprehension to filter keys
    vkeys = [key for key in bad_idx if key in df.index.values]
    return df.loc[vkeys]

def get_valid_keys_intersection():
    # Return filtered DataFrame using list intersection() to filter keys
    vkeys = df.index.intersection(bad_idx)
    return df.loc[vkeys]

%%timeit 
get_valid_keys_intersection()
# 64.5 ms ± 4.53 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit 
get_valid_keys_list_comp()
# 6.14 s ± 457 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
您可以使用此选项筛选索引查询

           A    B       C   D    F
test    1.0 2013-01-02  1.0 3   foo
train   1.0 2013-01-02  1.0 3   foo
test    1.0 2013-01-02  1.0 3   foo
train   1.0 2013-01-02  1.0 3   foo

如果您使用
df2.columns
而不是
df2.index.values

这对我来说似乎很好,那么这也适用于列。我正在运行0.20.3版的Python 3.5

keys = ['test', 'train', 'try', 'fake', 'broken']
valid_keys = [key for key in keys if key in df2.index.values]
df2.loc[valid_keys]
或者,如果要排除NaN行:

import numpy as np
import pandas as pd

# Create dataframe
data = {'distance': [0, 300, 600, 1000],
        'population': [4.8, 0.7, 6.4, 2.9]}
df = pd.DataFrame(data, index=['Alabama','Alaska','Arizona','Arkansas'])

keys = ['Alabama', 'Alaska', 'Arizona', 'Virginia']

# Create a subset of the dataframe.
df.loc[keys]
          distance  population
Alabama        0.0         4.8
Alaska       300.0         0.7
Arizona      600.0         6.4
Virginia       NaN         NaN
此页面提供了解决方案:


在[8]中:pd.DataFrame([1],index=['1']).reindex(['2'])
出[8]:
0
2楠

我找到了一个替代方案(前提是事先检查df.empty)。你可以这样做


df[df.index=='2']->返回具有匹配值的数据帧或空数据帧。

使用@binjip答案中的示例数据帧:

将numpy导入为np
作为pd进口熊猫
#创建数据帧
数据={'distance':[03006001000],
“人口”:[4.8,0.7,6.4,2.9]}
df=pd.DataFrame(数据,索引=[‘阿拉巴马’、‘阿拉斯加’、‘亚利桑那’、‘阿肯色州】)
基斯=['阿拉巴马州'、'阿拉斯加州'、'亚利桑那州'、'弗吉尼亚州']
从数据帧中获取匹配的记录NB:数据帧索引必须是唯一的,才能工作

df.reindex(键)
如果要忽略缺少的关键点:

df.reindex(df.index.intersection(键))

是的,这个解决方案也很有效,但是如果您碰巧已经有了包含all
NaN
的行,它们将被无意中删除。我得到一个未来警告:“传递list like to.loc或[]以及任何缺少的标签将在将来引发KeyError,您可以使用.reindex()作为替代。”@TalWeiss你使用的是哪种版本的熊猫?@stevepastelan 0.24.2尽管这样做有效,但熊猫本身没有办法做到这一点吗?如果你看的是一张大桌子和一张大名单,这可能会非常昂贵(n**2)@AlexLenail good think;我花了一点时间挖掘并找到了另一种解决方案。我希望有一个用于
df.loc[df.index.intersection(list)]的宏。
似乎扫描列要比键:值索引检索慢得多?对于112k行数据帧,操作员比较平均时间约为
508µs
,而尝试/例外方法的速度相当快,约为
35.7µs
df.loc[keys].dropna()
          distance  population
Alabama        0.0         4.8
Alaska       300.0         0.7
Arizona      600.0         6.4
          distance  population
Alabama        0.0         4.8
Alaska       300.0         0.7
Arizona      600.0         6.4
Virginia       NaN         NaN
         distance  population
Alabama         0         4.8
Alaska        300         0.7
Arizona       600         6.4