[問題] Pandas Series 條件-篩選-取代請益

看板Python作者 (TGG)時間1年前 (2022/04/27 19:55), 1年前編輯推噓7(7012)
留言19則, 6人參與, 1年前最新討論串1/1
大家好, 小弟python新手,最近練習pandas時面臨一個問題 懇請大家協助 假設我有一個共A B C D 四欄五列的dataframe 'df', 其中A欄為[20, 39, 41, 85, 11]的隨機數, 現在我想要將A欄中小於40的數+10,大於等於40的數-5, (同時,所以最終39要變成49,而不是44) 請問該怎麼處理呢? 直覺地想到就是 if df['A'] > 40: df['A] += 10 ... 但很明顯series沒辦法這樣處理。 之前學到的方式,大多是使用新建df的方法處理 df2 = df[df['A'] > 40] df2['A'] += 10 然而一來是這樣原來的df並沒有更動,而且一次只能用一個條件來篩選,頗為冗長 再來我也不會用新建的series來取代(畢竟長度不同,有這種方法嗎?) 懇請版上各位先進指教了, 該怎麼才能直接修改原來的df, 或是提點有甚麼方向可以去研究的,感謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.43.4.144 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Python/M.1651060519.A.576.html

04/27 20:37, 1年前 , 1F
def myadd(x):return(x+10 if x<40 else x-5)
04/27 20:37, 1F

04/27 20:37, 1年前 , 2F
df = df.assign(A=df.A.apply(myadd))
04/27 20:37, 2F

04/27 21:02, 1年前 , 3F
試試用 where: https://t.ly/6grQ
04/27 21:02, 3F

04/27 21:51, 1年前 , 4F
where正確, 不過如果是我會另設一個 df['A_1'] column
04/27 21:51, 4F

04/27 21:51, 1年前 , 5F
避免inplace計算
04/27 21:51, 5F

04/27 21:54, 1年前 , 6F
新的series直接copy df['A'] 就可以了
04/27 21:54, 6F

04/27 21:57, 1年前 , 7F
df.loc[df.A>40, 'A_1']-=5
04/27 21:57, 7F

04/27 23:12, 1年前 , 8F
要變數mask=df.A<40;df.A[mask]+=10;df.A[~mask]-=5
04/27 23:12, 8F
感謝大家! 剛剛把這些辦法都試了一遍,獲益匪淺 首先是自定義 def myAdd(x): return x+10 if x<40 else x-5 df = df.assign(A = df.A.apply(myAdd)) print(df) 但我發現直接粗暴取代好像也可以? df['A'] = df.A.apply(myAdd) 請問這樣會有甚麼差別嗎? ----------------- 再來是where df['A'] = np.where(var1, df.A+10, df.A-5) print(df) 原本嘗試用pd.df.where的,結果寫不出來Orz df.where(df.A < 40, df-5, inplace = True) 這樣會連其他欄一起更改,但當我想限制只有A欄時 df.where(df.A < 40, df.A-5, axis = 0, inplace = True) 會把其他欄也改成跟A欄一樣Orz e.g. A B C A B C 0 43 17 79 >> 0 38 38 38 QQ... ----------------- 最後不論是用loc還是直接指定 var1 = df['A'] < 40 df['A'][var1] += 10 df['A'][~var1] -= 5 df['A1'] = df.A df.loc[var1, 'A1'] += 10 df.loc[~var1, 'A1'] -= 5 都能達到目標,反而讓我有點好奇 會甚麼這樣分兩行來寫,新條件不會覆蓋到舊條件上呢? (38最終會變48,而不是38>48>43這樣) 總之,感謝各位! ※ 編輯: god1230321 (59.124.123.10 臺灣), 04/28/2022 10:39:38

04/28 10:46, 1年前 , 9F
assign會回傳修改後的df並不是inplace,而且可以同時
04/28 10:46, 9F

04/28 10:46, 1年前 , 10F
修改多個columns
04/28 10:46, 10F

04/28 10:49, 1年前 , 11F
先定義var1後,var1的狀態不會因為後面修改而變動
04/28 10:49, 11F
喔喔喔原來 剛剛把var1拿掉直接換成df['A'] < 40 條件就會互相影響了,感謝說明 ※ 編輯: god1230321 (59.124.123.10 臺灣), 04/28/2022 11:00:34

04/29 17:18, 1年前 , 12F
You can use list comprehension, here we have a
04/29 17:18, 12F

04/29 17:18, 1年前 , 13F
list L, L=[20,39,41,85,11], L2=[x+10 if x<40 el
04/29 17:18, 13F

04/29 17:18, 1年前 , 14F
se x-5 if x>40 else x for x in L], and df[‘B’
04/29 17:18, 14F

04/29 17:18, 1年前 , 15F
]=L2
04/29 17:18, 15F

04/30 00:58, 1年前 , 16F
w = df.A >= 40
04/30 00:58, 16F

04/30 00:58, 1年前 , 17F
df['A'] = df.A+w*(-5)+~w*10
04/30 00:58, 17F

04/30 12:13, 1年前 , 18F
df[‘A’] = df.A.map(lambda x:x+10 if x<40 else x-5
04/30 12:13, 18F

04/30 12:13, 1年前 , 19F
)
04/30 12:13, 19F
文章代碼(AID): #1YQIydLs (Python)