在Pandas中访问错误的列标签时没有异常?

时间:2017-03-08 10:29:14

标签: python pandas dataframe

在某些情况下访问Pandas数据帧不会引起异常,即使列标签不存在也是如此。

我应该如何检查这些情况,以避免读错结果?

a = pd.DataFrame(np.zeros((5,2)), columns=['la', 'lb'])

a
Out[349]: 
    la   lb
0  0.0  0.0
1  0.0  0.0
2  0.0  0.0
3  0.0  0.0
4  0.0  0.0

a.loc[:, 'lc']  # Raised exception as expected.

a.loc[:, ['la', 'lb', 'lc']]  # Not expected.
Out[353]: 
    la   lb  lc
0  0.0  0.0 NaN
1  0.0  0.0 NaN
2  0.0  0.0 NaN
3  0.0  0.0 NaN
4  0.0  0.0 NaN

a.loc[:, ['la', 'wrong_lb', 'lc']]  # Not expected.
Out[354]: 
    la  wrong_lb  lc
0  0.0       NaN NaN
1  0.0       NaN NaN
2  0.0       NaN NaN
3  0.0       NaN NaN
4  0.0       NaN NaN

更新:有一个建议的重复问题(Safe label-based selection in DataFrame),但它是关于行选择的,我的问题是关于列选择。

1 个答案:

答案 0 :(得分:4)

看起来因为至少有一个列存在,它会返回一个放大的df作为reindex操作。

您可以定义一个用户func,用于验证将处理列是否存在的列。在这里,我从传入的iterable构造一个pandas Index对象,并调用intersection从现有的df返回公共值并传递给iterable:

In [80]:
def val_cols(cols):
    return pd.Index(cols).intersection(a.columns)
​
a.loc[:, val_cols(['la', 'lb', 'lc'])] 

Out[80]:
    la   lb
0  0.0  0.0
1  0.0  0.0
2  0.0  0.0
3  0.0  0.0
4  0.0  0.0

这也处理完全缺少的列:

In [81]:
a.loc[:, val_cols(['x', 'y'])] 

Out[81]:
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3, 4]

这也处理你的后一种情况:

In [83]:
a.loc[:, val_cols(['la', 'wrong_lb', 'lc'])]

Out[83]:
    la
0  0.0
1  0.0
2  0.0
3  0.0
4  0.0

<强>更新

如果你想测试是否所有都有效,你可以迭代列表中的每一列并附加duff列:

In [93]:
def val_cols(cols):
    duff=[]
    for col in cols:
        try:
            a[col]
        except KeyError:
            duff.append(col)
    return duff
invalid = val_cols(['la','x', 'y'])
print(invalid)

['x', 'y']