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


99

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

但是,我得到了错误

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

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

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

这里的问题是,您无法将标量与数组进行比较,因此会出现错误,对于比较,您必须使用按位运算符,并且由于运算符的优先级而必须将它们括在括号中
EdChum

df.query并且pd.eval看起来很好拟合这个用例。有关pd.eval()功能系列,其功能和使用案例的信息,请访问使用pd.eval()在熊猫中进行动态表达评估
cs95

Answers:


103

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

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

162

还考虑以下系列

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

5
inclusive=True在中between,默认情况下使用Option ,因此您可以像这样查询df = df[df['closing_price'].between(99, 101)]
Anton Ermakov,

3
这是最好的答案!很好!
PEBKAC

大熊猫中是否存在“介于两者之间”功能?我找不到。
dsugasa

2
@dsugasa,将波浪号运算符与一起使用between
冻糕

1
@dsugasa例如df = df[~df['closing_price'].between(99, 101)]
1

22

还有一个更好的选择-使用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

我喜欢这里的语法,但是在尝试与expresison结合使用时会失败;df.query('(平均值+ 2 * sd)<=收盘价<=(平均值+ 2 * sd)')
映射dom

1
@mappingdom,什么是meansd?这些是列名吗?
MaxU

不,它们是作为浮点数存储的计算出的均值和标准差
映射dom

@mappingdom,您的意思是说“存储”?
MaxU

@mappingdom,我更新了我的帖子-那是您要的吗?
MaxU

9

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

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

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

输出量

在此处输入图片说明


6
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')

3

如果您要处理多个值和多个输入,则还可以设置这样的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)]

1

代替这个

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

你应该用这个

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.