Панды: удалить несколько строк в зависимости от условия - PullRequest
0 голосов
/ 25 января 2019

Ниже приведено подмножество pandas dataframe У меня есть, и я пытаюсь удалить несколько строк на основе некоторых условий.

  code1 code2 grp1 grp2  dist_km
0  M001  M002  AAA  AAA      112
1  M001  M003  AAA  IHH      275
2  M002  M005  AAA  XXY      150
3  M002  M004  AAA  AAA       65
4  M003  M443  IHH  GRR       50
5  M003  M667  IHH  IHH      647
6  M003  M664  IHH  FFG      336

Так что я бы хотел сохранить только те строки, где grp1 совпадает с grp2 для каждого code1, но только где dist_km - наименьшее значение для этого конкретного code1.

Для приведенного выше примера останутся только эти строки:

  code1 code2 grp1 grp2  dist_km
0  M001  M002  AAA  AAA      112
3  M002  M004  AAA  AAA       65

Какой самый простой способ сделать это?

Ответы [ 5 ]

0 голосов
/ 25 января 2019

Вы можете сделать это, отфильтровав ваш фрейм данных, применив groupby / agg, а затем объединить обратно.

result_df = df.loc[df.grp1 == df.grp2].groupby('code1').agg({'dist_km': min})
df = pd.merge(df, result_df, how='inner', 
              left_on=['code1', 'dist_km'], right_on=['code1', 'dist_km'])
0 голосов
/ 25 января 2019

Нет необходимости groupby с использованием sort_values с drop_duplicates

df.sort_values('dist_km').drop_duplicates('code1').query('grp1==grp2')
  code1 code2 grp1 grp2  dist_km
3  M002  M004  AAA  AAA       65
0  M001  M002  AAA  AAA      112
0 голосов
/ 25 января 2019

Если создание временного фрейма данных не является проблемой, вы можете попробовать использовать transform:

tmp = df[df.groupby('code1')['dist_km'].transform('min') == df['dist_km']]
df1 = tmp[tmp['grp1'] == tmp['grp2']]

Или вы также можете попробовать:

new_df = df.loc[df.groupby('code1')['dist_km'].idxmin()][df['grp1']==df['grp2']]
0 голосов
/ 25 января 2019

Используйте два условия

df.loc[(df['dist_km'] == df.groupby('code1')['dist_km'].transform('min')) & (df['grp1'] == df['grp2'])]

    code1   code2   grp1    grp2    dist_km
0   M001    M002    AAA     AAA     112
3   M002    M004    AAA     AAA     65
0 голосов
/ 25 января 2019

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

codes = df.code1.unique()     # gets unique codes
splitdfs = []

for code in codes:
    tempdf = df[df.code1 == code]                            # select all code1
    tempdf = tempdf[tempdf.dist_km == tempdf.dist_km.min()]  # select dist_km is min
    tempdf = tempdf[tempdf.grp1 == tempdf.grp2]              # select grp1 == grp2 (must be AFTER selecting lowest dist_km)

    splitdfs.append(tempdf)


selectdf = pd.concat(splitdfs)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...