条件逻辑:`np.where`, `df.mask`, `df.where` 实现复杂条件

条件逻辑大乱炖:np.where, df.mask, df.where,让你的数据“听话”!

各位屏幕前的程序猿、攻城狮、数据挖掘小能手们,大家好!我是你们的老朋友,数据魔法师——阿Q! 今天咱们要聊点儿刺激的,深入探讨一下在数据处理中那些“指哪打哪”的条件逻辑操作。 想象一下,你手握一份庞大的数据宝藏,想要从中淘出符合特定条件的金子,或者给不听话的数据来个“乾坤大挪移”,让它们乖乖听你的话。 那么,np.where, df.mask, df.where 这三位“大神”就是你手中的利器!

准备好了吗? 让我们一起踏上这场条件逻辑的奇妙之旅吧!🚀

一、故事的开端:为什么要玩转条件逻辑?

在开始正式讲解之前,咱们先来唠唠嗑,聊聊为什么要学习这些看似“高深莫测”的条件逻辑函数。

想象一下,你是一位古代的皇帝,面对堆积如山的奏折(数据),你不可能每个都亲自过目,而是需要制定一系列的规则(条件),让你的臣子(程序)帮你筛选出重要的信息,比如:

  • “凡是奏报边疆战事的,一律呈上来!”
  • “凡是涉及民生的,优先处理!”
  • “凡是歌功颂德的,统统打回!”

在数据分析的世界里,我们也是一样的。 原始数据往往杂乱无章,我们需要根据特定的条件,从中提取有用的信息,进行数据清洗、转换、分析等等。 如果没有条件逻辑,就像没有指南针的航海家,只能在数据的海洋里迷失方向。 🌊

举个栗子:

假设你有一份电商平台的销售数据,你想找出所有销售额超过1000元的订单,并给这些订单打上“VIP”的标签。 这就要用到条件逻辑啦!

所以,掌握条件逻辑,就像掌握了一把开启数据宝藏的钥匙!🔑

二、三位“大神”登场:np.where, df.mask, df.where

好了,废话不多说,让我们隆重请出今天的主角:

  • np.where (NumPy 大法): NumPy 的当家花旦,擅长处理数组(array)类型的条件逻辑。
  • df.mask (DataFrame 面具): Pandas DataFrame 的变形大师,能根据条件“遮盖”或替换数据。
  • df.where (DataFrame 守护): Pandas DataFrame 的守护者,只有满足条件的数据才能“幸存”。

这三位“大神”各有千秋,掌握了它们,你就能在数据的世界里呼风唤雨,让数据乖乖听话!

1. np.where: NumPy 的条件利器

np.where 是 NumPy 库中的一个函数,它根据指定的条件,返回数组中满足条件的元素的索引,或者根据条件选择不同的值。

语法:

np.where(condition, x, y)
  • condition: 一个布尔类型的数组,表示条件。
  • x: 当 conditionTrue 时,返回的值。
  • y: 当 conditionFalse 时,返回的值。

功能:

np.where 就像一个三元运算符,它根据条件,从 xy 中选择对应的值。

栗子时间:

假设我们有一个 NumPy 数组:

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

现在,我们想要找出所有大于 5 的元素,并将它们替换为 100,其余元素保持不变。

new_arr = np.where(arr > 5, 100, arr)
print(new_arr)
# 输出:[  1   2   3   4   5 100 100 100 100 100]

解释:

  • arr > 5 返回一个布尔类型的数组: [False False False False False True True True True True]
  • 当条件为 True 时,np.where 选择 100,否则选择 arr 中对应的值。

更高级的用法:

np.where 还可以嵌套使用,实现更复杂的条件逻辑。 比如,我们可以根据不同的条件,给不同的元素赋予不同的值。

new_arr = np.where(arr > 7, 200, np.where(arr > 5, 100, arr))
print(new_arr)
# 输出:[  1   2   3   4   5 100 100 200 200 200]

总结:

np.where 是处理 NumPy 数组条件逻辑的利器,它简单高效,能够轻松实现各种复杂的条件判断和赋值操作。

小贴士:

  • np.where 主要用于处理 NumPy 数组,对于 Pandas DataFrame,我们有更强大的工具!

2. df.mask: DataFrame 的变形大师

df.mask 是 Pandas DataFrame 的一个方法,它根据指定的条件,将 DataFrame 中满足条件的元素替换为指定的值(默认为 NaN)。

语法:

df.mask(cond, other=np.nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False)
  • cond: 一个布尔类型的 DataFrame 或 Series,表示条件。 True 表示要替换的元素。
  • other: 用于替换的值,默认为 NaN
  • inplace: 是否在原 DataFrame 上修改,默认为 False
  • axis: 轴方向,默认为 None
  • level: 多层索引的级别,默认为 None
  • errors: 错误处理方式,默认为 'raise'
  • try_cast: 是否尝试转换数据类型,默认为 False

功能:

df.mask 就像一个遮盖工具,它根据条件,将 DataFrame 中不需要的元素“遮盖”起来,或者替换为指定的值。

栗子时间:

假设我们有一个 Pandas DataFrame:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [6, 7, 8, 9, 10],
    'C': [11, 12, 13, 14, 15]
})
print(df)
# 输出:
#    A   B   C
# 0  1   6  11
# 1  2   7  12
# 2  3   8  13
# 3  4   9  14
# 4  5  10  15

现在,我们想要将 DataFrame 中所有大于 8 的元素替换为 0。

new_df = df.mask(df > 8, 0)
print(new_df)
# 输出:
#    A  B   C
# 0  1  6   0
# 1  2  7   0
# 2  3  8   0
# 3  4  0   0
# 4  5  0   0

解释:

  • df > 8 返回一个布尔类型的 DataFrame,True 表示对应位置的元素大于 8。
  • df.mask 将所有 True 对应的元素替换为 0。

更高级的用法:

df.mask 可以结合 inplace=True 参数,直接在原 DataFrame 上修改数据,避免创建新的 DataFrame。

df.mask(df < 3, inplace=True)
print(df)
# 输出:
#      A     B     C
# 0  NaN   6.0  11.0
# 1  NaN   7.0  12.0
# 2  3.0   8.0  13.0
# 3  4.0   9.0  14.0
# 4  5.0  10.0  15.0

总结:

df.mask 是 DataFrame 中进行条件替换的强大工具,它可以根据条件,将 DataFrame 中不需要的元素替换为指定的值,方便进行数据清洗和转换。

小贴士:

  • df.mask 默认将满足条件的元素替换为 NaN, 可以通过 other 参数指定替换的值。
  • inplace=True 参数可以节省内存空间,但要注意修改会直接影响原 DataFrame。

3. df.where: DataFrame 的守护者

df.where 是 Pandas DataFrame 的另一个方法,它根据指定的条件,保留 DataFrame 中满足条件的元素,将不满足条件的元素替换为指定的值(默认为 NaN)。

语法:

df.where(cond, other=np.nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False)
  • cond: 一个布尔类型的 DataFrame 或 Series,表示条件。 True 表示要保留的元素。
  • other: 用于替换的值,默认为 NaN
  • inplace: 是否在原 DataFrame 上修改,默认为 False
  • axis: 轴方向,默认为 None
  • level: 多层索引的级别,默认为 None
  • errors: 错误处理方式,默认为 'raise'
  • try_cast: 是否尝试转换数据类型,默认为 False

功能:

df.where 就像一个过滤器,它根据条件,只保留 DataFrame 中满足条件的元素,将不满足条件的元素“过滤”掉,或者替换为指定的值。

栗子时间:

还是用上面的 DataFrame:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [6, 7, 8, 9, 10],
    'C': [11, 12, 13, 14, 15]
})
print(df)
# 输出:
#    A   B   C
# 0  1   6  11
# 1  2   7  12
# 2  3   8  13
# 3  4   9  14
# 4  5  10  15

现在,我们想要保留 DataFrame 中所有小于 10 的元素,将其余元素替换为 100。

new_df = df.where(df < 10, 100)
print(new_df)
# 输出:
#      A    B    C
# 0  1.0  6.0  100
# 1  2.0  7.0  100
# 2  3.0  8.0  100
# 3  4.0  9.0  100
# 4  5.0  100  100

解释:

  • df < 10 返回一个布尔类型的 DataFrame,True 表示对应位置的元素小于 10。
  • df.where 只保留所有 True 对应的元素,将其余元素替换为 100。

更高级的用法:

df.where 可以结合 inplace=True 参数,直接在原 DataFrame 上修改数据。 另外,df.where 还可以接受一个 DataFrame 作为 other 参数,用于替换不满足条件的元素。

df2 = pd.DataFrame({
    'A': [100, 200, 300, 400, 500],
    'B': [600, 700, 800, 900, 1000],
    'C': [1100, 1200, 1300, 1400, 1500]
})

df.where(df < 5, df2, inplace=True)
print(df)
# 输出:
#       A      B      C
# 0   1.0  600.0  1100.0
# 1   2.0  700.0  1200.0
# 2   3.0  800.0  1300.0
# 3   4.0  900.0  1400.0
# 4 500.0 1000.0 1500.0

总结:

df.where 是 DataFrame 中进行条件过滤的利器,它可以根据条件,只保留 DataFrame 中满足条件的元素,方便进行数据筛选和分析。

小贴士:

  • df.where 默认将不满足条件的元素替换为 NaN, 可以通过 other 参数指定替换的值。
  • df.wheredf.mask 的功能正好相反, df.where 保留满足条件的元素, df.mask 替换满足条件的元素。 可以根据实际需求选择使用。

三、实战演练:让数据“听话”!

光说不练假把式! 咱们来几个实际的例子,看看如何利用这三位“大神”让数据乖乖听话。

场景一:电商平台数据清洗

假设你拿到了一份电商平台的订单数据,其中包含订单号、商品名称、用户ID、订单金额、支付状态等信息。 你需要对这份数据进行清洗,找出所有未支付的订单,并将它们的支付状态修改为“已取消”。

import pandas as pd
import numpy as np

data = {
    'order_id': [1, 2, 3, 4, 5],
    'product_name': ['A', 'B', 'C', 'D', 'E'],
    'user_id': [101, 102, 101, 103, 102],
    'order_amount': [100, 200, 300, 400, 500],
    'payment_status': ['paid', 'unpaid', 'paid', 'unpaid', 'paid']
}

df = pd.DataFrame(data)
print(df)
# 输出:
#    order_id product_name  user_id  order_amount payment_status
# 0         1            A      101           100           paid
# 1         2            B      102           200         unpaid
# 2         3            C      101           300           paid
# 3         4            D      103           400         unpaid
# 4         5            E      102           500           paid

df['payment_status'] = np.where(df['payment_status'] == 'unpaid', 'cancelled', df['payment_status'])
print(df)
# 输出:
#    order_id product_name  user_id  order_amount payment_status
# 0         1            A      101           100           paid
# 1         2            B      102           200      cancelled
# 2         3            C      101           300           paid
# 3         4            D      103           400      cancelled
# 4         5            E      102           500           paid

场景二:学生成绩分析

假设你有一份学生成绩数据,其中包含学生姓名、科目、成绩等信息。 你需要对这份数据进行分析,找出所有不及格的科目,并将它们的成绩标记为“不及格”。

import pandas as pd
import numpy as np

data = {
    'student_name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'subject': ['Math', 'English', 'Math', 'English', 'Math'],
    'score': [80, 55, 90, 45, 70]
}

df = pd.DataFrame(data)
print(df)
# 输出:
#   student_name  subject  score
# 0        Alice     Math     80
# 1          Bob  English     55
# 2      Charlie     Math     90
# 3        David  English     45
# 4          Eve     Math     70

df['score'] = df['score'].mask(df['score'] < 60, '不及格')
print(df)
# 输出:
#   student_name  subject   score
# 0        Alice     Math      80
# 1          Bob  English     不及格
# 2      Charlie     Math      90
# 3        David  English     不及格
# 4          Eve     Math      70

场景三: 股票数据处理

假设你有一份股票数据,其中包含股票代码、日期、开盘价、收盘价、最高价、最低价等信息。 你需要对这份数据进行处理,找出所有收盘价低于开盘价的日期,并将它们的收盘价标记为“下跌”。

import pandas as pd
import numpy as np

data = {
    'stock_code': ['AAPL', 'AAPL', 'AAPL', 'AAPL', 'AAPL'],
    'date': ['2023-10-26', '2023-10-27', '2023-10-28', '2023-10-29', '2023-10-30'],
    'open_price': [170, 172, 175, 173, 171],
    'close_price': [171, 170, 174, 175, 172],
    'high_price': [172, 173, 176, 176, 173],
    'low_price': [169, 168, 172, 171, 169]
}

df = pd.DataFrame(data)
print(df)
# 输出:
#   stock_code        date  open_price  close_price  high_price  low_price
# 0       AAPL  2023-10-26         170          171         172        169
# 1       AAPL  2023-10-27         172          170         173        168
# 2       AAPL  2023-10-28         175          174         176        172
# 3       AAPL  2023-10-29         173          175         176        171
# 4       AAPL  2023-10-30         171          172         173        169

df['close_price'] = df['close_price'].where(df['close_price'] >= df['open_price'], '下跌')
print(df)
# 输出:
#   stock_code        date  open_price close_price  high_price  low_price
# 0       AAPL  2023-10-26         170         171         172        169
# 1       AAPL  2023-10-27         172          下跌         173        168
# 2       AAPL  2023-10-28         175          下跌         176        172
# 3       AAPL  2023-10-29         173         175         176        171
# 4       AAPL  2023-10-30         171         172         173        169

四、总结:条件逻辑,数据分析的灵魂!

通过今天的学习,相信大家已经掌握了 np.where, df.mask, df.where 这三位“大神”的使用方法。 记住,条件逻辑是数据分析的灵魂,掌握了它们,你就能在数据的世界里游刃有余,轻松应对各种复杂的数据处理任务。

最后,送给大家一句至理名言:

“数据虐我千百遍,我待数据如初恋!” 💖

希望大家在数据分析的道路上越走越远,成为真正的数据魔法师!

下次再见! 😉

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注