pandas - получить последнее значение определенного столбца, проиндексированного другим столбцом (получить максимальное значение определенного столбца, проиндексированного другим столбцом) - PullRequest
16 голосов
/ 24 марта 2012

У меня есть следующий фрейм данных:

   obj_id   data_date   value
0  4        2011-11-01  59500    
1  2        2011-10-01  35200 
2  4        2010-07-31  24860   
3  1        2009-07-28  15860
4  2        2008-10-15  200200

Я хочу получить подмножество этих данных, чтобы у меня были только самые последние (самые большие 'data_date') 'value' для каждого 'obj_id'.

Я взломал решение, но оно кажется грязным. Мне было интересно, если у кого-нибудь есть лучший способ. Я уверен, что, должно быть, мне не хватает простого способа сделать это через панд.

Мой метод заключается в группировке, сортировке, извлечении и рекомбинации следующим образом:

row_arr = []
for grp, grp_df in df.groupby('obj_id'):
    row_arr.append(dfg.sort('data_date', ascending = False)[:1].values[0])

df_new = DataFrame(row_arr, columns = ('obj_id', 'data_date', 'value'))

Ответы [ 6 ]

14 голосов
/ 08 апреля 2014

Это еще одно возможное решение.Я считаю, что это самый быстрый.

df.loc[df.groupby('obj_id').data_date.idxmax(),:]
9 голосов
/ 09 января 2014

Если число «obj_id» очень велико, вы захотите отсортировать весь фрейм данных, а затем отбросить дубликаты, чтобы получить последний элемент.

sorted = df.sort_index(by='data_date')
result = sorted.drop_duplicates('obj_id', take_last=True).values

Это должно быть быстрее (извините, я не проверял это), потому что вам не нужно выполнять специальную функцию agg, которая работает медленно при большом количестве клавиш.Вы можете подумать, что сортировать весь массив данных хуже, но на практике в Python сортировки выполняются быстро, а собственные циклы - медленные.

4 голосов
/ 23 октября 2012

Мне нравится ответ crewbum, возможно, это быстрее (извините, еще не проверял, но я избегаю сортировки всего):

df.groupby('obj_id').agg(lambda df: df.values[df['data_date'].values.argmax()])

он использует функцию numpys "argmax", чтобы найти индекс строки, в котором появляется максимум.

2 голосов
/ 14 августа 2017

Обновление ответа thetainted1, поскольку некоторые функции теперь имеют предупреждения в будущем, как указал tommy.carstensen.Вот что сработало для меня:

sorted = df.sort_values(by='data_date')

result = sorted.drop_duplicates('obj_id', keep='last')
2 голосов
/ 25 марта 2012

Метод aggregate () для объектов groupby можно использовать для создания нового DataFrame из объекта groupby за один шаг.(Однако я не знаю более чистого способа извлечения первой / последней строки DataFrame.)

In [12]: df.groupby('obj_id').agg(lambda df: df.sort('data_date')[-1:].values[0])
Out[12]: 
         data_date  value
obj_id                   
1       2009-07-28  15860
2       2011-10-01  35200
4       2011-11-01  59500

Вы также можете выполнить агрегирование для отдельных столбцов, и в этом случае функция агрегирования работает наОбъект серии.

In [25]: df.groupby('obj_id')['value'].agg({'diff': lambda s: s.max() - s.min()})
Out[25]: 
          diff
obj_id        
1            0
2       165000
4        34640
0 голосов
/ 05 марта 2014

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

df = pd.DataFrame({
'CARD_NO': ['000', '001', '002', '002', '001', '111'],
'DATE': ['2006-12-31 20:11:39','2006-12-27 20:11:53','2006-12-28 20:12:11','2006-12-28 20:12:13','2008-12-27 20:11:53','2006-12-30 20:11:39']})

print df 
df.groupby('CARD_NO').apply(lambda df:df['DATE'].values[df['DATE'].values.argmax()])

Оригинал

CARD_NO                 DATE
0     000  2006-12-31 20:11:39
1     001  2006-12-27 20:11:53
2     002  2006-12-28 20:12:11
3     002  2006-12-28 20:12:13
4     001  2008-12-27 20:11:53
5     111  2006-12-30 20:11:39

Возвращенный фрейм данных:

CARD_NO
000        2006-12-31 20:11:39
001        2008-12-27 20:11:53
002        2006-12-28 20:12:13
111        2006-12-30 20:11:39
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...