推 lycantrope: def myadd(x):return(x+10 if x<40 else x-5) 04/27 20:37
→ lycantrope: df = df.assign(A=df.A.apply(myadd)) 04/27 20:37
推 Mupzopod: where正確, 不過如果是我會另設一個 df['A_1'] column 04/27 21:51
→ Mupzopod: 避免inplace計算 04/27 21:51
→ Mupzopod: 新的series直接copy df['A'] 就可以了 04/27 21:54
→ Mupzopod: df.loc[df.A>40, 'A_1']-=5 04/27 21:57
推 lycantrope: 要變數mask=df.A<40;df.A[mask]+=10;df.A[~mask]-=5 04/27 23:12
感謝大家! 剛剛把這些辦法都試了一遍,獲益匪淺
首先是自定義
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
推 lycantrope: assign會回傳修改後的df並不是inplace,而且可以同時 04/28 10:46
→ lycantrope: 修改多個columns 04/28 10:46
→ lycantrope: 先定義var1後,var1的狀態不會因為後面修改而變動 04/28 10:49
喔喔喔原來
剛剛把var1拿掉直接換成df['A'] < 40
條件就會互相影響了,感謝說明
※ 編輯: god1230321 (59.124.123.10 臺灣), 04/28/2022 11:00:34
推 robert09080: You can use list comprehension, here we have a 04/29 17:18
→ robert09080: list L, L=[20,39,41,85,11], L2=[x+10 if x<40 el 04/29 17:18
→ robert09080: se x-5 if x>40 else x for x in L], and df[‘B’ 04/29 17:18
→ robert09080: ]=L2 04/29 17:18
推 poototo: w = df.A >= 40 04/30 00:58
→ poototo: df['A'] = df.A+w*(-5)+~w*10 04/30 00:58
推 gene50814: df[‘A’] = df.A.map(lambda x:x+10 if x<40 else x-5 04/30 12:13
→ gene50814: ) 04/30 12:13