Индексирование рамки данных pandas на основе строк в столбце [duplicate]

На первый взгляд ...

Все, что вам нужно, - это предложение GROUP BY с агрегатной функцией MAX:

SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

Это никогда не бывает так просто, это ?

Я просто заметил, что вам нужен столбец content.

Это очень распространенный вопрос в SQL: найти все данные для строки с некоторым максимальным значением в столбца на один идентификатор группы. Я много слышал о своей карьере. На самом деле, это был один из вопросов, которые я ответил в техническом интервью моей текущей работы.

На самом деле настолько распространено, что сообщество StackOverflow создало один тег только для решения таких вопросов: .

В принципе, у вас есть два подхода к решению этой проблемы:

Соединение с простым group-identifier, max-value-in-group Sub-query

В этом подходе вы сначала найдете group-identifier, max-value-in-group (уже решены выше) в подзапросе. Затем вы присоединяетесь к своей таблице к подзапросу с равенством как на group-identifier, так и на max-value-in-group:

SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM YourTable
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev

Левое соединение с помощью себя, настройки условий и фильтров

In этот подход, вы оставили присоединиться к таблице с собой. Равенство, конечно, идет в group-identifier. Затем два умных перемещения:

  1. Второе условие соединения имеет значение слева ниже правого значения
  2. . Когда вы делаете шаг 1, строки (строки), которые на самом деле имеют максимальное значение будет иметь NULL в правой части (это LEFT JOIN, помните?). Затем мы фильтруем объединенный результат, показывая только строки, где правая сторона NULL.

Итак, вы закончите:

SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

Заключение

Оба подхода приносят точный результат.

Если у вас есть две строки с max-value-in-group для group-identifier, обе строки будут в результате в обоих подходах.

Оба подхода совместимы с SQL ANSI, таким образом, будут работать с вашей любимой РСУБД, независимо от ее «вкуса».

Оба подхода также дружелюбны к производительности, однако ваш пробег может варьироваться (РСУБД, структура БД, индексы и т. д.). Поэтому, когда вы выбираете один подход над другим, benchmark . И убедитесь, что вы выбрали тот, который вам больше всего подходит.

155
задан smci 17 July 2015 в 20:25
поделиться

5 ответов

Вы можете использовать pd.Series.isin .

Для «IN» используйте: something.isin(somewhere)

Или для «NOT IN»: ~something.isin(somewhere)

В качестве обработанного примера:

>>> df
  countries
0        US
1        UK
2   Germany
3     China
>>> countries
['UK', 'China']
>>> df.countries.isin(countries)
0    False
1     True
2    False
3     True
Name: countries, dtype: bool
>>> df[df.countries.isin(countries)]
  countries
1        UK
3     China
>>> df[~df.countries.isin(countries)]
  countries
0        US
2   Germany
353
ответ дан jpp 4 September 2018 в 10:18
поделиться
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']

реализовать в:

df[df.countries.isin(countries)]

реализовать не так, как в странах покоя:

df[df.countries.isin([x for x in np.unique(df.countries) if x not in countries])]
1
ответ дан Ioannis Nasios 4 September 2018 в 10:18
поделиться

Обычно я делаю общую фильтрацию по строкам следующим образом:

criterion = lambda row: row['countries'] not in countries
not_in = df[df.apply(criterion, axis=1)]
8
ответ дан Kos 4 September 2018 в 10:18
поделиться

Альтернативное решение, использующее метод .query () :

In [5]: df.query("countries in @countries")
Out[5]:
  countries
1        UK
3     China

In [6]: df.query("countries not in @countries")
Out[6]:
  countries
0        US
2   Germany
13
ответ дан MaxU 4 September 2018 в 10:18
поделиться

Я хотел отфильтровать строки dfbc, у которых был BUSINESS_ID, который также был в BUSINESS_ID dfProfilesBusIds

. Наконец, он работал:

dfbc = dfbc[(dfbc['BUSINESS_ID'].isin(dfProfilesBusIds['BUSINESS_ID']) == False)]
1
ответ дан Sam Henderson 4 September 2018 в 10:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: