如何在Python Pandas DataFrame中選擇每組的最大值?


簡介

在資料分析過程中,最基本和最常見的操作之一是從組內選擇包含某些列最大值的行。在這篇文章中,我將向您展示如何在DataFrame中查詢每組的最大值。

問題…

讓我們首先了解任務,假設您獲得了一個電影資料集,並要求根據受歡迎程度列出每年最受歡迎的電影。

怎麼做…

1.準備資料。

谷歌上有很多資料集。我經常使用kaggle.com來獲取資料分析所需的資料集。您可以隨意登入kaggle.com並搜尋電影。將電影資料集下載到目錄中並將其匯入Pandas DataFrame。

如果您像我一樣從kaggle.com下載了資料,請為幫助您提供資料的人點贊。

import pandas as pd
import numpy as np
movies = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")
# see sample 5 rows
print(f"Output \n\n*** {movies.sample(n=5)} ")

輸出

*** budget id original_language original_title popularity \
2028 22000000 235260 en Son of God 9.175762
2548 0 13411 en Malibu's Most Wanted 7.314796
3279 8000000 26306 en Prefontaine 8.717235
3627 5000000 10217 en The Sweet Hereafter 7.673124
4555 0 98568 en Enter Nowhere 3.637857

release_date revenue runtime status title \
2028 28/02/2014 67800064 138.0 Released Son of God
2548 10/04/2003 0 86.0 Released Malibu's Most Wanted
3279 24/01/1997 589304 106.0 Released Prefontaine
3627 14/05/1997 3263585 112.0 Released The Sweet Hereafter
4555 22/10/2011 0 90.0 Released Enter Nowhere

vote_average vote_count
2028 5.9 83
2548 4.7 77
3279 6.7 21
3627 6.8 103
4555 6.5 49

2.進行一些基本的資料分析以瞭解資料。

# Identify the data-types
print(f"Output \n*** Datatypes are {movies.dtypes} ")

輸出

*** Datatypes are budget int64
id int64
original_language object
original_title object
popularity float64
release_date object
revenue int64
runtime float64
status object
title object
vote_average float64
vote_count int64
dtype: object

2.現在,如果我們想節省大量記憶體使用,我們可以轉換float64和int64的資料型別。但是,在轉換資料型別之前,我們必須小心並做好功課。

# Check the maximum numeric value.
print(f"Output \n *** maximum value for Numeric data type - {movies.select_dtypes(exclude=['object']).unstack().max()}")

# what is the max vote count value
print(f" *** Vote count maximum value - {movies[['vote_count']].unstack().max()}")

# what is the max movie runtime value
print(f" *** Movie Id maximum value - {movies[['runtime']].unstack().max()}")

輸出

*** maximum value for Numeric data type - 2787965087.0
*** Vote count maximum value - 13752
*** Movie Id maximum value - 338.0

3.有些列不需要用64位表示,可以降低到16位,所以讓我們這樣做。64位int範圍是從-32768到+32767。我將對vote_count和runtime進行此操作,您可以對需要更少記憶體儲存的列進行此操作。

4.現在,要識別每年的最受歡迎電影,我們需要按release_date分組並獲取popularity的最大值。一個典型的SQL查詢如下所示。

SELECT movie with max popularity FROM movies GROUP BY movie released year

5.不幸的是,我們的release_date是物件資料型別,有幾種方法可以將其轉換為datetime。我將選擇建立一個只有年份的新列,以便可以使用該列進行分組。

movies['year'] = pd.to_datetime(movies['release_date']).dt.year.astype('Int64')
print(f"Output \n ***{movies.sample(n=5)}")

輸出

*** budget id original_language original_title popularity \
757 0 87825 en Trouble with the Curve 18.587114
711 58000000 39514 en RED 41.430245
1945 13500000 152742 en La migliore offerta 30.058263
2763 13000000 16406 en Dick 4.742537
4595 350000 764 en The Evil Dead 35.037625

release_date revenue runtime status title \
757 21/09/2012 0 111.0 Released Trouble with the Curve
711 13/10/2010 71664962 111.0 Released RED
1945 1/01/2013 19255873 124.0 Released The Best Offer
2763 4/08/1999 27500000 94.0 Released Dick
4595 15/10/1981 29400000 85.0 Released The Evil Dead

vote_average vote_count year
757 6.6 366 2012
711 6.6 2808 2010
1945 7.7 704 2013
2763 5.7 67 1999
4595 7.3 894 1981

方法1 - 不使用GroupBy

6.我們只需要3列:電影標題、電影上映年份和受歡迎程度。所以我們選擇這些列,並使用sort_values按年份排序,看看結果如何。

print(f"Output \n *** Method 1- Without Using Group By")
movies[["title", "year", "popularity"]].sort_values("year", ascending=True)

輸出

*** Without Using Group By



片名年份受歡迎程度
4592黨同伐異19163.232447
4661盛大的遊行19250.785744
2638大都會192732.351527
4594百老匯旋律19290.968865
4457潘多拉的魔盒19291.824184
............
2109遇見你之前201653.161905
3081森林201619.865989
2288戰鬥山谷20161.224105
4255成長中的史密斯20170.710870
4553美國仍然是最佳去處<NA>0.000000

4803行 × 3列

8.現在檢視結果,我們需要對受歡迎程度進行排序,以獲得每年的最受歡迎電影。將感興趣的列作為列表傳遞。ascending=False將使排序結果按降序排列。

movies[["title", "year", "popularity"]].sort_values(["year","popularity"], ascending=False)



片名年份受歡迎程度
4255成長中的史密斯20170.710870
788死侍2016514.569956
26美國隊長:內戰2016198.372395
10蝙蝠俠大戰超人:正義黎明2016155.790452
64X戰警:天啟2016139.272042
............
4593百老匯旋律19290.968865
2638大都會192732.351527
4660盛大的遊行19250.785744
4591黨同伐異19163.232447
4552美國仍然是最佳去處<NA>0.000000

4802行 × 3列

9.好了,資料現在已完美排序。所以下一步就是隻保留每年的第一個值並刪除其餘的值。猜猜怎麼做?

我們將使用.drop_duplicates方法。

movies[["title", "year", "popularity"]].sort_values(["year","popularity"], ascending=False).drop_duplicates(subset="year")



片名年份受歡迎程度
4255成長中的史密斯20170.710870
788死侍2016514.569956
546小黃人2015875.581305
95星際穿越2014724.247784
124冰雪奇緣2013165.125366
............
4456潘多拉的魔盒19291.824184
2638大都會192732.351527
4660盛大的遊行19250.785744
4591黨同伐異19163.232447
4552美國仍然是最佳去處<NA>0.000000

91行 × 3列

方法2 - 使用GroupBy

我們也可以用groupby實現同樣的效果。這種方法與上面顯示的SQL非常相似。

print(f"Output \n *** Method 2 - Using Group By")
movies[["title", "year", "popularity"]].groupby("year", as_index=False).apply(lambda df:df.sort_values("popularity", ascending=False)
.head(1)).droplevel(0).sort_values("year", ascending=False)

輸出

*** Method 2 - Using Group By



片名年份受歡迎程度
4255成長中的史密斯20170.710870
788死侍2016514.569956
546小黃人2015875.581305
95星際穿越2014724.247784
124冰雪奇緣2013165.125366
............
3804地獄天使19308.484123
4457潘多拉的魔盒19291.824184
2638大都會192732.351527
4661盛大的遊行19250.785744
4592黨同伐異19163.232447

90行 × 3列

更新於:2020年11月9日

581次瀏覽

啟動您的職業生涯

完成課程獲得認證

開始學習
廣告