簡體   English   中英

根據多行分組條件更改 pandas 列中的單元格值

[英]Changing a cell value in pandas column based on multiple rows grouping condition

我有一個 pandas dataframe 包含三列:

import pandas as pd
di={'id':[1,1,2,3,4,4],'b':['Sydney','Bexley','Arncliffe','Hurstville','Bexley North','Carlton'],
   'c':['contra','contra','contra_approved','contra','contra_approved','contra']}

df=pd.DataFrame(di)
df.head(10)


id  b             c
1   Sydney        contra
1   Bexley        contra
2   Arncliffe     contra_approved
3   Hurstville    contra
4   Bexley North  contra_approved
4   Carlton       contra

每個id都應該在'c'列中有一個關鍵字contra_approved

  • 對於帶有關鍵字' contra '的一個值的 id,我需要更改為contra_approved (例如 id 3
  • 對於具有關鍵字 contra 且其中沒有任何一個為contra_approved的多行 id,我需要將id相關行中的第一次出現更改為contra_approved (例如 id 1 )。

最終的 dataframe 將是:


id  b             c
1   Sydney        contra_approved
1   Bexley        contra
2   Arncliffe     contra_approved
3   Hurstville    contra_approved
4   Bexley North  contra_approved
4   Carlton       contra

如何解釋 pandas 中的以下邏輯?

我們試試看:

# check if all rows within same `id` have `c==contra`
g = df['c'].eq('contra').groupby(df['id']).transform('all')

# switch the first of those group into `contra_approved` 
# regardless of counts
df.loc[g & (~df.duplicated('id')), 'c'] = 'contra_approved'

Output:

   id             b                c
0   1        Sydney  contra_approved
1   1        Bexley           contra
2   2     Arncliffe  contra_approved
3   3    Hurstville  contra_approved
4   4  Bexley North  contra_approved
5   4       Carlton           contra

你可以試試:

def f(d):
    if "contra_approved" not in d["c"].unique():
        d.loc[d.index[0], "c"] = "contra_approved"
    return d

df = df.groupby("id").apply(f)
g=df.groupby('id').head(1)
df[~df.isin(g)].dropna().append(g.replace(regex='^contra$',value='contra_approved')).sort_values(by='id')


   id             b                c
1  1.0        Bexley           contra
0  1.0        Sydney  contra_approved
2  2.0     Arncliffe  contra_approved
3  3.0    Hurstville  contra_approved
5  4.0       Carlton           contra
4  4.0  Bexley North  contra_approved

這個怎么運作

  1. g=df.groupby('id').head(1) #隔離每組的第一個

  2. g.replace(regex='^contra$',value='contra_approved') #replace contra in g

  3. df[~df.isin(g)] #隔離每組中不在第一個的

  4. 結合第二步和第三步的結果

讓我們試試

cond = df.groupby('id').cumcount().eq(0) 
       & ~df.id.isin(df.loc[df.c.eq('contra_approved'),'id'])
df.loc[cond,'c']='contra_approved'
df
Out[146]: 
   id             b                c
0   1        Sydney  contra_approved
1   1        Bexley           contra
2   2     Arncliffe  contra_approved
3   3    Hurstville  contra_approved
4   4  Bexley North  contra_approved
5   4       Carlton           contra

暫無
暫無

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

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