我有一个包含多列(即分层)索引的表,如下所示:
a = pd.DataFrame([
['a', 'x0', 'v', 1],
['a', 'x1', 'w', 2],
['b', 'x0', 'y', 3],
['b', 'x1', 'z', 4],
], columns = ['key1', 'key2', 'key3', 'val']).set_index(['key1', 'key2', 'key3'])
现在,我可以选择一个完整键列表,如下所示:
a.loc[[('a', 'x0', 'v'), ('b', 'x1', 'z')]]
返回预期结果,即具有两行(值1和4)的数据帧。
然而,当我尝试使用部分键时,如下所示:
a.loc[[('a', 'x0'), ('b', 'x1')]]
然后我得到正确的键,但val列显示所有NaN值。这里有什么问题?
同样,我可以选择第一级的几个键:
a.loc[['a', 'b']]
效果很好。当我尝试那些元组时:
a.loc[[('a',), ('b',)]]
然后我再次获得NaN值。
编辑:我希望从我输入的组合键开始输出,而不是切片,即使用:
a.loc[[('a', 'x0'), ('b', 'x1')]]
我想要这个输出:
val
key1 key2 key3
a x0 v 1
b x1 z 4
但我得到的是:
val
key1 key2 key3
a x0 v NaN
b x1 z NaN
所以,显然,选择了正确的指数,但为什么我没有得到任何价值?
答案 0 :(得分:0)
我到目前为止找到的唯一可能是:
pd.concat([a.loc[key] for key in [
('a', 'x0'), ('b', 'x1')
]], axis=0)
它看起来不是最佳的并且有点慢,但至少我得到了正确的结果。因此,如果您有更好的解决方案,请发布。
答案 1 :(得分:0)
问题是import numpy as np
a=np.array([[1,2,3],[4,5,6]])
a=a.reshape((a.shape[0])*(a.shape[1])) # n is the nth largest taken by us
print(a[np.argsort()[-n]])
无法执行部分键的组合。如果您尝试使用多个值,它将连接包含任何值的所有行。因此,.loc()
(或在此特定情况下得出相同结果的a.loc[['a','b'], :, :]
)可以运行并返回a.loc[['a','b']]
为key1
或'a'
的所有行
但是,尝试为不同的键使用不同的值会导致一个或所有值,以便'b'
返回a.loc[['a','b'], ['x0', 'x1']]
key1
或'a'
的所有组合'b'
为key2
或'x0'
。当您尝试在元组中使用不完整的组合时,'x1'
会假定a.loc[[('a', 'x0'), ('b', 'x1')]]
和('a', 'x0')
为完整键。但这些(当然)不存在,因此('b', 'x1')
(不可用)作为输出返回。
因此,要选择多个部分键,您将注定使用另一种方法。一种方法是按照您的建议方式进行,通过逐个尝试部分键然后连接结果。另一种方法是使用NaN
来查找您感兴趣的项目。但是,这有点复杂,因为它需要一个函数,使用正确的键为行返回.select()
它的可能实现是:
True
这当然可以以更密集的方式实现,其中所有内容都合并为一行,但这会非常混乱:
sel_a_x0 = lambda row: row[0] == 'a' and row[1] == 'x0'
sel_b_x1 = lambda row: row[0] == 'b' and row[1] == 'x1'
sel_combined = lambda row: sel_a_x0(row) or sel_b_x1(row)
a.select(sel_combined)
所以我宁愿保持子表达式分开。
另外,我没有将这种方法与你自己建议的方法进行对比或比较,所以我不知道它是否更快。
答案 2 :(得分:0)
您可以先按droplevel
或reset_index
删除所有不必要的级别,然后与isin
进行比较,以获取布尔值掩码:
idx = [('a', 'x0'), ('b', 'x1')]
mask = a.index.droplevel(2).isin(idx)
mask = a.reset_index(level=2, drop=True).index.isin(idx)
print (mask)
[ True False False True]
最后按boolean indexing
过滤:
df = a[mask]
print (df)
val
key1 key2 key3
a x0 v 1
b x1 z 4