Pandas的clip和replace正则替换

举报
小小明-代码实体 发表于 2021/10/11 23:42:02 2021/10/11
5.9k+ 0 0
【摘要】 之前已发布 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用于对超过或者低于某些值的数进行截断。

准备示例数据:


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

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


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

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


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

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



DataFrame或Series的replace方法

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


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

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


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

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


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

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

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


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

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

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


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

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


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

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


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

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


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

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


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

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


       >>> df.replace(regex=r'^ba.$', value='new')
             A    B
       0   new  abc
       1   foo  new
       2  bait  xyz
       >>> df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})
             A    B
       0   new  abc
       1   xyz  new
       2  bait  xyz
       >>> df.replace(regex=[r'^ba.$', 'foo'], value='new')
             A    B
       0   new  abc
       1   new  new
       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)


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

s.replace('a', None)

相当于:

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


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


Series.str.replace

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


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

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


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

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


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

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


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

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


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

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


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

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

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

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

作者其他文章

评论(0

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

    全部回复

    上滑加载中

    设置昵称

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

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

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