Python / Pandas: подгруппа Dataframe соответствует критериям индекса - PullRequest
1 голос
/ 11 марта 2020

Я новичок в Python (привык к кодированию с двоюродным братом R) и все еще получаю навык pandas. Существует невероятно полезная связанная запись. , но вместо фильтрации () по номеру набора я надеялся сделать это по критериям, определенным во втором наборе данных.

Давайте создадим некоторые игрушечные данные:

import pandas as pd

pets = [['foxhound', 'dog', 20], ['husky', 'dog', 25], ['GSD', 'dog', 24],['Labrador', 'dog', 23],['Persian', 'cat', 7],['Siamese', 'cat', 6],['Tabby', 'cat', 5]]

df = pd.DataFrame(pets , columns = ['breed', 'species','height']).set_index('breed')

TooBigForManhattan = [['dog', 22],['cat', 6]]

TooBig = pd.DataFrame(TooBigForManhattan, columns = ['species','height']).set_index('species')

Я пытаюсь установить подмножество df(), выбрав породы, которые меньше или равны значениям TooBig(). Мой псевдокод выглядит следующим образом:

df.groupby(['breed','species']).filter(lambda x : (x['height']<='TooBig Cutoff by Species').any())

Данные, с которыми я работаю, представляют собой тысячи записей с примерно сотней критериев, поэтому любая помощь в определении решения, которое могло бы работать в таком масштабе, была бы очень полезной.

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 11 марта 2020

С объединением в одном столбце вы можете map каждого вида достичь его высоты и проверить, меньше ли значение в DataFrame.

df[df['height'] <= df['species'].map(dict(TooBigForManhattan))]

         species  height
breed                   
foxhound     dog      20
Siamese      cat       6
Tabby        cat       5

Подробнее о некоторых промежуточных шагах.

# List of lists becomes this dict
dict(TooBigForManhattan)
#{'cat': 6, 'dog': 22}

# We use this Boolean Series to slice the DataFrame
df.height <= df.species.map(dict(TooBigForManhattan))
#breed
#foxhound     True
#husky       False
#GSD         False
#Labrador    False
#Persian     False
#Siamese      True
#Tabby        True
#dtype: bool
3 голосов
/ 11 марта 2020

Я считаю, что вам нужно merge, с которым вы можете использовать df.query

out = (df.merge(TooBig,left_on='species',right_index=True,suffixes=('','_y'))
         .query("height<=height_y").loc[:,df.columns])
print(out)

Или аналогично:

out = df.merge(TooBig,left_on='species',right_index=True,suffixes=('','_y'))
out = out[out['height']<=out['height_y']].reindex(columns=df.columns)
print(out)

         species  height
breed                   
foxhound     dog      20
Siamese      cat       6
Tabby        cat       5
...