如何在Pandas中对整列和整行应用公式

966 阅读9分钟

Python pandas.apply()是Dataframe类中的一个成员函数,用于沿Dataframe的轴线应用一个函数。例如,沿着每一行或每一列。Pandas DataFrame是二维数据结构;例如,数据是以表格的方式在行和列中排列。在本教程中,我们将看到如何在Pandas中对整个列和行应用公式,并举例说明。

如何将公式应用于整列和整行

Pandas.dataframe.apply()函数用于沿DataFrame的轴应用函数。传递给该函数的对象是系列对象,其索引是DataFrame的索引(axis=0)或DataFrame的列(axis=1)。

默认情况下(result_type=None),最终的返回类型是由应用函数的返回类型推断出来的。否则,它取决于 result_type 参数。

语法

DataFrame.apply(func, axis=0, broadcast=None, raw=False, reduce=None, result_type=None, args=(), **kwds)

参数

  • func:这是一个要应用到每一行或每一列的函数。这个函数接受系列并返回一个系列。
  • :它是一个轴,在数据框架中沿着这个轴应用函数。默认值为0。
    • 如果一个值是0,那么它将对每一列应用一个函数。
    • 如果数值为1,那么它将对每一行应用一个函数。
  • args:它可以是一个元组或参数列表,以传递给函数。

对Pandas数据框架应用函数的例子

在这个例子中,你应该已经在你的机器上安装了pandas库,并确保你定义了正确的路径;否则,你就不能在你的程序中正确解决pandas包。

让我们来定义一个有3列5行的数据框架。

请看下面的代码:

import pandas as pd

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print(dfObj)

输出

(pythonenv) ➜  pyt python3 app.py
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
(pythonenv) ➜  pyt

所以,我们已经定义了5*3矩阵(5行3列)

对数据框架中的每一行或每一列应用lambda函数

Python lambda或匿名函数是一种没有定义名称的函数。标准函数是用def关键字定义的,而在Python中,匿名函数是用lambda关键字定义的。

比方说,我们有一个lambda函数,它接受一个数列作为参数,通过在给定数列的每个值中乘以11来返回新的数列对象。

lambda a : a * 11

好的,现在让我们看看如何将上述lambda函数应用于我们数据框架的每一行或每一列。

Python Pandas 对每一列应用lambda函数

我们可以将lambda a: a * 11函数应用到数据框架中的每一列,将lambda函数作为唯一的参数传给Dataframe.apply()中的上述创建的数据框架对象。

请看下面的代码:

import pandas as pd

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Lambda Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying lambda function
modDfObj = dfObj.apply(lambda a: a * 11)
print('After Lambda Function applied')
print(modDfObj)

输出

(pythonenv) ➜  pyt python3 app.py
Before Lambda Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Lambda Function applied
     x     y     z
0  121   231   209
1  242   462   418
2  363   693   627
3  484   924   836
4  605  1155  1045

由于dataframe(x, y, z)中有3列,所以我们的lambda函数被调用了三次,每次调用时,列将作为参数传递给 lambda函数。

由于我们的lambda函数通过将给定列中每个元素的值侵犯11来返回系列的副本。这个返回的系列取代了数据框架副本中的列。

所以,Dataframe.apply()为每一列调用传递的lambda函数,并将列的内容作为系列传递给这个lambda函数。

最后,它返回一个用lambda函数返回的列构建的修改后的数据框架副本,而不是改变原始数据框架。

Python Pandas。对每一行应用一个lambda函数

我们可以将lambda函数应用于数据框架中的每一行,将lambda函数作为第一个参数传递,同时在Dataframe.apply()中将axis=1作为第二个参数传递给上面创建的数据框架对象。

让我们把Lambda函数改为a: a + 2,看看输出:

import pandas as pd

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Lambda Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying lambda function
modDfObj = dfObj.apply(lambda a: a + 2, axis=1)
print('After Lambda Function applied')
print(modDfObj)

输出结果

(pythonenv) ➜  pyt python3 app.py
Before Lambda Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Lambda Function applied
    x    y   z
0  13   23  21
1  24   44  40
2  35   65  59
3  46   86  78
4  57  107  97

在上面的例子中,Pandas Dataframe.apply()为每一行调用传递的Lambda函数,并将每一行的内容作为系列给这个Lambda函数。

最后,它返回一个由lambda函数返回的行构建的数据框架的修改副本,而不是改变原始数据框架。

Python pandas 应用一个numpy函数的行或列

在真实世界的python应用中,我们将已经存在的numpy函数应用于数据框架的列和行。

让我们将numpy.square()函数应用于数据框架的行和列。

请看下面的代码:

import pandas as pd
import numpy as np

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Numpy square() Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying numpy square function
modDfObj = dfObj.apply(np.square)
print('After Numpy square() Function applied')
print(modDfObj)

输出

(pythonenv)   pyt python3 app.py
Before Numpy square() Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Numpy square() Function applied
      x      y     z
0   121    441   361
1   484   1764  1444
2  1089   3969  3249
3  1936   7056  5776
4  3025  11025  9025

我们也可以通过传递一个额外的参数将numpy.square()函数应用于每一行而不是每一列。请看下面的代码。

import pandas as pd
import numpy as np

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Numpy sqrt() Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying numpy sqrt function
modDfObj = dfObj.apply(np.sqrt, axis=1)
print('After Numpy sqrt() Function applied')
print(modDfObj)

输出

(pythonenv) ➜  pyt python3 app.py
Before Numpy sqrt() Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Numpy sqrt() Function applied
          x          y         z
0  3.316625   4.582576  4.358899
1  4.690416   6.480741  6.164414
2  5.744563   7.937254  7.549834
3  6.633250   9.165151  8.717798
4  7.416198  10.246951  9.746794

Python pandas 应用还原函数行或列

到目前为止,我们必须应用一种接受每一列或每一行作为序列并返回相同大小的序列的函数。

但是我们也可以调用一个接受系列并返回单个变量而不是系列的函数。

例如,让我们对数据框架中的每一列应用numpy.sum()来找出每一列中每个值的总和。

请看下面的代码:

import pandas as pd
import numpy as np

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Numpy sum() Reduce Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying sum reduce function
modDfObj = dfObj.apply(np.sum)
print('After Numpy sum() Reduce Function applied')
print(modDfObj)

输出

(pythonenv) ➜  pyt python3 app.py
Before Numpy sum() Reduce Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Numpy sum() Reduce Function applied
x    165
y    315
z    285
dtype: int64

现在让我们将numpy.sum()应用于数据框架中的每一行,找出每一行中每个值的总和:

import pandas as pd
import numpy as np

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before Numpy sum() Reduce Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying sum reduce function
modDfObj = dfObj.apply(np.sum, axis=1)
print('After Numpy sum() Reduce Function applied')
print(modDfObj)

输出

(pythonenv) ➜  pyt python3 app.py
Before Numpy sum() Reduce Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After Numpy sum() Reduce Function applied
0     51
1    102
2    153
3    204
4    255
dtype: int64

Python Pandas 应用一个用户定义的函数

让我们来定义一个UDF(用户定义函数):

def subtractData(x):
   return x - 2

如果你传递任何参数,那么它将从该数字中减去2并返回。

现在,让我们在我们的DataFrame例子中使用这个函数:

import pandas as pd
import numpy as np

matrix = [(11, 21, 19), (22, 42, 38), (33, 63, 57), (44, 84, 76),
          (55, 105, 95)]

# user-defined function
def subtractData(x):
    return x - 2


# Create a DataFrame object
dfObj = pd.DataFrame(matrix, columns=list('xyz'))
print('Before subtractData() Function applied')
print(dfObj)
print('------------------')

# modify the dataframe by applying subtractData() function
modDfObj = dfObj.apply(subtractData)
print('After subtractData() Function applied')
print(modDfObj)

输出

(pythonenv) ➜  pyt python3 app.py
Before subtractData() Function applied
    x    y   z
0  11   21  19
1  22   42  38
2  33   63  57
3  44   84  76
4  55  105  95
------------------
After subtractData() Function applied
    x    y   z
0   9   19  17
1  20   40  36
2  31   61  55
3  42   82  74
4  53  103  93

因此,它将从矩阵的每一项中减去2并返回修改后的DataFrame。

最后,在Pandas的例子中,如何将公式应用于整个列或行或整个数据框架,已经结束。