Як вибрати рядки в DataFrame між двома значеннями, у Pyndon Pandas?


102

Я намагаюся змінити DataFrame, dfщоб містити лише рядки, значення яких у стовпці closing_priceзнаходяться між 99 і 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()сімейство функцій, їх особливості та випадки використання, будь-ласка, відвідайте Dynamic Expression Evaluation in pandas за допомогою pd.eval () .
cs95

Відповіді:


108

Вам слід використовувати ()для групування вашого логічного вектора, щоб усунути двозначність.

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

176

Розглянемо також серії між :

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

6
Опція inclusive=Trueвикористовується за замовчуванням у between, тому ви можете робити запити таким чиномdf = df[df['closing_price'].between(99, 101)]
Антон Єрмаков

3
це найкраща відповідь! чудова робота!
PEBKAC

Чи існує функція "не між" у пандах? Я його не знаходжу.
dsugasa

3
@dsugasa, використовуй оператор тильди з between.
Парфе

1
@dsugasa, напр.df = df[~df['closing_price'].between(99, 101)]
33 січня

23

є приємніша альтернатива - використовуйте метод 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

UPDATE: відповідь на коментар:

Мені тут подобається синтаксис, але я впав при спробі поєднати з 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, що таке meanі sd? Це назви стовпців?
MaxU

немає , вони є обчисленим середнім і стандартне відхилення зберігається у вигляді поплавця
відображення РОМА

@mappingdom, що ви маєте на увазі кажучи "зберігається"?
MaxU

@mappingdom, я оновив свій пост - це те, про що ти просив?
MaxU

9

Ви також можете використовувати .between()метод

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

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

Вихідні дані

введіть тут опис зображення


7
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

Якщо ви маєте справу з кількома значеннями та кількома входами, ви також можете налаштувати функцію застосування, як ця. У цьому випадку фільтрування кадру даних для місцезнаходжень 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 |, &, ~, ^. Крім того, дужки важливі для пріоритету оператора.

Для отримання додаткової інформації ви можете відвідати посилання: Порівняння, маски та логічна логіка

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.