返回介绍

第34单元 组合数据

发布于 2024-01-28 22:01:16 字数 6397 浏览 0 评论 0 收藏 0

使用series或frame时,有用的数据可能存在于多个frame中,因此可能需要组合数据以备进一步处理。pandas提供了合并和连接frame的函数——你只需要判断是否需要合并或连接。

合并

frame的合并类似于数据库表的合并:pandas将左侧和右侧frame中具有相同索引(或其他指定列中具有相同值)的行组合在一起。如果左侧frame与右侧frame中相匹配的行是唯一的,则称该类型的合并为一对一合并。当有多个匹配时,该类型的合并称为一对多合并。对于一对多合并而言,pandas会根据需要复制左侧frame的行,而复制可能会导致行的重复(我们将在下一小节介绍如何处理重复的行)。当两个frame中都有多行相匹配时,这种合并类型称为多对多合并,而pandas还是会根据需要进行行复制,并将numpy.nans插入缺失数据的单元。

如果两个frame具有一个名称相同的列(即键列),就可以将该列上的frame合并。即使没有这样的列,也可以指定其他列作为键,如下所示:

df = pd.merge(df1, df2, on="key")
df = pd.merge(df1, df2, left_on="key1", right_on="key2")

使用美国人口普查局截至2009年7月1日的数据5,建立一个关于美国人口的frame。除了包含每个州的人口数据,该frame还包含美国东部、东北部、西北部、中西部、西部和南部,以及整个美国的人口数据。

5www.census.gov/popest/data/historical/2000s/vintage_2009/state.html

   population.head()

➾                       PopulationStateWyoming                   544270District of Columbia      599657Vermont                   621760North Dakota              646844Alaska                    698473

population和alco2009这两个frame都具有“State”索引,因此可以将索引删除,把两个frame在公共列上的所有内容合并,同时观察酒的消费量和人口数量:

   df = pd.merge(alco2009.reset_index(),
                 population.reset_index()).set_index("State")
   df.head()

➾            Beer  Wine  Spirits  PopulationStateAlabama    1.20  0.22     0.58     4708708Alaska     1.31  0.54     1.16      698473Arizona    1.19  0.38     0.74     6595778Arkansas   1.07  0.17     0.60     2889450California 1.05  0.55     0.73    36961664

如果两个frame中有相同名称的列,则pandas会将后缀"_l"和"_r"添加到列名称中。使用可选参数suffixes(两个字符串组成的元组)控制后缀。如果要在索引列而不是一般的列上合并,请使用可选参数left_index=True和right_index=True(可以同时使用或单独使用)。以下语句的结果与之前的相同,但默认的排序顺序可能存在差异:

   df = pd.merge(alco2009, population, left_index=True, right_index=True)
   df.head()

➾                      Beer  Wine  Spirits  PopulationStateWyoming              1.45  0.22     1.10      544270District of Columbia 1.26  1.00     1.64      599657Vermont              1.36  0.63     0.70      621760North Dakota         1.63  0.25     1.16      646844Alaska               1.31  0.54     1.16      698473

如果两个索引都是键,就要使用join()函数替换上述的merge()函数:

   population.join(alco2009).tail(10)

➾              Population  Beer  Wine  SpiritsStateIllinois       12910409  1.22  0.39     0.73Florida        18537969  1.21  0.48     0.92New York       19541453  0.91  0.46     0.69Texas          24782302  1.42  0.28     0.58California     36961664  1.05  0.55     0.73Northeast      55283679   NaN   NaN      NaNMidwest        66836911   NaN   NaN      NaNWest           71568081   NaN   NaN      NaNSouth         113317879   NaN   NaN      NaNUnited States 307006550   NaN   NaN      NaN

join()和merge()这两个函数使用同一个可选参数how,它的可接受值为"left"(join()函数的默认值)、"right"、"inner"(merge()函数的默认值)或"outer"。左连接使用调用函数的frame(即左侧frame)的索引。右连接使用作为参数的frame(即右侧frame)的索引。外连接使用索引的并集。内连接使用索引的交集。(pandas的连接类型与先前在第18单元中介绍的MySQL连接类型一致。)

如果frame的索引不相同,则左连接(或合并)、右连接(或合并)和外连接(或合并)操作将引入具有缺失值的行。在上述例子中,这种情况发生在啤酒、葡萄酒和烈酒的总量未知的地方。内连接(或合并)不会引入新的缺失值。

如果两个frame具有名称相同的列,则必须提供可选参数lsuffix和rsuffix(这两个参数都是字符串)。pandas会将后缀附加到公共的列名称之后。

join()函数还可以使用可选参数on,实现在共享的列名称上连接两个frame(但不能用名称不同的列,或者一个是列而另一个是索引)。

连接

concat()函数通过将一组frame彼此“竖直”(axis=0,默认值)或“水平”(axis=1)地放置在一起来连接它们,并返回一个新的frame:

   pd.concat([alco2009, population], axis=1).tail()

➾               Beer  Wine  Spirits  PopulationWashington    1.09  0.51     0.74     6664195West           NaN   NaN      NaN    71568081West Virginia 1.24  0.10     0.45     1819777Wisconsin     1.49  0.31     1.16     5654774Wyoming       1.45  0.22     1.10      544270

如果frame的维度不匹配,pandas就会在所谓的“空位”处加入具有缺失值的行或列。

pandas忠实地保留所有竖直堆叠的frame的索引,这可能导致索引出现重复的键。这并不妨碍你的使用,当然你也可以选择删除重复的项(具体方法将在下一小节介绍),或者通过可选参数keys(字符串列表),给新的frame添加二级索引,从而形成分层索引。对于“水平”方向的(逐列的)连接,可以使用相同的参数创建分层列名。

我们使用加拿大统计局网站6的数据,创建一个关于2011年加拿大省份人口的frame。接下来我们就可以创建一个新的frame来描述北美国家人口,结合美国和加拿大的两个人口的frame,可以给出一个合适的新索引。(请注意,美国的frame比加拿大的早两年。)

6www.statcan.gc.ca/tables-tableaux/sum-som/l01/cst01/demo02a-eng.htm

   pop_na = pd.concat([population, pop_ca], keys=["US", "CA"])
   pop_na.index.names = ("Country", "State")

➾                           PopulationCountry StateUS      Wyoming               544270District of Columbia  599657Vermont               621760North Dakota          646844Alaska                698473«...»CA      Alberta               3790200British Columbia      4499100Yukon                   35400Northwest Territories   43500Nunavut                 34200

请记住,必要时,分层索引可以被扁平化。

 两个frame应该进行合并还是连接呢?

merge()和concat()都可以将两个或多个frame组合在一起。concat()用于组合具有相似内容的frame(比如美国各州和加拿大各省的人口:“苹果到苹果”),而merge()则用于组合具有互补内容的frame(比如人口和酒精消费率:“苹果到橘子”)。

删除重复行

函数duplicated([subset])返回一个布尔型的series,表示在所有列或subset表示的列中是否有重复的行(subset是一个列名称组成的序列)。可选参数keep用于控制标记的重复行是第一个重复行("first")、最后一个重复行("last"),还是每个(True)重复行都标记。

函数drop_duplicates()返回一个删除了所有列或subset表示的列中重复行的frame或series(subset是一个列名称组成的序列)。可选参数keep用于控制删除的行是第一个重复行("frist")、最后一个重复行("last"),还是每个(True)重复行都删除。使用可选参数inplace=True可以从原始对象中删除重复项。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文