对应书本第二部分第5章Pandas高级操作第5节
df.where()和df.mask()通过给定的条件对原数据是否满足条件进行筛选,最终返回与原数据形状相同的数据。为了方便讲解,我们仅取我们的数据集的数字部分,即只有Q1到Q4列:
# 只保留数字类型列
df = df.select_dtypes(include='number')
df.where()
df.where()中可以传入一个布尔表达式、布尔值的Series/DataFrame、序列或者可调用的对象,然后与原数据做对比,返回一个行索引与列索引与原数据相同的数据,且在满足条件的位置保留原值,在不满足条件的位置填充NaN。
# 数值大于70
df.where(df > 70)
传入一个可调用对象,这里我们用lambda:
# Q1列大于50
df.where(lambda d: d.Q1>50)
条件为一个布尔值的Series:
# 传入布尔值Series,前三个为真
df.Q1.where(pd.Series([True]*3))
上例中不满足条件的都返回为NaN,我们可以指定一个值或者算法来替换NaN:
# 大于等于60分的显示成绩,小于的显示“不及格”
df.where(df>=60, '不及格')
给定一个算法:
# c 定义一个数是否为偶数的表达式
c = df%2 == 0
# 传入c, 为偶数时显示原值减去20后的相反数
df.where(~c, -(df-20))
np.where()
np.where()是NumPy的一个功能,虽然不是Pandas提供的,但可以弥补df.where()的不足,所以有必要一起介绍。df.where()方法可以将满足条件的值筛选出来,将不满足的值替换为另一个值,但无法对满足条件的值进行替换,而np.where()就实现了这种功能,达到SQL中if(条件,条件为真的值,条件为假的值)的效果。
np.where()返回的是一个二维array:
# 小于60分为不及格
np.where(df>=60, '合格', '不合格')
可以使用df.where()来应用它:
# 让df.where()中的条件为假,从而应用np.where()的计算结果
df.where(df==9999999, np.where(df>=60, '合格', '不合格'))
下例是np.where()对一个Series(d.avg为计算出来的虚拟列)进行判断,返回一个包含是、否结果的Series。
(
df.assign(avg=df.mean(1)) # 计算一个平均数
# 通过np.where()及判断平均分是否及格
.assign(及格=lambda d: np.where(d.avg>=60, '是', '否'))
)
df.mask()
df.mask()的用法和df.where()基本相同,唯一的区别是df.mask()将满足条件的位置填充为NaN。
# 符合条件的为NaN
s = df.Q1 # 取Q1列为Series
df.mask(s > 80)
可以指定填充值:
df.Q1.mask(s > 80, '优秀')
df.mask()和df.where()还可以通过数据筛选返回布尔序列:
# 返回布尔序列,符合条件的行值为True
(df.where((df.team=='A') & (df.Q1>60)) == df).Q1
# 返回布尔序列,符合条件的行值为False
(df.mask((df.team=='A') & (df.Q1>60)) == df).Q1
df.lookup()
语法为df.lookup(行标签,列标签),返回一个numpy.ndarray,标签必须是一个序列。
# 行列相同数量,返回一个array
df.lookup([1,3,4], ['Q1','Q2','Q3']) # array([36, 96, 61])
df.lookup([1], ['Q1']) # array([36])
lookup()函数的作用就是依据行标签和列标签来取值,类似于
result = []
for row, col in zip(row_labels, col_labels):
result.append(df.get_value(row, col))
df.where()与df.mask()都可以按条件筛选数据,df.where()将不满足条件的值替换为NaN,df.mask()将满足条件的值替换为NaN。np.where()是NumPy的一个方法,在满足条件和不满足条件的情况下都可指定填充值。
网友评论