如何在Python Pandas中的两个值之间选择DataFrame中的行?

问题:如何在Python Pandas中的两个值之间选择DataFrame中的行?

我试图将DataFrame修改df为仅包含其列中的值在closing_price99到101之间的行,并尝试使用下面的代码执行此操作。

但是,我得到了错误

ValueError:系列的真值不明确。使用a.empty,a.bool(),a.item(),a.any()或a.all()

我想知道是否有一种方法可以不使用循环。

df = df[(99 <= df['closing_price'] <= 101)]

I am trying to modify a DataFrame df to only contain rows for which the values in the column closing_price are between 99 and 101 and trying to do this with the code below.

However, I get the error

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()

and I am wondering if there is a way to do this without using loops.

df = df[(99 <= df['closing_price'] <= 101)]

回答 0

您应该使用()将布尔向量分组的方式来消除歧义。

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]

You should use () to group your boolean vector to remove ambiguity.

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]

回答 1

还考虑以下系列

df = df[df['closing_price'].between(99, 101)]

Consider also series between:

df = df[df['closing_price'].between(99, 101)]

回答 2

还有一个更好的选择-使用query()方法:

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

更新:回答评论:

我喜欢这里的语法,但是在尝试与expresison结合使用时感到失望; df.query('(mean + 2 *sd) <= closing_price <=(mean + 2 *sd)')

In [161]: qry = "(closing_price.mean() - 2*closing_price.std())" +\
     ...:       " <= closing_price <= " + \
     ...:       "(closing_price.mean() + 2*closing_price.std())"
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
0             97
1            101
2             97
3             95
4            100
5             99
6            100
7            101
8             99
9             95

there is a nicer alternative – use query() method:

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

UPDATE: answering the comment:

I like the syntax here but fell down when trying to combine with expresison; df.query('(mean + 2 *sd) <= closing_price <=(mean + 2 *sd)')

In [161]: qry = "(closing_price.mean() - 2*closing_price.std())" +\
     ...:       " <= closing_price <= " + \
     ...:       "(closing_price.mean() + 2*closing_price.std())"
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
0             97
1            101
2             97
3             95
4            100
5             99
6            100
7            101
8             99
9             95

回答 3

您也可以使用.between()方法

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")

emp[emp["Salary"].between(60000, 61000)]

输出量

you can also use .between() method

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")

emp[emp["Salary"].between(60000, 61000)]

Output


回答 4

newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

要么

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')
newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

or

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')

回答 5

如果您要处理多个值和多个输入,则还可以设置这样的apply函数。在这种情况下,为落在特定范围内的GPS位置过滤数据帧。

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]

If you’re dealing with multiple values and multiple inputs you could also set up an apply function like this. In this case filtering a dataframe for GPS locations that fall withing certain ranges.

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]

回答 6

代替这个

df = df[(99 <= df['closing_price'] <= 101)]

你应该用这个

df = df[(df['closing_price']>=99 ) & (df['closing_price']<=101)]

我们必须使用NumPy的按位逻辑运算符|,&,〜,^进行复合查询。同样,括号对于运算符优先级也很重要。

有关更多信息,您可以访问链接:比较,掩码和布尔逻辑

Instead of this

df = df[(99 <= df['closing_price'] <= 101)]

You should use this

df = df[(df['closing_price']>=99 ) & (df['closing_price']<=101)]

We have to use NumPy’s bitwise Logic operators |, &, ~, ^ for compounding queries. Also, the parentheses are important for operator precedence.

For more info, you can visit the link :Comparisons, Masks, and Boolean Logic