提问人:zach 提问时间:8/24/2012 最后编辑:Joepzach 更新时间:11/17/2023 访问量:1620487
使用值列表从 Pandas 数据帧中选择行
Use a list of values to select rows from a Pandas dataframe
问:
假设我有以下 Pandas 数据帧:
df = DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]})
df
A B
0 5 1
1 6 2
2 3 3
3 4 5
我可以根据特定值进行子集:
x = df[df['A'] == 3]
x
A B
2 3 3
但是,如何根据值列表进行子集?- 像这样的东西:
list_of_values = [3,6]
y = df[df['A'] in list_of_values]
要获取:
A B
1 6 2
2 3 3
答:
您可以使用 isin
方法:
In [1]: df = pd.DataFrame({'A': [5,6,3,4], 'B': [1,2,3,5]})
In [2]: df
Out[2]:
A B
0 5 1
1 6 2
2 3 3
3 4 5
In [3]: df[df['A'].isin([3, 6])]
Out[3]:
A B
1 6 2
2 3 3
并得到相反的用法:~
In [4]: df[~df['A'].isin([3, 6])]
Out[4]:
A B
0 5 1
3 4 5
您可以使用方法查询:
df.query('A in [6, 3]')
# df.query('A == [6, 3]')
或
lst = [6, 3]
df.query('A in @lst')
# df.query('A == @lst')
评论
query()
isin()
df.query('A.str.lower() in @lst')
另一种方法;
df.loc[df.apply(lambda x: x.A in [3,6], axis=1)]
与 isin 方法不同,这在确定列表是否包含列的函数时特别有用。例如,作为函数;A
f(A) = 2*A - 5
df.loc[df.apply(lambda x: 2*x.A-5 in [3,6], axis=1)]
应该注意的是,这种方法比方法慢。isin
您可以将值存储在列表中,如下所示:
lis = [3,6]
然后
df1 = df[df['A'].isin(lis)]
评论
list
list
list_of_values
不一定是 ;它可以是 、 、 、 numpy 数组、pandas 系列、生成器等,并且仍然可以工作。list
set
tuple
dictionary
range
isin()
query()
关于以下事项的说明:query()
- 您也可以在里面打电话:
isin()
query()
list_of_values = [3, 6] df.query("A.isin(@list_of_values)")
- 您可以将要搜索的值作为参数传递,如果您不想事先在函数调用链中创建筛选列表,这将非常有用:
local_dict
df.query("A == @lst", local_dict={'lst': [3, 6]})
选择行的一些常见问题
1. 是一个范围list_of_values
如果需要在某个范围内进行过滤,可以使用 between()
方法或 .query()
list_of_values = [3, 4, 5, 6] # a range of values
df[df['A'].between(3, 6)] # or
df.query('3<=A<=6')
2. 按以下顺序返回df
list_of_values
在 OP 中,中的值不会按 中的顺序显示。如果要按它们出现的顺序返回,即 “排序” by ,请使用 。list_of_values
df
df
list_of_values
list_of_values
loc
list_of_values = [3, 6]
df.set_index('A').loc[list_of_values].reset_index()
如果要保留旧索引,可以使用以下命令。
list_of_values = [3, 6, 3]
df.reset_index().set_index('A').loc[list_of_values].reset_index().set_index('index').rename_axis(None)
3.不要使用apply
一般来说,并且是完成此任务的最佳方法;没有必要。例如,对于列上的函数,两者的工作效率要高得多:isin()
query()
apply()
f(A) = 2*A - 5
A
isin()
query()
df[(2*df['A']-5).isin(list_of_values)] # or
df[df['A'].mul(2).sub(5).isin(list_of_values)] # or
df.query("A.mul(2).sub(5) in @list_of_values")
4. 选择不在list_of_values
要选择不在 中的行,则否定 /:list_of_values
isin()
in
df[~df['A'].isin(list_of_values)]
df.query("A not in @list_of_values") # df.query("A != @list_of_values")
5. 选择多列所在的行list_of_values
如果要使用两个(或多个)列进行筛选,则根据需要使用减少列 ()。any()
all()
axis=1
- 选择至少一个 or 所在的行:
A
B
list_of_values
df[df[['A','B']].isin(list_of_values).any(1)] df.query("A in @list_of_values or B in @list_of_values")
- 选择 和 都在 的行:
A
B
list_of_values
df[df[['A','B']].isin(list_of_values).all(1)] df.query("A in @list_of_values and B in @list_of_values")
使用 f-Strings 更棘手
list_of_values = [3,6]
df.query(f'A in {list_of_values}')
上面的答案是正确的,但是如果您仍然无法按预期筛选出行,请确保两个 DataFrame 的列具有相同的 。dtype
source = source.astype({1: 'int64'})
to_rem = to_rem.astype({'some col': 'int64'})
works = source[~source[1].isin(to_rem['some col'])]
花了我足够长的时间。
在速度方面进行比较的非熊猫解决方案可能是:
filtered_column = set(df.A) - set(list_list_of_values)
下一个:如何修复导航栏上的重叠图像?
评论