1.创建一个三行两列的df对象 指定两列名为a,b 数据分别是 1,2,3 4,5,6
import pandas as pd
df = pd.DataFrame({'a':[1,2,3],'b':[4,5,6]})
df
2.模拟一个计算每行平均数的函数,并查看执行了几次.
def avg_2(x,y):
print('看看我执行了几次')
return(x+y)/2
# 通过df对象调用 avg_2()
avg_2(df['a'],df['b'])
一共执行了一次
3.尝试在上述代码的基础上 改造判断x的值是否为2 如果是2 就返回空
def avg_2(x,y):
print('看看我执行了几次')
if x==2:
return np.NAN
else:
return(x+y) /2
# 测试函数
avg_2(10,2)
一共执行了一次,且函数可以实现功能
def avg_2(x,y):
print('看看我执行了几次')
if x==2:
return np.NAN
else:
return(x+y) /2
# 测试函数
avg_2(10,2)
# 通过df对象,调用avg_2()函数对象
avg_2(df['a'],df['b'])
报错,值是不明确的.
分析原因:因为x = df['a'] 是一个Series对象 =3个值(向量),数字2 是一个标量 向量和标量无法直接运算
4.解决方案
函数向量化,函数的向量化,函数结果向量化处理后,就不再是调用一次了,而是传入一个值,就调用一次
#写法一: np.vectiorize()方式实现
import numpy as np
avg_2_vec = np.vectorize(avg_2) #avg_2_vec 就是经过向量化处理后的函数,接收到Serise对象的时候,会逐个遍历
avg_2_vec(df['a'],df['b'])
可以实现结果
第二种方法:装饰器写法
@np.vectorize # 函数的向量化操作.
def avg_2(x, y):
print('看看我执行了几次!')
if x == 2:
return np.NAN
else:
return (x + y) / 2
avg_2(df['a'], df['b']) #验证
总结
这里的x = df['a'] = 1个Series对象 = 3个值(向量) 2是1个标量, 向量 和 标量无法直接运算.需要把函数进行向量化,函数接收到Series对象的时候, 会逐个遍历, 获取其值.