Pandas - 根据条件层次选择行

时间:2021-01-05 14:52:01

标签: python pandas

我有一个数据框,我想根据数据框某些列中值的嵌套层次结构获取'第一个可用'索引。

示例:

import pandas as pd

foo = ['a','a','a','a','b','b','b','b']
bar = [0,0,1,1,2,2,1,1]
foobar = ['x',1,1,2,2,3,4,5]

df = pd.DataFrame({'foo':foo,'bar':bar,'foobar':foobar})

这给了你:

  foo  bar foobar
0   a    0      x
1   a    0      1
2   a    1      1
3   a    1      2
4   b    2      2
5   b    2      3
6   b    1      4
7   b    1      5

规则应如下所示:对于 foo 中的每个值,根据 barfoobar 中的值选择一个且仅一个行索引。对于 bar,这是条件的层次结构:0 > 1 > 2 > ... 而对于 foobar,它是 'x' > 1 > 2 > ...

foobar 应该嵌套在 bar 中,因此如果 bar 有多个可用值,则仅考虑 {{ 中 'first available' 值的行1}},然后才根据 bar 中特定值的 foobar 值的层次结构获取一个行索引。

预期输出:

对于我的示例,应该选择索引 bar0

1 个答案:

答案 0 :(得分:2)

IIUC,您可以使用 sort_values + duplicated

df = df.sort_values(by=['foo', 'bar', 'foobar'], key=lambda x: x.replace('x', 0).astype(int))
mask = df.duplicated(subset=['foo'])
res = df[~mask].index
print(res)

输出

Int64Index([0, 4], dtype='int64')

这个想法是按层次结构优先级对 DataFrame 的行进行排序,将 'x' 替换为 0(或任何其他高优先级)。然后找到被 foo 列重复的行。

更新

对于新案例,您可以这样做:

df = df.set_index('foo').sort_index().sort_values(by=['bar', 'foobar'],
                                                  key=lambda x: x.replace('x', 0).astype(int)).reset_index()
mask = df.duplicated(subset=['foo'])
res = df[~mask].index
print(res)
相关问题