亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python:如果有平局,則從 nsmallest 獲取第二個 idxmax

Python:如果有平局,則從 nsmallest 獲取第二個 idxmax

飲歌長嘯 2022-07-19 17:00:43
我有DataFrame如下。我想要得到的是 mininim 1st, 2nd, ... , n Valuefor eachArticle并且知道Name每個的Value來源。df   Article  Name  Value0     A_01  P_01    3601     A_03  P_01    6252     A_01  P_07    3603     A_01  P_09    3704     A_02  P_09    8475     A_03  P_09    6856     A_03  P_18    6507     A_02  P_22    9358     A_03  P_22    6259     A_02  P_25    75010    A_03  P_25    60011    A_01  P_26    50012    A_02  P_26    75013    A_03  P_26    60014    A_01  P_33    48015    A_03  P_33    750我正在使用此代碼n minimum value查找n minimum name每個Article. 首先,我轉動我df的以獲得:list_articles = df['Article'].drop_duplicates()list_names = list(df['Name'].drop_duplicates())pivot_df = df.pivot(index='Article', columns='Name', values='Value').reset_index()pivot_dfName Article   P_01   P_07   P_09   P_18   P_22   P_25   P_26   P_330       A_01  360.0  360.0  370.0    NaN    NaN    NaN  500.0  480.01       A_02    NaN    NaN  847.0    NaN  935.0  750.0  750.0    NaN2       A_03  625.0    NaN  685.0  650.0  625.0  600.0  600.0  750.0然后我運行了 lambda 函數來查找minimum_value和對應minimum_name:for i in range(1, 4):  # minimum 3    pivot_df[f'Min_{i}_Value'] = pivot_df[list_names].T.apply(lambda x: x.nsmallest(i).max())    pivot_df[f'Min_{i}_Name'] = pivot_df[list_names].T.apply(lambda x: x.nsmallest(i).idxmax())這給了我另外 6 列:pivot_dfName Article   P_01   P_07  ...  Min_2_Name  Min_3_Value  Min_3_Name0       A_01  360.0  360.0  ...        P_01        370.0        P_091       A_02    NaN    NaN  ...        P_25        847.0        P_092       A_03  625.0    NaN  ...        P_25        625.0        P_01最后,我的問題是什么?如果你仔細觀察,你會發現Min_1_ValueandMin_2_Value是一樣的(這是正確的),但是Min_1_Name和Min_2_Name也是一樣的,這是不正確的。為什么?因為在原始數據中,同一篇文章有兩個具有相同值的名稱,所以這是平局。我的代碼正在通過 min_n_value 的索引查找 min_n 的名稱,因此如果匹配超過 1 個,則不考慮平局的可能性。但是如何Min_2_Name正確分配不是的Min_1_Name呢?可以按字母順序選擇,沒關系。你有什么主意嗎?
查看完整描述

2 回答

?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

我希望您的解決方案應該簡化 - 首先DataFrame.sort_values是 2 列:


df = df.sort_values(['Article','Value'])

print (df)

   Article  Name  Value

0     A_01  P_01    360

2     A_01  P_07    360

3     A_01  P_09    370

14    A_01  P_33    480

11    A_01  P_26    500

9     A_02  P_25    750

12    A_02  P_26    750

4     A_02  P_09    847

7     A_02  P_22    935

10    A_03  P_25    600

13    A_03  P_26    600

1     A_03  P_01    625

8     A_03  P_22    625

6     A_03  P_18    650

5     A_03  P_09    685

15    A_03  P_33    750

然后創建計數器 Series byGroupBy.cumcount并通過 過濾 top3 值boolean indexing,添加MultiIndex并重塑 by Series.unstack,最后MultiIndex按 s 在列中展平f-string:


g = df.groupby('Article').cumcount().add(1)

mask = g < 4

df = df[mask].set_index(['Article',g[mask]]).unstack().sort_index(axis=1, level=1)

df.columns = df.columns.map(lambda x: f'Min_{x[1]}_{x[0]}')

df = df.reset_index()


print (df)

  Article Min_1_Name  Min_1_Value Min_2_Name  Min_2_Value Min_3_Name  \

0    A_01       P_01          360       P_07          360       P_09   

1    A_02       P_25          750       P_26          750       P_09   

2    A_03       P_25          600       P_26          600       P_01   


   Min_3_Value  

0          370  

1          847  

2          625  


查看完整回答
反對 回復 2022-07-19
?
慕萊塢森

TA貢獻1810條經驗 獲得超4個贊

您可以通過用 NaN 替換以前的最小來實現它。


import pandas as pd

import numpy as np

df = pd.DataFrame(

      [['A_01', 'P_01', 360],

       ['A_03', 'P_01', 625],

       ['A_01', 'P_07', 360],

       ['A_01', 'P_09', 370],

       ['A_02', 'P_09', 847],

       ['A_03', 'P_09', 685],

       ['A_03', 'P_18', 650],

       ['A_02', 'P_22', 935],

       ['A_03', 'P_22', 625],

       ['A_02', 'P_25', 750],

       ['A_03', 'P_25', 600],

       ['A_01', 'P_26', 500],

       ['A_02', 'P_26', 750],

       ['A_03', 'P_26', 600],

       ['A_01', 'P_33', 480],

       ['A_03', 'P_33', 750]])


df.columns=['Article','Name','Value']

list_articles = df['Article'].drop_duplicates()

list_names = list(df['Name'].drop_duplicates())

pivot_df = df.pivot(index='Article', columns='Name', values='Value').reset_index()

for i in range(1, 4):

    pivot_df[f'Min_{i}_Value'] = pivot_df[list_names].T.apply(lambda x: x.nsmallest(1).max())

    indices=pivot_df[list_names].T.apply(lambda y: y.nsmallest(1).idxmax())

    pivot_df[f'Min_{i}_Name'] = indices

    for i,x in enumerate(indices):

        pivot_df[x][i]=np.nan


ColsToKeep = [x for x in pivot_df.columns.tolist() if x not in list_names]

ColsToKeep = [x for x in ColsToKeep if x[:3] == 'Min']

ColsToKeep.sort()

ColsToKeep = ['Article'] + ColsToKeep


final_df = pivot_df[ColsToKeep]

final_df


查看完整回答
反對 回復 2022-07-19
  • 2 回答
  • 0 關注
  • 110 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號