使用值列表从Pandas数据框中选择行

bsxbgnwa  于 2023-01-28  发布在  其他
关注(0)|答案(8)|浏览(104)

假设我有以下Pandas Dataframe :

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
blmhpbnm

blmhpbnm1#

可以使用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
dfuffjeb

dfuffjeb2#

您可以使用方法查询:

df.query('A in [6, 3]')
# df.query('A == [6, 3]')

lst = [6, 3]
df.query('A in @lst')
# df.query('A == @lst')
5hcedyr0

5hcedyr03#

您可以将列表中的值存储为:
lis = [3,6]
那么
df1 = df[df['A'].isin(lis)]

zkure5ic

zkure5ic4#

另一种方法;

df.loc[df.apply(lambda x: x.A in [3,6], axis=1)]

isin方法不同,这在确定列表是否包含列A的函数时特别有用。

df.loc[df.apply(lambda x: 2*x.A-5 in [3,6], axis=1)]

应当注意,这种方法比isin方法慢。

cuxqih21

cuxqih215#

不一定是一个它可以是settupledictionary,numpy阵列,Pandas系列,发电机,range等,isin()query()仍然可以工作。

选择行的一些常见问题

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.按照list_of_values的顺序返回df

在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(),例如,对于列A上的函数f(A) = 2*A - 5isin()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)。
1.选择AB中至少有一个在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")

1.选择AB都在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")
奖金:

也可以在query()中调用isin()

df.query("A.isin(@list_of_values).values")
fwzugrvs

fwzugrvs6#

F弦更棘手

list_of_values = [3,6]

df.query(f'A in {list_of_values}')
wnvonmuf

wnvonmuf7#

上面的答案是正确的,但是如果您仍然不能按预期筛选出行,请确保两个DataFrame的列具有相同的dtype

source = source.astype({1: 'int64'})
to_rem = to_rem.astype({'some col': 'int64'})

works = source[~source[1].isin(to_rem['some col'])]

花了我够长时间。

whlutmcx

whlutmcx8#

在速度方面进行比较的非Pandas解决方案可能是:

filtered_column = set(df.A) - set(list_list_of_values)

相关问题