我有一个数据框,我想根据数据框某些列中值的嵌套层次结构获取'第一个可用'索引。
示例:
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
中的每个值,根据 bar
和 foobar
中的值选择一个且仅一个行索引。对于 bar
,这是条件的层次结构:0 > 1 > 2 > ...
而对于 foobar
,它是 'x' > 1 > 2 > ...
foobar
应该嵌套在 bar
中,因此如果 bar
有多个可用值,则仅考虑 {{ 中 'first available' 值的行1}},然后才根据 bar
中特定值的 foobar
值的层次结构获取一个行索引。
预期输出:
对于我的示例,应该选择索引 bar
和 0
。
答案 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)