使用值列表从 Pandas 数据框中选择行
- 2024-11-28 08:37:00
- admin 原创
- 7
问题描述:
假设我有以下 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
解决方案 1:
您可以使用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
解决方案 2:
您可以使用方法查询:
df.query('A in [6, 3]')
# df.query('A == [6, 3]')
或者
lst = [6, 3]
df.query('A in @lst')
# df.query('A == @lst')
解决方案 3:
list_of_values
不一定是list
;它可以是set
、、、numpy 数组、pandas 系列、生成器tuple
等。并且和仍然可以工作。dictionary
`rangeisin()
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')
df
2.按以下顺序返回list_of_values
在 OP 中, 中的值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
选择至少有一个
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")
解决方案 4:
您可以将您的值存储在列表中,如下所示:
lis = [3,6]
然后
df1 = df[df['A'].isin(lis)]
解决方案 5:
另一种方法;
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
方法要慢。
解决方案 6:
使用 f-Strings 比较棘手
list_of_values = [3,6]
df.query(f'A in {list_of_values}')
解决方案 7:
上述答案是正确的,但是如果您仍然无法按预期过滤行,请确保两个 DataFrames 的列具有相同的dtype
。
source = source.astype({1: 'int64'})
to_rem = to_rem.astype({'some col': 'int64'})
works = source[~source[1].isin(to_rem['some col'])]
我花了足够长的时间。
解决方案 8:
就速度而言,可比较的非熊猫解决方案可能是:
filtered_column = set(df.A) - set(list_list_of_values)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件