如何合并多个表中的数据

In [1]: import pandas as pd

本教程使用的数据

空气质量:二氧化氮数据

本教程使用OpenAQ提供、通过py-openaq包下载的二氧化氮(NO₂)空气质量数据。

air_quality_no2_long.csv数据集包含巴黎、安特卫普和伦敦三个测量站FR04014、BETR801、London Westminster的NO₂值。查看原始数据。

In [2]: air_quality_no2 = pd.read_csv("data/air_quality_no2_long.csv",
   ...:                               parse_dates=True)
   ...:

In [3]: air_quality_no2 = air_quality_no2[["date.utc", "location",
   ...:                                    "parameter", "value"]]
   ...:

In [4]: air_quality_no2.head()
Out[4]:
                    date.utc location parameter  value
0  2019-06-21 00:00:00+00:00  FR04014       no2   20.0
1  2019-06-20 23:00:00+00:00  FR04014       no2   21.8
2  2019-06-20 22:00:00+00:00  FR04014       no2   26.5
3  2019-06-20 21:00:00+00:00  FR04014       no2   24.9
4  2019-06-20 20:00:00+00:00  FR04014       no2   21.4

空气质量:颗粒物数据

本教程还使用OpenAQ提供、通过py-openaq包下载的粒径小于2.5微米的颗粒物空气质量数据。

air_quality_pm25_long.csv数据集包含巴黎、安特卫普和伦敦三个测量站FR04014、BETR801、London Westminster的PM₂.₅值。查看原始数据。

In [5]: air_quality_pm25 = pd.read_csv("data/air_quality_pm25_long.csv",
   ...:                                parse_dates=True)
   ...:

In [6]: air_quality_pm25 = air_quality_pm25[["date.utc", "location",
   ...:                                      "parameter", "value"]]
   ...:

In [7]: air_quality_pm25.head()
Out[7]:
                    date.utc location parameter  value
0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5

拼接对象

沿行方向拼接两个表的原文示意图
沿行方向拼接(原文示意图)。

我希望将NO₂与PM₂.₅测量数据这两个结构相似的表,合并到一个表中。

In [8]: air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0)

In [9]: air_quality.head()
Out[9]:
                    date.utc location parameter  value
0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5

concat()函数沿某个轴拼接多个表,既可按行,也可按列。

默认沿axis=0拼接,因此结果表合并了各输入表的行。检查原表与拼接后表的形状,验证这一操作:

In [10]: print('Shape of the ``air_quality_pm25`` table: ', air_quality_pm25.shape)
Shape of the ``air_quality_pm25`` table:  (1110, 4)

In [11]: print('Shape of the ``air_quality_no2`` table: ', air_quality_no2.shape)
Shape of the ``air_quality_no2`` table:  (2068, 4)
In [12]: print('Shape of the resulting ``air_quality`` table: ', air_quality.shape)
Shape of the resulting ``air_quality`` table:  (3178, 4)

因此,结果表有3178行,即1110 + 2068。

按日期时间排序,也能展示两个表已经合并。parameter列标识来源:no2来自air_quality_no2,pm25来自air_quality_pm25。

In [13]: air_quality = air_quality.sort_values("date.utc")

In [14]: air_quality.head()
Out[14]:
                       date.utc            location parameter  value
100   2019-05-07 01:00:00+00:00             BETR801      pm25   12.5
1109  2019-05-07 01:00:00+00:00  London Westminster      pm25    8.0
1003  2019-05-07 01:00:00+00:00             FR04014       no2   25.0
1098  2019-05-07 01:00:00+00:00             BETR801       no2   50.5
2067  2019-05-07 01:00:00+00:00  London Westminster       no2   23.0

这个特定示例中的parameter列能识别每个原表,但并非总有这样的列。concat通过keys参数提供方便的解决方案:增加一层行索引。例如:

In [15]: air_quality_ = pd.concat([air_quality_pm25, air_quality_no2], keys=["PM25", "NO2"])

In [16]: air_quality_.head()
Out[16]:
                         date.utc location parameter  value
PM25 0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
     1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
     2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
     3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
     4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5

关于多重索引,见用户指南中的高级索引部分。

关于按行与按列拼接的更多选项,以及如何用concat指定其他轴上索引的并集或交集逻辑,见对象拼接部分。

通过共同标识符连接表

用共同标识符进行左连接的原文示意图
按共同标识符左连接(原文示意图)。

将测量站元数据表提供的站点坐标,加到测量表的对应行中。

In [17]: stations_coord = pd.read_csv("data/air_quality_stations.csv")

In [18]: stations_coord.head()
Out[18]:
  location  coordinates.latitude  coordinates.longitude
0  BELAL01              51.23619                4.38522
1  BELHB23              51.17030                4.34100
2  BELLD01              51.10998                5.00486
3  BELLD02              51.12038                5.02155
4  BELR833              51.32766                4.36226
In [19]: air_quality.head()
Out[19]:
                       date.utc            location parameter  value
100   2019-05-07 01:00:00+00:00             BETR801      pm25   12.5
1109  2019-05-07 01:00:00+00:00  London Westminster      pm25    8.0
1003  2019-05-07 01:00:00+00:00             FR04014       no2   25.0
1098  2019-05-07 01:00:00+00:00             BETR801       no2   50.5
2067  2019-05-07 01:00:00+00:00  London Westminster       no2   23.0


In [20]: air_quality = pd.merge(air_quality, stations_coord, how="left", on="location")

In [21]: air_quality.head()
Out[21]:
                    date.utc  ... coordinates.longitude
0  2019-05-07 01:00:00+00:00  ...               4.43182
1  2019-05-07 01:00:00+00:00  ...              -0.13193
2  2019-05-07 01:00:00+00:00  ...               2.39390
3  2019-05-07 01:00:00+00:00  ...               2.39390
4  2019-05-07 01:00:00+00:00  ...               4.43182

[5 rows x 6 columns]

使用merge()函数,可以为air_quality中的每一行,从站点坐标表加入相应坐标。两个表都有location列,作为合并信息的键。选择left连接后,只有左表air_quality中的位置,即FR04014、BETR801与London Westminster,才会出现在结果表中。

merge函数支持多种连接选项,类似数据库风格的操作。

接下来,把参数元数据表提供的参数完整描述与名称,加入测量表。

In [22]: air_quality_parameters = pd.read_csv("data/air_quality_parameters.csv")

In [23]: air_quality_parameters.head()
Out[23]:
     id                                        description  name
0    bc                                       Black Carbon    BC
1    co                                    Carbon Monoxide    CO
2   no2                                   Nitrogen Dioxide   NO2
3    o3                                              Ozone    O3
4  pm10  Particulate matter less than 10 micrometers in...  PM10


In [24]: air_quality = pd.merge(air_quality, air_quality_parameters,
   ....:                        how='left', left_on='parameter', right_on='id')
   ....:

In [25]: air_quality.head()
Out[25]:
                    date.utc  ...   name
0  2019-05-07 01:00:00+00:00  ...  PM2.5
1  2019-05-07 01:00:00+00:00  ...  PM2.5
2  2019-05-07 01:00:00+00:00  ...    NO2
3  2019-05-07 01:00:00+00:00  ...    NO2
4  2019-05-07 01:00:00+00:00  ...    NO2

[5 rows x 9 columns]

与前一个示例相比,这里没有同名列。不过,air_quality表的parameter列与air_quality_parameters表的id列都以相同格式表示被测变量,因此使用left_on和right_on参数,而不是单独的on,来建立两表之间的关联。

pandas也支持内连接、外连接与右连接。有关表的连接与合并,见用户指南中的数据库风格表合并,或与SQL比较页面。

记住

  • 多个表可以使用concat按列或按行拼接。
  • 数据库式表合并/连接使用merge。

用户指南提供了各种合并数据表功能的完整说明。


原文:How to combine data from multiple tables,pandas 3.0.6文档。© 2026 pandas / NumFOCUS, Inc. 按转载授权汉化。数据来源OpenAQ;示例保留原文IPython输入提示与输出,未在本环境运行。源项目许可请参阅pandas LICENSE。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容