Группируйте и сравнивайте / фильтруйте определенные группы в зависимости от других столбцов в панде. - PullRequest
2 голосов
/ 05 апреля 2019

У меня есть df, как:

number   city        date
1        Denver_1     2019-01-14
1        Denver_1     2019-01-15
1        Denver_1     2019-01-16
1        Denver_2     2019-03-28
1        Denver_2     2019-03-29
2        Denver_1     2019-05-14
2        Denver_1     2019-05-15
2        Denver_1     2019-05-16
2        Denver_2     2019-01-28
2        Denver_2     2019-01-29
2        Seattle      2019-03-22
2        Seattle      2019-03-22
3        Denver_2     2019-05-28
3        Denver_2     2019-05-29
3        Seattle      2019-03-21
3        Seattle      2019-03-21

Я хочу сгруппировать число и выбрать Денвер с более высокой датой с и оставить Сиэтл с, как они есть, потому что те не дублируйте как Денвер с. Результат, который я хочу, будет выглядеть так:

number   city        date
1        Denver_2     2019-03-28
1        Denver_2     2019-03-29
2        Denver_1     2019-05-14
2        Denver_1     2019-05-15
2        Denver_1     2019-05-16
2        Seattle      2019-03-22
2        Seattle      2019-03-22
3        Denver_2     2019-05-28
3        Denver_2     2019-05-29
3        Seattle      2019-03-21
3        Seattle      2019-03-21

Я пытался:

df2 = df.groupby(['number']).apply(lambda x: x['city'].unique())

number
1       [Denver_1, Denver_2]
2       [Denver_1, Denver_2, Seattle]

, который показывает мне разные города для каждого номера, но я не знаю, как добавить к нему фильтр максимальной даты и применить его к основной df.

Другие примеры, которые я видел при использовании groupby (). Filter () избавили бы от Сиэтла s в моем случае.

1 Ответ

1 голос
/ 05 апреля 2019

К сожалению, поскольку правила разные, я думаю, что вам нужно обращаться с Денвером и Сиэтлом отдельно:

Загрузить данные образца:

s = '''number   city        date
1        Denver_1     2019-01-14
1        Denver_1     2019-01-15
1        Denver_1     2019-01-16
1        Denver_2     2019-03-28
1        Denver_2     2019-03-29
2        Denver_1     2019-05-14
2        Denver_1     2019-05-15
2        Denver_1     2019-05-16
2        Denver_2     2019-01-28
2        Denver_2     2019-01-29
2        Seattle      2019-03-22
2        Seattle      2019-03-22
3        Denver_2     2019-05-28
3        Denver_2     2019-05-29
3        Seattle      2019-03-21
3        Seattle      2019-03-21'''


df = pd.DataFrame.from_csv(io.StringIO(s), sep='\s+')
df['date'] = pd.to_datetime(df['date'])
df =df.reset_index()

Решение:

selector = lambda x: x.loc[x['city'] == x.loc[x['date'].idxmax(), 'city']]
denvers = df[df['city'].str.contains('Denver')].groupby('number', as_index=False).apply(selector)
seattles = df[df['city'].str.contains('Seattle')]

pd.concat([denvers.reset_index(level=0, drop=True), seattles], axis = 0).sort_index()

Выход:

    number      city       date
3        1  Denver_2 2019-03-28
4        1  Denver_2 2019-03-29
5        2  Denver_1 2019-05-14
6        2  Denver_1 2019-05-15
7        2  Denver_1 2019-05-16
10       2   Seattle 2019-03-22
11       2   Seattle 2019-03-22
12       3  Denver_2 2019-05-28
13       3  Denver_2 2019-05-29
14       3   Seattle 2019-03-21
15       3   Seattle 2019-03-21
...