Python dataframe合并列:Pandas合并和连接数据帧(dataframe)

2021年8月13日04:01:51 发表评论 2,742 次浏览

如何实现Python dataframe合并列?在使用Python 的任何现实世界数据科学情况下,当您需要合并或连接Pandas Dataframes 以形成分析数据集时,大约需要 10 分钟。Pandas合并和连接数据帧是任何有抱负的数据分析师都需要掌握的核心过程。这篇博文介绍了合并数据集的过程和Python dataframe合并列,即将两个数据集基于它们之间的公共列连接在一起。此处涵盖的关键主题:

如果您想自己完成本教程,我正在使用来自 Anaconda 的带有Python 3.5.2的Jupyter 笔记本设置,并且我已将代码发布在 GitHub 上。我已将示例数据集包含在 GitHub 存储库中。

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
如果您需要快速入门,请合并概述(以下所有说明)!Pandas merge() 命令获取左右数据帧,根据“on”列匹配行,并执行不同类型的合并——左、右等。

Python dataframe合并列:示例数据

关于Python合并dataframe,在这篇文章中,我从KillBiller 应用程序中获取了一些真实数据和一些下载的数据,包含在三个 CSV 文件中:

  • user_usage.csv – 第一个包含用户每月移动使用统计数据的数据集
  • user_device.csv – 第二个数据集,包含系统个人“使用”的详细信息,以及日期和设备信息。
  • android_devices.csv – 包含设备和制造商数据的第三个数据集,其中列出了所有 Android 设备及其型号代码,从谷歌这里获得。

我们可以 使用 Pandas read_csv命令将这些 CSV 文件作为Pandas DataFrames 加载到 Pandas 中 ,并使用DataFrame head()命令检查内容。

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
来自 KillBiller 应用程序的示例使用信息显示了一部分用户的每月移动使用统计信息。
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
来自 KillBiller 应用程序的用户信息,为 KillBiller 应用程序的个人“使用”提供设备和操作系统版本。
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
Android 设备数据,包含所有带有制造商和型号详细信息的 Android 设备。

Pandas合并和连接数据帧:需要注意的示例数据集之间存在链接属性——“use_id”在 user_usage 和 user_device 之间共享,并且 user_device 的“device”列和设备数据集的“Model”列包含通用代码。

示例问题 - Pandas合并和连接数据帧

我们想确定不同设备之间用户的使用模式是否不同。例如,使用三星设备的用户是否比使用LG设备的用户使用更多的通话时间  ?鉴于这些数据集中的样本量很小,这是一个玩具问题,但它是需要合并的完美示例。

我们希望形成一个包含用户使用数据列(每月通话次数、每月短信等)以及设备信息列(型号、制造商等)的单个数据框。我们需要将我们的样本数据集“合并”(或“连接”)到一个单一的数据集中进行分析。

Python dataframe合并列:合并数据帧

Pandas合并和连接dataframe:“合并”两个数据集是将两个数据集合并为一个,并根据共同属性或列对齐每个数据集的行的过程。

“合并”和“连接”这两个词在 Pandas 和其他语言(即SQLR )中相对可以互换使用。在 Pandas 中,有单独的“ merge ”和“ join ”函数,两者都做类似的事情。

在这个Python dataframe合并列示例场景中,我们需要执行两个步骤:

  1. 对于 user_usage 数据集中的每一行 - 创建一个新列,其中包含来自 user_devices 数据帧的“设备”代码。即对于第一行,use_id 是 22787,所以我们转到 user_devices 数据集,找到 use_id 22787,然后复制“device”列中的值。
  2. 完成后,我们获取新的设备列,并从设备数据集中找到相应的“零售品牌”和“型号”。
  3. 最后,我们可以查看使用 的设备制造商的使用拆分和分组数据的不同统计数据。

Pandas合并和连接数据帧:我可以使用 for 循环吗?

可以。您可以为此任务编写 for 循环。第一个将遍历 user_usage 数据集中的 use_id,然后在 user_devices 中找到正确的元素。第二个 for 循环将对设备重复此过程。

但是,使用 for 循环比使用 Pandas 合并功能要慢得多,也更冗长。所以,如果你遇到这种情况——不要使用 for loops

Python dataframe合并列:将 user_usage 与 user_devices 合并

让我们看看如何使用Pandas Merge命令将“设备”和“平台”列正确添加到 user_usage 数据帧。

result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id')
result.head()
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
基于公共列将用户使用情况与用户设备合并的结果。

所以这很有效,而且很容易!现在——这是如何运作的?pd.merge 命令在做什么?

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)

合并命令是这篇文章的主要学习目标。最简单的合并操作需要一个左数据框(第一个参数)、一个右数据框(第二个参数),然后是一个合并列名,或者一个要“on”合并的列。在输出/结果中,左侧和右侧数据帧中的行匹配,其中存在由“on”指定的合并列的公共值。

有了这个结果,我们现在可以继续从“设备”数据集中获取制造商和型号。但是,首先我们需要更多地了解合并类型和输出数据帧的大小。

Python dataframe合并列:内、左、右合并类型

在上面的示例中,我们将 user_usage 与 user_devices 合并。结果的head () 预览看起来很棒,但还有更多的东西比眼睛看到的要多。首先,让我们看看合并命令的输入和输出的大小或形状

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
合并操作后数据集的结果大小可能与预期不同。Pandas merge() 默认为“内部”合并操作。

Pandas合并和连接数据帧:为什么结果与原始数据帧的大小不同?

默认情况下,Pandas 合并操作与“内部”合并一起工作。内部合并(或内部连接)仅保留左右数据帧中结果的公共值。在我们上面的示例中,只有包含 user_usage 和 user_device 之间通用的 use_id 值的行保留在结果数据集中。我们可以通过查看共有多少个值来验证这一点:

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
在 Pandas 中,默认情况下仅保留左右数据帧之间的公共值,即使用“内部”合并。

在 user_device 中出现的 user_usage 表中有 159 个 use_id 值。这些值也出现在最终结果数据框中(159 行)。

其他Python dataframe合并列类型

Pandas 提供三种不同类型的合并。这些合并类型在大多数数据库和面向数据的语言(SQLRSAS)中都很常见,通常称为“联接”。如果你不了解它们,现在就学习Pandas合并和连接数据帧。

  1. 内部合并/内部连接——默认的 Pandas 行为,只保留左右数据帧中存在合并“on”值的行。
  2. 左合并/左外连接 -(又名左合并或左连接)保留左数据框中的每一行。如果右侧数据框中的“on”变量缺失值,请在结果中添加空/NaN 值。
  3. 右合并 /右外连接-(又名右合并或右连接)将每一行保留在正确的数据框中。如果左列中的“on”变量缺失值,请在结果中添加空 / NaN 值。
  4. 外合并/全外连接—— 全外连接返回左侧数据框中的所有行、右侧数据框中的所有行,并在可能的情况下匹配行,在其他地方使用 NaN。

Python合并dataframe:使用合并命令中的“how”参数指定要使用的合并类型,取值“left”、“right”、“inner”(默认)或“outer”。

Python dataframe合并列维恩图通常用于举例说明不同的合并和连接类型。请参阅stackoverflow中的此示例:

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
Pandas、R、SQL 和其他面向数据的语言和库中使用的 Merge/Join 类型。来源:堆栈溢出。

如果这对您来说是新的,或者您皱着眉头看上面的内容,请花点时间观看Coursera上有关“合并数据帧”的视频,以获得 可能有帮助的另一种解释。现在,我们将更详细地查看每种合并类型,并逐一举例说明。

Python dataframe合并列:左合并/左连接示例

让我们重复我们的合并操作,但这次在 Pandas 中执行“左合并”,Pandas合并和连接dataframe:。

  • 最初,结果数据帧有 159 行,因为我们的左右数据帧之间共有 159 个“use_id”值,并且默认使用了“内部”合并。
  • 对于我们的左合并,我们希望结果与我们的左数据框“user_usage”(240)具有相同的行数,除了 159 个合并的“平台”和“设备”列(81 行)之外的所有列都缺少值。
  • 我们希望结果具有与左侧数据帧相同的行数,因为 user_usage 中的每个 use_id 在 user_device 中只出现一次。一对一映射并不总是如此。在左侧数据框中的单行与右侧数据框中的多行匹配的合并操作中,将生成多个结果行。即,如果 user_usage 中的 use_id 值在 user_device 数据帧中出现两次,则连接结果中将有该 use_id 的两行。

您可以使用合并命令的“how”参数将合并更改为左合并。结果数据框的顶部包含成功匹配的项目,底部包含 user_usage 中在 user_device 中没有相应 use_id 的行。

result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id', 
                 how='left')
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
Pandas 中的左连接示例。在“how”命令中指定连接类型。左连接或左合并保留左数据框中的每一行。
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
Pandas 中两个数据框的左连接或左合并的结果。左侧数据框中在右侧数据框中没有相应连接值的行将保留为 NaN 值。

右合并/右连接Python dataframe合并列示例

例如,我们可以通过右连接/右合并重复此过程,只需在 Pandas 合并命令中将how='left'替换为how='right'

result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id', 
                 how='right')

预期结果将与右侧数据框 user_device 具有相同的行数,但在源自左侧数据框 user_usage(即“outgoing_mins_per_month”、“outgoing_sms_per_month”和“monthly_mb”)的列中有几个空值或 NaN 值. 相反,我们希望来自正确数据框“user_device”的列中没有缺失值。

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
右合并或右连接的示例。请注意,输出的行数与右侧数据帧的行数相同,只有左侧数据帧中的 use_id 与左侧的任何内容都不匹配时才会丢失值。

外合并/全外连接示例

最后,我们将使用 Pandas执行外部合并,也称为“完全外部连接”或“外部连接”。外连接可以看作是左连接和右连接的组合,或者是内连接的反面。在外连接中,左右数据帧的每一行都保留在结果中,NaN 没有匹配的连接变量。

因此,我们希望结果具有相同的行数,因为 user_device 和 user_usage 之间存在不同的“use_id”值,即左侧数据框中的每个连接值都将与右侧数据框中的每个值一起出现在结果中,它们将在可能的情况下链接。

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
使用 Pandas 的外部合并结果。左右数据帧中的每一行都保留在结果中,缺少值或合并列不匹配的 numpy NaN 值。

在下图中,显示了来自外部合并结果的示例行,前两个是“use_id”在数据帧之间通用的示例,后两个仅来自左侧数据帧,最后两个仅来自右侧数据框。

使用合并指示器跟踪合并

Pandas合并和连接数据帧:为了帮助识别行的来源,Pandas 提供了一个“指示符”参数,该参数可与合并函数一起使用,该函数在输出中创建一个名为“_merge”的附加列,用于标记每一行的原始来源。

result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id', 
                 how='outer', 
                 indicator=True)
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
来自外部合并(完全外部联接)结果的示例行。请注意,包含来自左右合并数据帧的所有行,但 NaN 将位于不同的列中,具体取决于数据来自左数据帧还是右数据帧。

Python dataframe合并列 - 加入设备详细信息以获得结果

回到我们最初的问题,我们已经将 user_usage 和 user_device 合并了,所以我们有每个用户的平台和设备。最初,我们在 Pandas 中使用“内部合并”作为默认值,因此,我们只为用户提供设备信息的条目。我们将使用左连接重做此合并以保留所有用户,然后使用第二个左合并以最终获得同一数据帧中的设备制造商。

# First, add the platform and device to the user usage - use a left join this time.
result = pd.merge(user_usage,
                 user_device[['use_id', 'platform', 'device']],
                 on='use_id',
                 how='left')
# At this point, the platform and device columns are included
# in the result along with all columns from user_usage
# Now, based on the "device" column in result, match the "Model" column in devices.
devices.rename(columns={"Retail Branding": "manufacturer"}, inplace=True)
result = pd.merge(result, 
                  devices[['manufacturer', 'Model']],
                  left_on='device',
                  right_on='Model',
                  how='left')
print(result.head())
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
最终合并结果与设备制造商信息合并到用户使用表中。使用两个左合并来达到这一点。

Python dataframe合并列:使用 left_on 和 right_on 合并不同的列名

合并运算符中使用的列不需要在左右数据框中命名相同。在上面的第二个合并中,请注意设备 ID 在左侧数据框中称为“设备”,在右侧数据框中称为“型号”。

在 Pandas 中使用“left_on”和“right_on”参数为合并指定不同的列名,而不是仅使用“on”参数。

Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
使用 pandas 合并函数的 left_on 和 right_on 参数来合并具有不同名称的连接变量的数据帧。

基于设备计算统计数据

Python dataframe合并列合并完成后,我们可以使用Pandas合并dataframe的数据聚合功能,根据设备制造商快速计算出用户的平均使用情况。请注意,小样本量会创建更小的组,因此我不会将任何统计显着性归因于这些特定结果,Pandas合并和连接dataframe:

result.groupby("manufacturer").agg({
        "outgoing_mins_per_month": "mean",
        "outgoing_sms_per_month": "mean",
        "monthly_mb": "mean",
        "use_id": "count"
    })
Python dataframe合并列:Pandas合并和连接数据帧(dataframe)
最终结果使用 agg() pandas 聚合按设备制造商分组并计算出不同列的平均统计数据。

Python dataframe合并列总结

以上就是Pandas合并和连接数据帧的全部内容,这完成了本合并教程的第一部分。您现在应该已经掌握了Python dataframe合并列的基础知识:Pandas合并和连接dataframe,并且能够使用上述信息解决您自己的合并和连接问题。本博文的第 2 部分讨论了以下更高级的主题(Python合并dataframe):

  • Pandas合并dataframe:如何使用多个连接/公共列合并数据框?
  • 如何根据数据帧的索引合并数据帧?
  • Pandas 中的合并和连接功能有什么区别?
  • Python Pandas 中的合并速度有多快?
木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: