首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

pandas系列学习(五):数据连接

pandas系列学习(一):pandas入门

pandas系列学习(二):Series

pandas系列学习(三):DataFrame

pandas系列学习(四):数据提取

pandas系列学习(五):数据连接(当前文章)

利用 Python 处理任何实际的数据时,你就需要将 pandas DataFrame 合并或者链接在一起来分析数据集,但是这个过程还是非常花费时间的,大约是 10 分钟。合并(merge)和连接(join)数据框 是任何有抱负的数据分析师需要掌握的核心过程。这篇文章介绍了合并和连接数据集的过程,即根据它们之间的公共列将两个数据集连接在一起。主要分为这些主题:

什么是两个数据帧的合并和连接?

什么是内合并,外合并,左合并,右合并?

如何合并具有不同公共列名称的两个数据帧?(lefton 和 righton 语法)

示例数据

对于这篇文章,我从 KillBiller 应用程序和一些别的地方下载的数据,这些数据包含在三个 CSV 文件中:

user_usage.csv: 第一个数据集包含用户每月移动使用情况统计信息;

user_device.csv: 第二个数据集包含系统的单独 “使用” 的详细信息,包括日期和设备信息;

android_devices.csv: 第三个数据集包含设备和制造商数据,其中列出了从Google获取的所有Android设备及其型号代码;

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

来自 KillBiller 应用程序的示例使用信息,显示一部分用户的每月移动使用情况统计信息。

来自 KillBiller 应用程序的用户信息,为 KillBiller 应用程序的各个 “用途” 提供设备和操作系统版本。

Android 设备数据,包含所有具有制造商和型号详细信息的 Android 设备。

注意重要的样本数据集之间存在连接属性:userusage 和 userdevice 之间共享 useid ,而 userdevice 的 device 列和设备数据集的 Model 列包含公共代码。

举个例子

我们想知道不同设备之间用户的使用模式是否不同。例如,使用三星设备的用户使用通话时间是否比使用 LG 设备的用户多?考虑到这些数据集中的样本量较小,这是一个demo问题,但它是需要合并的完美示例。

我们希望形成一个单独的数据框,其中包含用户使用数字(每月呼叫,每月短信等)以及包含设备信息(模型,制造商等)的列。我们需要将我们的样本数据集进行合并(或者连接)到一个单独的数据集中进行分析。

合并 DataFrame

合并两个数据集是将两个数据集合并为一个数据集,并根据公共属性或者列对齐每个数据集的行的过程。

合并和连接着两个词在 pandas 和其他语言中相对可互换,即 SQL 和 R 。在 pandas 中,有单独的 merge 和 join 函数,两者都做类似的事情。

在这个场景中,我们需要执行两个步骤:

对于 userusage 数据集中的每一行——创建一个包含 userdevice 数据帧中的 device 代码的心裂。即对于第一行,useid 为 22787,因此我们转到 userdevices 数据集,找到 use_id 22787,并复制 device 列中的值;

完成此操作后,我们将获取新设备列,并从设备数据集中找到相应的“零售品牌”和“模型”;

最后,我们可以查看使用的设备制造商对使用情况进行拆分和分组数据的不同统计数据。

我可以使用 for 循环吗?

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

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

合并 userusage 和 userdevices

让我们看看如何使用 merge 命令将 device 和 platform 列正确添加到 user_usage 数据帧。

以上是基于公共列将 user usage 和 user devices 合并的结果。

从结果中,我们看到这个非常有效,而且很容易实现,那么 merge 命令做了一些什么呢?

pandas merge 命令如何工作。至少,合并需要左数据集,右数据集和公共列以合并。

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

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

内部(inner),左侧(left)和右侧(right)合并类型

在上面的例子中,我们将 userusage 和 userdevices 进行合并。利用 head() 查看结果发现非常棒,但是除此之外,我们还能获得更多的东西。首先,让我们看看 merge 命令的输入和输出的大小:

合并操作后数据集 result 的大小与预期不符合,即它的大小不是两个数据集大小之和。因为默认情况下, pandas merge() 默认为 inner 合并操作。内部合并(或内部连接)仅保留结果的左侧和右侧数据帧中的公共值。在上面的示例中,只有包含 userusage 和 userdevice 之间通用的 use_id 值的行扔保留在 result 数据集中。我们可以通过查看常见的值来验证这一点:

默认情况下,在 pandas 中仅保留左右数据帧之间的公共值,即我们使用了内部合并。

userusage 中有 159 个 useid 值出现在 user_device 中,这些值也出现在最终结果数据框 159 行中。

其他合并类型

pandas 中有三种不停类型的合并。这些合并类型在大多数数据库和面向数据的语言(SQL,R,SAS)中都很常见,通常称为 join 操作。如果你对合并操作不是很熟悉,可以看看下面的介绍:

inner merge:默认的 pandas 行为,仅保留左侧和右侧数据框中存在合并 on 值的行;

left merge:保留左数据框中的每一行。如果右侧数据框中存在 on 变量的缺失值,那么请在结果中添加 NaN 值;

right merge:保留右数据框中的每一行。如果左侧数据框中存在 on 变量的缺失值,那么请在结果中添加 NaN 值;

outer merge:完全外部连接返回左侧数据框中的所有行,右侧数据框中的所有行,并在可能额情况下匹配行,其他地方使用 NaN 值;

要使用的合并类型是使用 merge 命令中的 how 参数指定的,取值为 left,right,inner(默认值)或者 outer。具体可以看下图:

左合并例子

让我们重复我们的合并操作,但这次在 pandas 中执行 “左合并”。

最初,result 数据帧有 159 行,因为我们的左右数据帧之间共有 159 个 use_id 值,默认使用 inner 合并。

对于我们的左合并,我们期望 result 与我们的左数据帧 user_usage (240行)具有相同的行数,除了 159 个行是没有缺失值的,剩余 81 行都是有缺失值的;

我们希望 result 与左数据帧具有相同的行数,因为 userusage 中的每个 useid 在 userdevice 中只出现一次。一对一的映射并非总是如此。在合并操作中,左侧数据框中的单行与右侧数据框中的多行匹配,将生成多个 result 行。即如果 userusage 中的 useid 值在 userdevice 数据帧中出现两次,则在连接 result 中将有两行用于该 use_id 。

你可以使用 merge 命令的 how 参数将合并更改为 left merge。result 数据框的顶部包含成功匹配的项,而底部包含 userusage 中的 userdevice 中没有相应 use_id 的行。

在 pandas 中左连接示例。在 how 命令中指定连接类型。

右连接的例子

例如,我们可以使用右连接合并重复此过程,只需要在 pandas merge 命令中将 how

\=\=left 替换成 how==right。

预期结果将于正确的数据框 userdevice 具有相同的行数,但是来源于左数据框中的数据就会具有多个空值或者 NaN 值。userusage 中的 outgoingminspermonth,outgoingsmspermonth 和 monthlymb 会有空值,但是右侧数据框 userdevice 中的列中没有缺失值。

外部合并的例子

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

因此,我们希望 result 具有与 userdevice 和 userusage 之间的 use_id 的不同值相同的行数,即来自左数据帧的每个连接值将与来自右数据帧的每个值一起出现在 result 中。

使用 pandas 的外部合并 result 。左侧和右侧数据帧中的每一行都保留在 result 中,缺少值为 NaN 值。

在下图中,显示了外部合并 result 中的示例行,前两个是 use_id 在数据帧之间最常见的示例,后两个仅来自左侧数据帧,最后两个仅来自右侧数据帧。

使用合并指示器跟踪合并

为了帮助识别行的来源,pandas 提供了一个指标参数,可以与 merge 函数一起使用,该函数在输出中创建一个名为 _merge 的附加列,用于标记每行的原始源。

从上图的 _merge 字段我们就可以很清楚的看到每一行是来源于原始数据的左侧数据框还是右侧数据框。

最终合并——将设备详细信息加入到结果中

回到我们原来的问题,我们已经将 userusage 与 userdevice 合并,因此我们为每个用户提供了平台和设备。最初,我们在 pandas 中使用了 inner merge 作为默认值,因此,我们只为具有设备信息的用户提供条目。我们将使用左连接重做此合并以保留所有用户,然后使用第二个左合并最终使设备制造商处于同一数据帧中。

使用 lefton 和 righton 与不同的列名合并

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

使用 lefton 和 righton 参数为 pandas 中的合并指定了不同的列名,而不是仅使用 on 参数。

根据设备计算统计数据

随着我们的合并完成,我们可以使用 pandas 的数据聚合功能来快速计算出基于设备制造商的用户的平均使用情况。请注意,小样本量会创建更小的组,因此我不会将这些特定结果归因于任何统计意义。

作者:chen_h

CoderPai 是一个专注于人工智能在量化交易应用的算法实战平台,主要关注人工智能在量化交易上面的应用。如果你对人工智能感兴趣,请快快关注 “CoderPai” 微信号(coderpai)吧。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181028G14V7900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券