簡體   English   中英

獲取Python中dataframe子集的n個最小值

[英]Get n smallest values of a subset of a dataframe in Python

我正在嘗試做一些類似於在 Geeks for Geeks 工作例子。

在該示例中,他們處理了 dataframe 的 NBA(籃球)球員,並找到了聯盟中最小的 5 名球員(按身高或體重)。

所有這些都是有道理的,我能夠輕松地將它應用到我正在使用的數據集,直到我想做一些更精確的數據切片。 例如,我想找出每支 NBA 球隊中體型最小的 3 名球員。

我希望數據 output 如下所示:

團隊 播放器 重量 其他數據 x 其他數據
A隊 玩家 1 最小的 xxxxxx yyyyyy
A隊 玩家 2 第二小 xxxxxx yyyyyy
A隊 玩家 3 第三小 xxxxxx yyyyyy
---------- ---------- ---------- -------------- --------------
B隊 玩家 1 最小的 xxxxxx yyyyyy
B隊 玩家 2 第二小 xxxxxx yyyyyy
B隊 玩家 3 第三小 xxxxxx yyyyyy
---------- ---------- ---------- -------------- --------------
團隊 C 玩家 1 最小的 xxxxxx yyyyyy
團隊 C 玩家 2 第二小 xxxxxx yyyyyy
團隊 C 玩家 3 第三小 xxxxxx yyyyyy
---------- ---------- ---------- -------------- --------------

我已經嘗試按照我想要的方式進行以下兩項工作。

  1. df2 = df1.groupby('Team').nsmallest(3, ['Weight'])
  2. df2 = df1.groupby('Team')['Weight'].nsmallest(3)

關於如何進行多次數據切割的任何建議? 我還想保留所有其他列中的數據,而不是球隊/球員/體重數據。

您可以利用df.groupby('Team')["Weight"].nsmallest(3)已經在該結果的index列中為您提供所需的索引這一事實。 所以你可以只使用iloc原始 dataframe 中的那些索引。

import pandas as pd
    
# making data frame 
df = pd.read_csv("https://media.geeksforgeeks.org/wp-content/uploads/nba.csv") 

new_df = df.iloc[df.groupby('Team')["Weight"].nsmallest(3).index.get_level_values(1)]

結果:

>>> new_df.head(5)
                    Name            Team  Number  ... Weight        College     Salary
    318  Dennis Schroder   Atlanta Hawks    17.0  ...  172.0            NaN  1763400.0
    323      Jeff Teague   Atlanta Hawks     0.0  ...  186.0    Wake Forest  8000000.0
    311     Kirk Hinrich   Atlanta Hawks    12.0  ...  190.0         Kansas  2854940.0
    0      Avery Bradley  Boston Celtics     0.0  ...  180.0          Texas  7730337.0
    3        R.J. Hunter  Boston Celtics    28.0  ...  185.0  Georgia State  1148640.0
    
    [5 rows x 9 columns]

然后您可以將TeamName設置為多索引:

>>> new_df.set_index(["Team", "Name"]).head(6)
                                    Number Position  ...        College     Salary
    Team           Name                              ...                          
    Atlanta Hawks  Dennis Schroder    17.0       PG  ...            NaN  1763400.0
                   Jeff Teague         0.0       PG  ...    Wake Forest  8000000.0
                   Kirk Hinrich       12.0       SG  ...         Kansas  2854940.0
    Boston Celtics Avery Bradley       0.0       PG  ...          Texas  7730337.0
                   R.J. Hunter        28.0       SG  ...  Georgia State  1148640.0
                   Isaiah Thomas       4.0       PG  ...     Washington  6912869.0
    
    [6 rows x 7 columns]

Groupby Team ,在Weight上應用 pd.Series.nsmallest ,將級別降低到 1,將其轉換為 frame,然后將其內部合並回TeamWeight上的實際 dataframe

df.groupby('Team')['Weight'].apply(lambda row: row.nsmallest(3)).to_frame('Weight').droplevel(1).merge(df, on=['Team', 'Weight'], how='inner')

             Team  Weight           Name  Number Position   Age Height        College     Salary
0  Boston Celtics   180.0  Avery Bradley     0.0       PG  25.0    6-2          Texas  7730337.0
1  Boston Celtics   185.0    R.J. Hunter    28.0       SG  22.0    6-5  Georgia State  1148640.0
2  Boston Celtics   190.0   Terry Rozier    12.0       PG  22.0    6-2     Louisville  1824360.0

PS:在添加預期 output 時,從原始數據創建樣本,人們可能會對這種捏造的預期 output 感到困惑,這與實際數據完全不同。

import pandas as pd

details = {
    'Team' : ['A', 'A', 'A', 'A', 'B', 'B', 'B','B'],
    'Age' : [23, 21, 22, 19,18,17,20,22],
}
  
# creating a Dataframe object 
df = pd.DataFrame(details)

df=df.sort_values(by=['Team','Age'])
df['tmp']=1

df['seq']=df.groupby('Team')['tmp'].cumsum()
  
#filter out based on Nth basis on seq column
#filter code here

print(df.head())

稍后您可以根據“最小”字連接到 seq 列並刪除 tmp 列。

如果你這樣做

df2 = df1.groupby('Team').apply(lambda x: x.nsmallest(3, ['Weight'])

你會得到一個由數據幀組成的可迭代對象,每個數據幀都有一個團隊中最小的三個。 然后,您可以將它們 append 放在一起或將它們放在一個多索引 dataframe 中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM