作者god1230321 (TGG)
看板Python
标题[问题] Pandas Series 条件-筛选-取代请益
时间Wed Apr 27 19:55:17 2022
大家好,
小弟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://webptt.com/cn.aspx?n=bbs/Python/M.1651060519.A.576.html
1F:推 lycantrope: def myadd(x):return(x+10 if x<40 else x-5) 04/27 20:37
2F:→ lycantrope: df = df.assign(A=df.A.apply(myadd)) 04/27 20:37
4F:推 Mupzopod: where正确, 不过如果是我会另设一个 df['A_1'] column 04/27 21:51
5F:→ Mupzopod: 避免inplace计算 04/27 21:51
6F:→ Mupzopod: 新的series直接copy df['A'] 就可以了 04/27 21:54
7F:→ Mupzopod: df.loc[df.A>40, 'A_1']-=5 04/27 21:57
8F:推 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
9F:推 lycantrope: assign会回传修改後的df并不是inplace,而且可以同时 04/28 10:46
10F:→ lycantrope: 修改多个columns 04/28 10:46
11F:→ lycantrope: 先定义var1後,var1的状态不会因为後面修改而变动 04/28 10:49
喔喔喔原来
刚刚把var1拿掉直接换成df['A'] < 40
条件就会互相影响了,感谢说明
※ 编辑: god1230321 (59.124.123.10 台湾), 04/28/2022 11:00:34
12F:推 robert09080: You can use list comprehension, here we have a 04/29 17:18
13F:→ robert09080: list L, L=[20,39,41,85,11], L2=[x+10 if x<40 el 04/29 17:18
14F:→ robert09080: se x-5 if x>40 else x for x in L], and df[‘B’ 04/29 17:18
15F:→ robert09080: ]=L2 04/29 17:18
16F:推 poototo: w = df.A >= 40 04/30 00:58
17F:→ poototo: df['A'] = df.A+w*(-5)+~w*10 04/30 00:58
18F:推 gene50814: df[‘A’] = df.A.map(lambda x:x+10 if x<40 else x-5 04/30 12:13
19F:→ gene50814: ) 04/30 12:13