假设我有以下 DataFrame:
dic = {'a' : [1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
'b' : [1, 1, 1, 1, 2, 2, 1, 1, 2, 2],
'c' : ['f', 'f', 'f', 'e', 'f', 'f', 'f', 'e', 'f', 'f'],
'd' : [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]}
df = pd.DataFrame(dic)
df
Out[10]:
a b c d
0 1 1 f 10
1 1 1 f 20
2 2 1 f 30
3 2 1 e 40
4 2 2 f 50
5 2 2 f 60
6 3 1 f 70
7 3 1 e 80
8 3 2 f 90
9 3 2 f 100
在下文中,我想获取 a 和 b 列的值,其中 c='e' 并使用这些值来选择 df 的相应行(这将过滤第 2、3、6、7 行)。这个想法是创建一个元组列表并通过该列表索引 df:
list_tup = list(df.loc[df['c'] == 'e', ['a','b']].to_records(index=False))
df_new = df.set_index(['a', 'b']).sort_index()
df_new
Out[13]:
c d
a b
1 1 f 10
1 f 20
2 1 f 30
1 e 40
2 f 50
2 f 60
3 1 f 70
1 e 80
2 f 90
2 f 100
list_tup
Out[14]: [(2, 1), (3, 1)]
df.loc[list_tup]
导致 TypeError: unhashable type: 'writeable void-scalar',我不明白。有什么建议么?我对 python 和 pandas 还很陌生,因此我认为我错过了一些基本知识。
最佳答案
我相信在这个用例中使用 groupby().transform()
和 bool 索引会更好:
valids = (df['c'].eq('e') # check if `c` is 'e`
.groupby([df['a'],df['b']]) # group by `a` and `b`
.transform('any') # check if `True` occurs in the group
# use the same label for all rows in group
)
# filter with `boolean indexing
df[valids]
输出:
a b c d
2 2 1 f 30
3 2 1 e 40
6 3 1 f 70
7 3 1 e 80
与 groupby().filter()
类似的想法,可读性更好,但速度可能稍慢:
df.groupby(['a','b']).filter(lambda x: x['c'].eq('e').any())
关于python - 按元组列表过滤 DataFrame 的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65849246/