Pandas的clip和replace正则替换

举报
小小明-代码实体 发表于 2021/10/11 23:42:02 2021/10/11
【摘要】 之前已发布 DataFrame的apply和applymap方法以及Series中的map方法 利用Pandas进行数据转换(map、replace、rename、duplicated等函数的使用) 本文再补充更多的关于replace函数的用法,以及没有提到的clip函数。 clip函数 clip用于对超过或者低于某...

之前已发布

DataFrame的apply和applymap方法以及Series中的map方法

利用Pandas进行数据转换(map、replace、rename、duplicated等函数的使用)

本文再补充更多的关于replace函数的用法,以及没有提到的clip函数。


clip函数

clip用于对超过或者低于某些值的数进行截断。

准备示例数据:


   
  1. >>> data = {'col_0': [9, -3, 0, -1, 5], 'col_1': [-2, -7, 6, 8, -5]}
  2. >>> df = pd.DataFrame(data)
  3. >>> df
  4. col_0 col_1
  5. 0 9 -2
  6. 1 -3 -7
  7. 2 0 6
  8. 3 -1 8
  9. 4 5 -5

Clips对超过或者低于指定阈值的数据将替换为指定阈值:


   
  1. >>> df.clip(-4, 6)
  2. col_0 col_1
  3. 0 6 -2
  4. 1 -3 -4
  5. 2 0 6
  6. 3 -1 6
  7. 4      5     -4

传入两个Series,并指定axis=0则可以对每一行数据都用指定的范围进行截断:


   
  1. >>> df
  2. col_0 col_1
  3. 0 9 -2
  4. 1 -3 -7
  5. 2 0 6
  6. 3 -1 8
  7. 4 5 -5
  8. >>> t1 = pd.Series([2, -4, -1, 6, 3])
  9. >>> t2 = pd.Series([6, 0, 3, 9, 8])
  10. >>> df.clip(t1, t2, axis=0)
  11. col_0 col_1
  12. 0 6 2
  13. 1 -3 -4
  14. 2 0 3
  15. 3 6 8
  16. 4      5      3

比如对于第一行数据9 和 -2被截断在[2,6]的范围,大于6取6,小于2取2.



DataFrame或Series的replace方法

对指定的单个标量值进行替换:


   
  1. >>> s = pd.Series([0, 1, 2, 3, 4])
  2. >>> s.replace(0, 5)
  3. 0 5
  4. 1 1
  5. 2 2
  6. 3 3
  7. 4 4
  8. dtype: int64
  9. >>> df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
  10. ... 'B': [5, 6, 7, 8, 9],
  11. ... 'C': ['a', 'b', 'c', 'd', 'e']})
  12. >>> df.replace(0, 5)
  13. A B C
  14. 0 5 5 a
  15. 1 1 6 b
  16. 2 2 7 c
  17. 3 3 8 d
  18. 4  4  9  e

将指定的列表内的所有标量值都替换为指定值:


   
  1. >>> df.replace([0, 1, 2, 3], 4)
  2. A B C
  3. 0 4 5 a
  4. 1 4 6 b
  5. 2 4 7 c
  6. 3 4 8 d
  7. 4 4 9 e

传入两个长度一致的列表,则有一一对应的替换关系:


   
  1. >>> df.replace([0, 1, 2, 3], [4, 3, 2, 1])
  2. A B C
  3. 0 4 5 a
  4. 1 3 6 b
  5. 2 2 7 c
  6. 3 1 8 d
  7. 4 4 9 e

其中0替换为4,1替换为3,2依然替换为2,替换为1。

对指定标量值使用向上填充的方式进行替换:


   
  1. >>> s.replace([1, 2], method='bfill')
  2. 0 0
  3. 1 3
  4. 2 3
  5. 3 3
  6. 4 4
  7. dtype: int64

原本的1和2都被下面3向上填充。

使用单个普通字典进行替换,效果与传入两个长度一致的列表一致:


   
  1. >>> df.replace({0: 10, 1: 100})
  2. A B C
  3. 0 10 5 a
  4. 1 100 6 b
  5. 2 2 7 c
  6. 3 3 8 d
  7. 4 4 9 e

传入两个参数,则字典中的键为要被替换的键,值为要被替换的值,第二个参数为替换后的值:


   
  1. >>> df.replace({'A': 0, 'B': 5}, 100)
  2. A B C
  3. 0 100 100 a
  4. 1 1 6 b
  5. 2 2 7 c
  6. 3 3 8 d
  7. 4 4 9 e

还可以传入嵌套字典,外层字典的键表示要替换的列,内层字典的键值表示被替换的值和替换后的值:


   
  1. >>> df.replace({'A': {0: 100, 4: 400}})
  2. A B C
  3. 0 100 5 a
  4. 1 1 6 b
  5. 2 2 7 c
  6. 3 3 8 d
  7. 4 400 9 e

指定参数regex=True即可实现正则表达式替换。


   
  1. >>> df = pd.DataFrame({'A': ['bat', 'foo', 'bait'],
  2. ... 'B': ['abc', 'bar', 'xyz']})
  3. >>> df.replace(to_replace=r'^ba.$', value='new', regex=True)
  4. A B
  5. 0 new abc
  6. 1 foo new
  7. 2 bait xyz

下面将A列符合^ba.$规则的都替换为new


   
  1. >>> df.replace({'A': r'^ba.$'}, {'A': 'new'}, regex=True)
  2. A B
  3. 0 new abc
  4. 1 foo bar
  5. 2 bait xyz

也可以直接向regex参数传递替换规则:


   
  1. >>> df.replace(regex=r'^ba.$', value='new')
  2. A B
  3. 0 new abc
  4. 1 foo new
  5. 2 bait xyz
  6. >>> df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})
  7. A B
  8. 0 new abc
  9. 1 xyz new
  10. 2 bait xyz
  11. >>> df.replace(regex=[r'^ba.$', 'foo'], value='new')
  12. A B
  13. 0 new abc
  14. 1 new new
  15. 2  bait  xyz

Tips:传入一个字典和传入两个替换参数的默认行为不一样。

s = pd.Series([10, 'a', 'a', 'b', 'a'])

  

s.replace({'a': None}) 

相当于:

s.replace(to_replace={'a': None}, value=None, method=None)


   
  1. >>> s.replace({'a': None})
  2. 0 10
  3. 1 None
  4. 2 None
  5. 3 b
  6. 4 None
  7. dtype: object

s.replace('a', None)

相当于:

s.replace(to_replace='a', value=None, method='pad')


   
  1. >>> s.replace('a', None)
  2. 0 10
  3. 1 10
  4. 2 10
  5. 3 b
  6. 4 b
  7. dtype: object


Series.str.replace

Series.str.replace默认支持正则表达式:


   
  1. >>> se1 = pd.Series(['foo', 'fuz', np.nan])
  2. >>> se1.str.replace('f.', 'ba')
  3. 0 bao
  4. 1 baz
  5. 2 NaN
  6. dtype: object

也可以设置参数regex=False关闭:


   
  1. >>> se1.str.replace('f.''ba', regex=False)
  2. 0 bao
  3. 1 fuz
  4. 2 NaN
  5. dtype: object

当给第二个参数repl传递一个函数时,该函数接收一个正则表达式对象,返回一个字符串作为替换结果:


   
  1. >>> def f(arg):
  2. print(arg, type(arg))
  3.     return arg.group(0)
  4. >>> se1.str.replace('f.', f)
  5. <re.Match object; span=(0, 2), match='fo'> <class 're.Match'>
  6. <re.Match object; span=(0, 2), match='fu'> <class 're.Match'>
  7. 0 foo
  8. 1 fuz
  9. 2 NaN
  10. dtype: object

根据此特性实现将每个小写单词都倒序:


   
  1. >>> repl = lambda m: m.group(0)[::-1]
  2. >>> se2 = pd.Series(['foo 123', 'bar baz', np.nan])
  3. >>> se2.str.replace(r'[a-z]+', repl)
  4. 0 oof 123
  5. 1 rab zab
  6. 2 NaN
  7. dtype: object

使用正则表达式的组(提取第二组并交换大小写):


   
  1. pat = r"(?P<one>\w+) (?P<two>\w+) (?P<three>\w+)"
  2. repl = lambda m: m.group('two').swapcase()
  3. pd.Series(['One Two Three', 'Foo Bar Baz']).str.replace(pat, repl)
  4. 0 tWO
  5. 1 bAR
  6. dtype: object

还可以使用python编译好的正则表达式对象便于复用:


   
  1. import re
  2. regex_pat = re.compile(r'FUZ', flags=re.IGNORECASE)
  3. pd.Series(['foo', 'fuz', np.nan]).str.replace(regex_pat, 'bar')
  4. 0 foo
  5. 1 bar
  6. 2 NaN
  7. dtype: object

文章来源: xxmdmst.blog.csdn.net,作者:小小明-代码实体,版权归原作者所有,如需转载,请联系作者。

原文链接:xxmdmst.blog.csdn.net/article/details/105985763

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。