Python 环境加载中…

把几张表拼起来

3 道练习题·预计 45 分钟·做对一题解锁下一段

完整通读本章 →

教学 01 / 08· 已读

前言

前面几章,每次分析的都只是一张表。可真实的数据,常常是分散在好几张表里的。

两点书店的数据就是这样,分成了两张表。books.csv 是书目,记着每本书的书名、作者、类别、价格。book_reviews.csv 是读者的评分,一条评分占一行,只记了是给哪个编号的书、打了几分、哪天打的。

那么,要是想知道「哪一类书评分最高」呢?这时候两张表缺一不可:评分在一张表里,类别却在另一张表里。所以,得先把它们合并起来。

这一章就来学两种合并的办法:一种是按某一列「对上号」,左右拼起来;另一种是把几张一样的表,上下接起来。

学这一章之前,需要先学完 数据分析课第 6 章 。

目录

这一章会学到:

  • 一、两张表怎么对上号——认识「键」
  • 二、左右拼起来——merge()
  • 三、对不上号的行去哪儿了——how 参数
  • 四、上下接起来——pd.concat()
  • 五、常见坑
  • 六、自己查一次文档——用 indicator 看清每一行从哪儿来
  • 七、小结与回看

学完这一章,数据分散在几张表里也不用怕了:你能先把它们拼成一张,再接着用前面学的本事去分析。

教学 02 / 08· 已读

一、两张表怎么对上号

两张表要合并,首先得知道它们靠什么连在一起。咱们先看看评分表里都记了些什么:

Python· 可在网页运行
import pandas as pd

reviews = pd.read_csv('book_reviews.csv')
print(reviews.shape)
print(reviews.head(3))

输出的结果:

文本
(834, 4)
   review_id  book_id  score        date
0          1      111      4  2025-01-01
1          2       49      2  2025-01-02
2          3      106      4  2025-01-02

可以看到,评分表一共有 834 条评分。每一条里,和书有关的只有一个 book_id ,也就是书的编号。比如第一条评分,是给 111 号书的,打了 4 分。那 111 号书叫什么、是什么类别呢?这张表里可就没有了。

书名和类别,都记在书目表里。再从书目表里挑三列出来看看:

Python· 可在网页运行
import pandas as pd

books = pd.read_csv('books.csv')
print(books[['id', 'title', 'category']].head(3))

输出的结果:

文本
   id               title category
0   1      轻松玩转自动化     编程
1   2  小账本里的通货膨胀     经济
2   3            早起养花     生活

两边对比一下就会发现:书目表里的 id ,就是评分表里的 book_id 。两张表就是靠这个编号对上号的。评分表说「111 号书打了 4 分」,那就去书目表里找 id 是 111 的那一行,一看就知道是哪本书了。

像这样用来对号的列,叫做键(key)。它就像身份证号一样,一个编号只对应一本书。

看到这里,很多童鞋可能会问:「为什么不在评分表里直接写上书名呢?」因为一本书有好几条评分,要是书名、作者、类别、价格每条都写一遍,就太浪费了;而且万一哪本书改了价格,还得把它所有的评分都改一遍。所以,数据常常分成几张表,各管各的,再用键连在一起。等到要分析的时候,再把它们合并起来。

那么,具体怎么合并呢?下一节就来动手。

教学 03 / 08

二、左右拼起来

按键把两张表左右拼起来,用的是 merge() 。不过,这两张表里键的列名不一样:评分表里叫 book_id ,书目表里叫 id 。所以要分别告诉它:left_on 写左边那张表的列名,right_on 写右边那张表的列名:

Python· 可在网页运行
import pandas as pd

books = pd.read_csv('books.csv')
reviews = pd.read_csv('book_reviews.csv')
merged = reviews.merge(books, left_on='book_id', right_on='id')
print(merged.shape)
print(merged[['review_id', 'book_id', 'title', 'category', 'score']].head(3))

输出的结果:

文本
(834, 14)
   review_id  book_id           title category  score
0          1      111  小账本里的保险     经济      4
1          2       49      月亮的冒险     童书      2
2          3      106    一个人的厨房     生活      4

读这行合并的代码,先要分清谁在左、谁在右。reviews.merge(books, ...) 里,reviews 在左,books 在右。合并的时候,每一条评分都会拿着自己的 book_id ,去书目表里找到 id 一样的那一行,再把那一行拼到自己的右边。

再看输出的第一行。拼完以后还是 834 行,因为仍然是每条评分占一行;列却变成了 14 列,也就是评分表的 4 列,加上书目表的 10 列。这样一来,每条评分旁边,就都有了书名和类别。

有了类别,前言里那个问题「哪一类书评分最高」,就能回答了。用的还是第 6 章的老本事,按类别分组:

Python· 可在网页运行
import pandas as pd

books = pd.read_csv('books.csv')
reviews = pd.read_csv('book_reviews.csv')
merged = reviews.merge(books, left_on='book_id', right_on='id')
print(merged.groupby('category')['score'].agg(['count', 'mean']).round(2).sort_values('mean', ascending=False))

输出的结果:

文本
          count  mean
category             
设计        107  3.83
编程        107  3.68
小说        100  3.59
童书         88  3.50
经济        106  3.50
科普        108  3.38
历史        100  3.36
生活        118  3.25

从结果看,设计类的书评分最高,平均 3.83 分;生活类收到的评分最多,平均分却是最低的。

所以说,合并只是一个开头。表拼好了以后,筛选、分组、排序,前几章学的本事都能接着用。

不过,这回每一条评分都对上了号,拼完一行也没少。要是有的行对不上号,又会怎么样呢?下一节就来看看。在那之前,先做一道练习:给评分配上书名。

练习 1 / 3给评分配上书名题目有问题?

读进两张表,把评分表和书目表按书的编号合并,然后只取 review_id 、title 、score 三列,打印前 5 行。

运行后的输出应该是:

文本
   review_id               title  score
0          1      小账本里的保险      4
1          2          月亮的冒险      2
2          3        一个人的厨房      4
3          4            好好收纳      4
4          5  小账本里的通货膨胀      4
main.py
可编辑
做对当前题解锁下一段 ·03

推荐一个,全网最全最友好的中文 AI 编程指南: coding.stormzhang.ai

学习目录