3.数据预览与预处理

本文最后更新于 2025年7月27日 晚上

初始化与加载数据

在开始之前,我们还是需要先导入 pandas 库,并加载本期练习所需的数据集 TOP250.xlsx

1
2
3
4
import pandas as pd

# 加载数据
df = pd.read_excel("TOP250.xlsx")

数据查看

拿到一个数据集后,首要任务就是像侦探一样,从不同角度审视它,了解其规模、结构和内容。

1. 查看数据维度

  • 题目: 先看看数据多少行,多少列,对接下来的处理量心里有个数。
  • 答案:
    1
    df.shape
  • 解释:
    • df.shape 是 DataFrame 的一个属性(注意后面没有括号),它会返回一个**元组 (tuple)**。
    • 元组的第一个元素代表行数,第二个元素代表列数
    • 这是了解数据规模最快、最直接的方法。

2. 随机查看5条数据

  • 题目: 随机查看5条数据。
  • 答案:
    1
    df.sample(5)
    • 解释:
    • df.sample(n) 是一个非常有用的方法,它可以从 DataFrame 中随机抽取 n 条数据。
    • 为什么要用随机查看?相比于只看开头或结尾的数据,随机抽样能更客观地反映数据集中间部分的情况,避免因数据排序带来的片面印象。

3. 查看数据前后5行

  • 题目: 查看数据前后5行。
  • 答案:
    1
    2
    3
    4
    5
    # 查看前5行
    df.head()

    # 查看后5行
    df.tail()
  • 解释:
    • df.head(n) 查看 DataFrame 的前 n 行(默认为 5)。
    • df.tail(n) 查看 DataFrame 的后 n 行(默认为 5)。
    • 这两个方法可以帮助我们快速检查数据是否加载正确,表头是什么,数据的大致格式,以及是否有明显的排序规律。

4. 查看数据基本信息

  • 题目: 看看数据类型,有无缺失值什么的。
  • 答案:
    1
    df.info()
  • 解释:
    • df.info() 是数据概览的“神器”,它会打印出 DataFrame 的摘要信息,包括:
      • 索引类型和范围: RangeIndex: 250 entries, 0 to 249
      • 总列数: Data columns (total 10 columns):
      • 每列的信息:
        • 列名: 如 片名
        • 非缺失值数量: 248 non-null,这直接告诉我们该列有多少缺失值(总行数 - 非缺失值数量)。
        • 数据类型 (Dtype): 如 object (通常是字符串)、float64 (浮点数)、int64 (整数)。
      • 内存占用: memory usage: ...

5. 查看数据统计信息|数值

  • 题目: 查看 数值型 列的统计信息,计数、均值什么的。
  • 答案:
    1
    df.describe()
  • 解释:
    • df.describe() 会对所有数值类型(如 int64, float64)的列进行描述性统计,输出包括:
      • count: 非缺失值的数量
      • mean: 平均值
      • std: 标准差
      • min: 最小值
      • 25%, 50%, 75%: 分别代表第一、第二(中位数)、第三四分位数
      • max: 最大值
    • 这能帮我们快速了解数值数据的分布情况,比如评分范围、评价人数的量级等。

6. 查看数据统计信息|离散

  • 题目: 查看 离散型 列的统计信息,计数、频率什么。
  • 答案:
    1
    df.describe(include=['object'])
  • 解释:
    • describe() 方法可以通过 include 参数来指定要统计的数据类型。
    • include=['object'] 表示我们只想看对象类型(通常是字符串)列的统计信息,输出包括:
      • count: 非缺失值的数量
      • unique: 有多少个不重复的类别
      • top: 出现次数最多的类别是什么
      • freq: top 类别出现的次数

7. 查看数据统计信息|整体

  • 题目: 查看 全部 列的统计信息。
  • 答案:
    1
    df.describe(include='all')
  • 解释:
    • include='all' 会将数值型和离散型列的统计信息合并在一起展示。
    • 对于数值列,离散型统计(如 unique, top)会显示为 NaN;反之亦然。

缺失值处理

数据很少是完美的,缺失值是家常便饭。处理缺失值是数据预处理的核心步骤。

8. 计算缺失值|总计

  • 题目: 看看一共存在多少个缺失值。
  • 答案:
    1
    df.isnull().sum().sum()
  • 解释:
    • df.isnull(): 这个操作会返回一个和 df 同样大小的 DataFrame,但元素是布尔值 (True/False)。True 表示该位置是缺失值 (NaN),False 则表示不是。
    • df.isnull().sum(): 对布尔值 DataFrame 按列求和。True 被当作 1,False 被当作 0。所以结果是一个 Series,显示每列的缺失值数量。
    • df.isnull().sum().sum(): 对上一步得到的 Series 再次求和,得到整个 DataFrame 的总缺失值数量

9. 计算缺失值|分列

  • 题目: 再看看具体每列有多少缺失值。
  • 答案:
    1
    df.isnull().sum()
  • 解释:
    • 这就是上一步的中间结果,它清晰地列出了每一列包含的缺失值个数,让我们能定位到问题所在的列。

10. 查看缺失值

  • 题目: 看看全部缺失值所在的行。
  • 答案:
    1
    df[df.isnull().any(axis=1)]
  • 解释:
    • df.isnull(): 得到布尔值 DataFrame。
    • .any(axis=1): any() 方法用于检查是否有任何 True 存在。axis=1 表示按行检查。所以,如果某一行有任意一个单元格是 True(即有缺失值),any() 就会返回 True
    • df[...]: 最后,我们用这个布尔值的 Series 来过滤原始的 DataFrame,就只筛选出了那些至少包含一个缺失值的行。

11. 高亮缺失值

  • 题目: 将缺失值进行高亮进一步查看。
  • 答案:
    1
    df.style.highlight_null(color='red')
  • 解释:
    • df.style 会返回一个 Styler 对象,允许我们对 DataFrame 的显示样式进行美化(这在 Jupyter Notebook 中特别有用)。
    • .highlight_null() 是一个样式函数,它会自动找到所有的缺失值,并用指定的颜色(这里是红色)进行高亮。这比纯文本查看要直观得多。

12. 删除缺失值

  • 题目: 将缺失值出现的行全部删掉。
  • 答案:
    1
    df_no_na = df.dropna()
  • 解释:
    • dropna() 是处理缺失值最简单粗暴的方法。
    • 默认情况下(how='any'),它会删除任何包含至少一个缺失值的行。
    • 注意: 这是一种有损操作,可能会丢失大量信息,尤其是在数据稀疏的情况下,所以使用前要慎重。

13. 缺失值补全|整体填充

  • 题目: 将全部缺失值替换为 *
  • 答案:
    1
    df_filled_star = df.fillna('*')
  • 解释:
    • fillna() 是用于填充缺失值的核心方法。
    • 当给它传入一个具体的值(如字符串 *、数字 0 等)时,它会将 DataFrame 中所有的 NaN 都替换成这个值。

14. 缺失值补全|向上填充

  • 题目: 将评分列的缺失值,替换为上一个电影的评分。
  • 答案:
    1
    df['评分'] = df['评分'].ffill()
  • 解释:
    • ffill() (forward fill) 会用前一个非缺失值来填充当前的缺失值。
    • 因为数据是按评分排序的,这种方法在一定程度上是合理的。与之对应的是 bfill() (backward fill),用后一个值来填充。

15. 缺失值补全|整体均值填充

  • 题目: 将评价人数列的缺失值,用整列的均值进行填充。
  • 答案:
    1
    2
    mean_value = df['评价人数'].mean()
    df['评价人数'] = df['评价人数'].fillna(mean_value)
  • 解释:
    • 这是处理数值型特征缺失值最常用的方法之一。
    • df['评价人数'].mean() 计算出该列的平均值。
    • 然后将这个计算出的平均值作为 fillna() 的参数,对该列的缺失值进行填充。

16. 缺失值补全|上下均值填充

  • 题目: 将评价人数列的缺失值,用上下数字的均值进行填充。
  • 答案:
    1
    df['评价人数'] = df['评价人数'].interpolate()
  • 解释:
    • interpolate() 是一个更高级的填充方法,专门用于数值数据。
    • 默认情况下,它使用线性插值。简单来说,如果一个值缺失了,它会取其“邻居”(上一个和下一个有效值)的平均值来填充。这通常比用整列的均值填充更精确。

17. 缺失值补全|匹配填充

  • 题目: 填充 “语言” 列的缺失值,要求根据 “国家/地区” 列的值进行填充。

  • 答案: (这里提供两种思路)

    方法一:使用 groupbytransform (更强大灵活)

    1
    df['语言'] = df.groupby('国家/地区')['语言'].transform(lambda x: x.mode()[0] if not x.mode().empty else None)

    方法二:创建映射字典后填充 (更易于理解)

    1
    2
    3
    4
    5
    # 1. 创建一个“国家/地区”到“最常见语言”的映射
    lang_map = df.groupby('国家/地区')['语言'].apply(lambda x: x.mode()[0] if not x.mode().empty else None)

    # 2. 填充缺失值
    df['语言'] = df['语言'].fillna(df['国家/地区'].map(lang_map))
  • 解释:

    • 这是一个非常经典的分组填充问题,核心思想是:用同一组内的数据特征来填充缺失值。
    • groupby('国家/地区'): 首先按“国家/地区”列进行分组。
    • ['语言']: 在每个分组内,我们关注“语言”这一列。
    • x.mode()[0]: 对于每个国家分组内的所有语言 (x),我们计算**众数 (mode)**,也就是出现次数最多的语言,并取第一个结果 ([0])。
    • transform: 它的强大之处在于,它会将计算结果(每个分组的众数)“广播”回原始的 DataFrame 形状,可以直接用于赋值。
    • 第二种方法思路更清晰,先创建一个映射关系,再用 .map() 方法根据“国家/地区”列的值去查找对应的语言来填充,两者效果一致。

重复值处理

重复的数据行会影响统计分析的准确性,需要识别并处理。

18. 查找重复值

  • 题目: 将全部重复值所在的行筛选出来。
  • 答案:
    1
    df[df.duplicated()]
  • 解释:
    • df.duplicated() 会返回一个布尔 Series。对于某一行,如果它与前面出现过的某一行完全相同,则标记为 True
    • 用这个布尔 Series 过滤 DataFrame,即可找出所有(除第一次出现外的)重复行。

19. 查找重复值|指定

  • 题目: 查找 片名 列全部重复的行。
  • 答案:
    1
    df[df.duplicated(subset=['片名'], keep=False)]
  • 解释:
    • subset=['片名']: duplicated 方法的 subset 参数让我们只根据指定的列(这里是 片名)来判断是否重复,而不是比较整行。
    • keep=False: 这是一个关键参数。默认的 keep='first' 只会标记第二次、第三次出现的重复项为 True。而 keep=False 会将所有出现重复的项(包括第一次出现的)都标记为 True。这能帮助我们看到所有相关的重复记录。

20. 删除重复值

  • 题目: 删除全部的重复值。
  • 答案:
    1
    df_deduplicated = df.drop_duplicates()
  • 解释:
    • drop_duplicates() 是用于删除重复行的方法。
    • 默认情况下(keep='first'),它会删除所有重复的行,只保留第一次出现的那一行。

21. 删除重复值|指定

  • 题目: 删除全部的重复值,但保留最后一次出现的值。
  • 答案:
    1
    df_deduplicated_last = df.drop_duplicates(keep='last')
  • 解释:
    • keep='last' 参数会改变删除逻辑,删除所有重复的行,但保留最后一次出现的那一行。

3.数据预览与预处理
https://blog.wyyy.dpdns.org/2025/3-数据预览与预处理/
作者
lwy
发布于
2025年7月27日
许可协议