前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据处理 | 在学这几个pandas函数,继续加快你数据处理的速度

数据处理 | 在学这几个pandas函数,继续加快你数据处理的速度

作者头像
DataCharm
发布2021-04-16 11:55:57
1.2K0
发布2021-04-16 11:55:57
举报

上次我们介绍了几个pandas函数,如nlargest()pct_change()explode(),《学会这些好用的pandas函数,让你的数据处理更快人一步》让大家可以更快的求取前N组数据、计算数据之间变化率以及将列表元素数据展开为一列等等。

今天,我们再介绍几个好用的pandas函数,让大家在新增数据列数据筛选或进行数据微调的时候继续快人一步。

目录:

  • 1. 为Dataframe新增数据列
    • 1.1. assign()
    • 1.2. eval()
  • 2. 数据筛选
  • 3. 数据微调

1. 为Dataframe新增数据列

新增数据列其实是很常见的操作,一般情况下我们可以采用直接赋值法,也就是在原来的Dataframe数据上进行直接操作,比如:

代码语言:javascript
复制
>>> import  pandas as pd
>>> df = pd.DataFrame({'temp_c': [17.0, 25.0]},
...                   index=['Portland', 'Berkeley'])
>>> df
          temp_c
Portland    17.0
Berkeley    25.0
# 直接赋值法,新增一列
>>> df['temp_f'] = ['f1','f2']
>>> df
          temp_c temp_f
Portland    17.0     f1
Berkeley    25.0     f2
# 直接赋值法,修改已有列数据
>>> df['temp_c'] = [100,200]
>>> df
          temp_c temp_f
Portland     100     f1
Berkeley     200     f2

当然,我这里自然不是简单的说 直接赋值法这种操作,所以我们来看看直接赋值法可能带来的问题:

  • 如果我们想保留原有的df,新增一个df1并在新的df1上进行有关操作,直接赋值法可能会导致修改df1的时候df也发生变化的情况
代码语言:javascript
复制
>>> df1 = df
>>> df1['A'] = '直接赋值'
>>> df1
          temp_c temp_f     A
Portland     100     f1  直接赋值
Berkeley     200     f2  直接赋值
>>> df
          temp_c temp_f     A
Portland     100     f1  直接赋值
Berkeley     200     f2  直接赋值

上述这种情况,一般我们可以通过df1=df.copy()解决(深拷贝和浅拷贝的差异),具体这里不展开。

代码语言:javascript
复制
>>> df1=df.copy() # 深拷贝
>>> df1['A'] = '直接赋值'
>>> df1
          temp_c temp_f     A
Portland     100     f1  直接赋值
Berkeley     200     f2  直接赋值
>>> df
          temp_c temp_f
Portland     100     f1
Berkeley     200     f2

1.1. assign()

这个时候,我们就要介绍assign()方法了,它并不是在原来的Dataframe上进行操作,而是返回一个含原来Dataframe全部数据和新增列的Dataframe对象

代码语言:javascript
复制
>>> df = pd.DataFrame({'temp_c': [17.0, 25.0]},
...                   index=['Portland', 'Berkeley'])
>>> df
          temp_c
Portland    17.0
Berkeley    25.0
# 新增一列数据c
>>> df.assign(c= ['100','200'])
          temp_c    c
Portland    17.0  100
Berkeley    25.0  200

它还支持调用函数的方式进行赋值

代码语言:javascript
复制
>>> df.assign(temp_f= lambda x: x.temp_c * 9 / 5 + 32)
          temp_c  temp_f
Portland    17.0    62.6
Berkeley    25.0    77.0

也支持直接引用现有数据列进行相关操作

代码语言:javascript
复制
>>> df.assign(temp_f= df['temp_c'] * 9 / 5 + 32)
          temp_c  temp_f
Portland    17.0    62.6
Berkeley    25.0    77.0

关键它还支持同时进行多个数据列的新增处理

代码语言:javascript
复制
>>> df.assign(temp_f= lambda x: x['temp_c'] * 9 / 5 + 32,
...           temp_k= lambda x: (x['temp_f'] +  459.67) * 5 / 9)
          temp_c  temp_f  temp_k
Portland    17.0    62.6  290.15
Berkeley    25.0    77.0  298.15

1.2. eval()

eval()是pandas里的顶层函数,有着很牛批的作用。我们在之前《推荐几个好用的python内置函数》里关于字符串操作里介绍过python内置函数eval(),其作用是接受字符串参数,并返回该字符串的求值结果,其实在这里也差不多,具体见下面案例介绍。

比如,我们将两列的值相加

代码语言:javascript
复制
>>> df = pd.DataFrame({'A': range(1, 6), 'B': range(10, 0, -2)})
>>> df
   A   B
0  1  10
1  2   8
2  3   6
3  4   4
4  5   2
>>> df.eval('A+B')
0    11
1    10
2     9
3     8
4     7
dtype: int64
>>> df['A']+df['B']
0    11
1    10
2     9
3     8
4     7
dtype: int64

所以,基于上述,我们可以进行新增列的操作

代码语言:javascript
复制
>>> df.eval('C= A+B')
   A   B   C
0  1  10  11
1  2   8  10
2  3   6   9
3  4   4   8
4  5   2   7
>>> df
   A   B
0  1  10
1  2   8
2  3   6
3  4   4
4  5   2
# 在原数据集上进行操作
>>> df.eval('C= A+B',inplace= True)
>>> df
   A   B   C
0  1  10  11
1  2   8  10
2  3   6   9
3  4   4   8
4  5   2   7

同样,我们也可以新增多列

代码语言:javascript
复制
>>> df.eval(
...     '''
... C = A + B
... D = A - B
... '''
... )
   A   B   C  D
0  1  10  11 -9
1  2   8  10 -6
2  3   6   9 -3
3  4   4   8  0
4  5   2   7  3

需要注意的是,eval()只能对列进行操作,不能对元素或者行进行操作。

当然了,eval()还支持通过 @ 符号使用 Python 的局部变量 ,@ 符号表示“这是一个变量名称而不是一个列名”,从而让你灵活地用两个“命名空间”的资源(列名的命名空间和 Python 对象的命名空间)计算代数式。

代码语言:javascript
复制
>>> df
   A   B   C
0  1  10  11
1  2   8  10
2  3   6   9
3  4   4   8
4  5   2   7
>>> max = df.A.max()
>>> max
5
# 通过 @ 符号使用 Python 的局部变量
>>> df.eval('D = A + @max')
   A   B   C   D
0  1  10  11   6
1  2   8  10   7
2  3   6   9   8
3  4   4   8   9
4  5   2   7  10

2. 数据筛选

关于更多的数据筛选大家可以参考之前的文章《Pandas学习笔记03-数据清洗(通过索引选择数据)》,这里介绍的是query(),一个也是接收字符串表达式参数,然后返回满足条件的数据部分的方法,据说它的性能更高。

代码语言:javascript
复制
>>> df = pd.DataFrame({'A': range(1, 6),
...                    'B': range(10, 0, -2),
...                    'C C': range(10, 5, -1)})
>>> df
   A   B  C C
0  1  10   10
1  2   8    9
2  3   6    8
3  4   4    7
4  5   2    6
# 返回A列中值大于B列的数据
# 等效于 df[df.A > df.B]
>>> df.query('A>B')
   A  B  C C
4  5  2    6
# 都会B列中值等于C C列的数据
# 等效于 df[df.B == df['C C']]
>>> df[df.B == df['C C']]
   A   B  C C
0  1  10   10

更多表达式方式大家可以自行测试

3. 数据微调

这里介绍的是replace()方法,将原有数据中特定的数据用指定的数据进行替换

代码语言:javascript
复制
replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')

场景很多,比如指定的A用B替换,特定的某些数据用另外一组数据替换,满足条件的某些数据用另外的数据替换等等。

指定的A用B替换:

代码语言:javascript
复制
>>> s = pd.Series([0, 1, 2, 3, 4])
>>> s
0    0
1    1
2    2
3    3
4    4
dtype: int64
>>> 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
   A  B  C
0  0  5  a
1  1  6  b
2  2  7  c
3  3  8  d
4  4  9  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

指定某些数据用另外一组数据替换

将被替换的数用放在列表里或者用字典进行对应等(注意看案例演示)

代码语言:javascript
复制
>>> df
   A  B  C
0  0  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
# 多个指定值用对应值替换【字典】
>>> 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: 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

我们用Series数据演示一下参数 method的效果:

代码语言:javascript
复制
>>> s
0    0
1    1
2    2
3    3
4    4
dtype: int64
# 将1和2用它们前面的值替换
>>> s.replace([1,2],method = 'ffill')
0    0
1    0
2    0
3    3
4    4
dtype: int64
# 将1和2用它们前面的值替换
>>> s.replace([1,2],method = 'bfill')
0    0
1    3
2    3
3    3
4    4
dtype: int64
>>> s.replace([1,3],method = 'bfill')
0    0
1    2
2    2
3    4
4    4
dtype: int64

正则替换

这则替换就是将满足正则表达式条件的元素替换为我们想要替换的值,关于替换的方式也是有很多种的,具体大家看案例:

代码语言:javascript
复制
>>> df = pd.DataFrame({'A': ['bat', 'foo', 'bait'],
...                    'B': ['abc', 'bar', 'xyz']})
>>> df
      A    B
0   bat  abc
1   foo  bar
2  bait  xyz
# 将ba开头的元素替换为 new
>>> 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
# 同第一种方法
>>> 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

以上 就是本次全部内容了,节假日学习来吧~

当然了,要是出门玩的还是尽情happy吧,哈哈!


推荐阅读

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataCharm 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 为Dataframe新增数据列
    • 1.1. assign()
      • 1.2. eval()
      • 2. 数据筛选
      • 3. 数据微调
        • 推荐阅读
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档