簡體   English   中英

Pandas:將 <= 0 的所有值按組設置為列中的最大值,但僅在該組中的最后一個正值之后

[英]Pandas: set all values that are <= 0 to the maximum value in a column by group, but only after the last positive value in that group

我試圖將所有 <= 0 的值按組設置為該組中的最大值,但僅在最后一個正值之后。 也就是說,必須忽略組中最后一個正值之前的所有 <=0 值。 例子:

data = {'group':['A', 'A', 'A', 'A', 'A', 'B', 'B', 
                'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'], 
                 'value':[3, 0, 8, 7, 0, -1, 0, 9, -2, 0, 0, 2, 0, 5, 0, 1]} 
df = pd.DataFrame(data)
df

  group  value
0   A      3
1   A      0
2   A      8
3   A      7
4   A      0
5   B     -1
6   B      0
7   B      9
8   B     -2
9   B      0
10  B      0
11  C      2
12  C      0
13  C      5
14  C      0
15  C      1

結果必須是:

  group  value
0   A      3
1   A      0
2   A      8
3   A      7
4   A      8
5   B     -1
6   B      0
7   B      9
8   B      9
9   B      9
10  B      9
11  C      2
12  C      0
13  C      5
14  C      0
15  C      1

謝謝指教

首先添加一列來標識具有負值的行(更准確地說 <= 0):

df['neg'] = (df['value'] <= 0)

然后,對於每個組,找到將'neg'設置為 True 且連續的最后幾個條目的序列。 為此,請顛倒 DataFrame 的順序(使用.iloc[::-1] ),然后在'neg'列上使用.cumprod() cumprod()會將 True 視為 1,將 False 視為 0,因此只要您看到所有 True,累積乘積將為 1,並且在您看到第一個 False 時將變為並保持為 0。 因為我們顛倒了順序,所以我們從末尾向后,所以我們在末尾找到 True 的序列。

df['upd'] = df.iloc[::-1].groupby('group')['neg'].cumprod().astype(bool)

現在我們知道要更新哪些條目,我們只需要知道將它們更新為什么,即組的最大值。 我們可以在 groupby 上使用transform('max')來獲取該值,然后剩下的就是對設置了'upd''value'進行實際更新:

df.loc[df['upd'], 'value'] = df.groupby('group')['value'].transform('max')

我們可以通過刪除我們在過程中使用的兩個輔助列來完成:

df = df.drop(['neg', 'upd'], axis=1)

我得到的結果與您的預期結果相符。


更新:或者在單個(長!)行中執行整個操作,而不向原始 DataFrame 添加任何輔助列:

df.loc[
    df.assign(
        neg=(df['value'] <= 0)
    ).iloc[::-1].groupby(
        'group'
    )['neg'].cumprod().astype(bool),
    'value'
] = df.groupby(
    'group'
)['value'].transform('max')

你可以這樣做。

(df.loc[(df.assign(m=df['value'].lt(0)).groupby(['group'], sort=False)['m'].transform('any')) &
    (df.index>=df.groupby('group')['value'].transform('idxmin')),'value']) = np.nan
df['value']=df.groupby('group').ffill()
df

輸出

group   value
0   A   3.0
1   A   0.0
2   A   8.0
3   A   7.0
4   A   0.0
5   B   -1.0
6   B   0.0
7   B   9.0
8   B   9.0
9   B   9.0
10  B   9.0
11  C   2.0
12  C   0.0
13  C   5.0
14  C   0.0
15  C   1.0

暫無
暫無

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

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