关于*多键*外连接的默认/填充值

2024-05-22

注意:下面的帖子是“多键”对应的先前的问题 https://stackoverflow.com/q/39748976/559827我的。先前问题的解决方案仅适用于连接位于单个键上的情况,并且我不清楚如何将这些解决方案推广到下面介绍的多键情况。因为,IME,以取消其收到的答案资格的方式修改一个已经回答的问题,在 SO 中是不受欢迎的,所以我单独发布这个变体。我还发布了一个question https://meta.stackoverflow.com/q/335424/559827向 Meta SO 询问我是否应该删除这篇文章并修改原始问题,但代价是使其当前答案无效。


以下是我正在使用的更大/复杂数据帧的微小/玩具版本:

>>> A
  key1 key2         u         v         w         x
0    a    G  0.757954  0.258917  0.404934  0.303313
1    b    H  0.583382  0.504687       NaN  0.618369
2    c    I       NaN  0.982785  0.902166       NaN
3    d    J  0.898838  0.472143       NaN  0.610887
4    e    K  0.966606  0.865310       NaN  0.548699
5    f    L       NaN  0.398824  0.668153       NaN

  key1 key2         y         z
0    a    G  0.867603       NaN
1    b    H       NaN  0.191067
2    c    I  0.238616  0.803179
3    d    G  0.080446       NaN
4    e    H  0.932834       NaN
5    f    I  0.706561  0.814467

(FWIW,在这篇文章的末尾,我提供了生成这些数据帧的代码。)

我想在这些数据帧上生成一个外部连接key1 and key2列,这样由外连接引起的新位置将获得默认值 0.0。 IOW,期望的结果看起来像这样

  key1 key2         u         v         w         x          y         z
0    a    G  0.757954  0.258917  0.404934  0.303313   0.867603       NaN
1    b    H  0.583382  0.504687       NaN  0.618369        NaN  0.191067
2    c    I       NaN  0.982785  0.902166       NaN   0.238616  0.803179
3    d    J  0.898838  0.472143       NaN  0.610887   0.000000  0.000000
4    e    K  0.966606   0.86531       NaN  0.548699   0.000000  0.000000
5    f    L       NaN  0.398824  0.668153       NaN   0.000000  0.000000
6    d    G  0.000000  0.000000  0.000000  0.000000   0.080446       NaN
7    e    H  0.000000  0.000000  0.000000  0.000000   0.932834       NaN
8    f    I  0.000000  0.000000  0.000000  0.000000   0.706561  0.814467

(请注意,这个所需的输出包含一些 NaN,即那些已经存在于A or B.)

The merge方法让我到达那里,但填充的默认值是 NaN,而不是 0.0:

>>> C = pandas.DataFrame.merge(A, B, how='outer', on=('key1', 'key2'))
>>> C
  key1 key2         u         v         w         x         y         z
0    a    G  0.757954  0.258917  0.404934  0.303313  0.867603       NaN
1    b    H  0.583382  0.504687       NaN  0.618369       NaN  0.191067
2    c    I       NaN  0.982785  0.902166       NaN  0.238616  0.803179
3    d    J  0.898838  0.472143       NaN  0.610887       NaN       NaN
4    e    K  0.966606  0.865310       NaN  0.548699       NaN       NaN
5    f    L       NaN  0.398824  0.668153       NaN       NaN       NaN
6    d    G       NaN       NaN       NaN       NaN  0.080446       NaN
7    e    H       NaN       NaN       NaN       NaN  0.932834       NaN
8    f    I       NaN       NaN       NaN       NaN  0.706561  0.814467

The fillna方法无法产生所需的输出,因为它修改了一些应保持不变的位置:

>>> C.fillna(0.0)
  key1 key2         u         v         w         x         y         z
0    a    G  0.757954  0.258917  0.404934  0.303313  0.867603  0.000000
1    b    H  0.583382  0.504687  0.000000  0.618369  0.000000  0.191067
2    c    I  0.000000  0.982785  0.902166  0.000000  0.238616  0.803179
3    d    J  0.898838  0.472143  0.000000  0.610887  0.000000  0.000000
4    e    K  0.966606  0.865310  0.000000  0.548699  0.000000  0.000000
5    f    L  0.000000  0.398824  0.668153  0.000000  0.000000  0.000000
6    d    G  0.000000  0.000000  0.000000  0.000000  0.080446  0.000000
7    e    H  0.000000  0.000000  0.000000  0.000000  0.932834  0.000000
8    f    I  0.000000  0.000000  0.000000  0.000000  0.706561  0.814467

如何高效地达到预期的输出? (性能在这里很重要,因为我打算在比此处显示的数据帧大得多的数据帧上执行此操作。)


重要的:为了使示例保持最小,我使多键仅包含两列;实际上,多钥匙中的钥匙数量可能要多得多。建议的答案应该适合由至少六列组成的多键。


FWIW,下面是生成示例数据帧的代码A and B.

from pandas import DataFrame
from collections import OrderedDict
from random import random, seed

def make_dataframe(rows, colnames):
    return DataFrame(OrderedDict([(n, [row[i] for row in rows])
                                 for i, n in enumerate(colnames)]))

maybe_nan = lambda: float('nan') if random() < 0.4 else random()

seed(0)

A = make_dataframe([['A', 'g', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()],
                    ['B', 'h', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()],
                    ['C', 'i', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()],
                    ['D', 'j', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()],
                    ['E', 'k', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()],
                    ['F', 'l', maybe_nan(), maybe_nan(), maybe_nan(), maybe_nan()]],
                   ('key1', 'key2', 'u', 'v', 'w', 'x'))

B = make_dataframe([['A', 'g', maybe_nan(), maybe_nan()],
                    ['B', 'h', maybe_nan(), maybe_nan()],
                    ['C', 'i', maybe_nan(), maybe_nan()],
                    ['D', 'g', maybe_nan(), maybe_nan()],
                    ['E', 'h', maybe_nan(), maybe_nan()],
                    ['F', 'i', maybe_nan(), maybe_nan()]],
                   ('key1', 'key2', 'y', 'z'))

Set the keys作为两者的索引DF's:

def index_set(frame, keys=['key1', 'key2']):
    frame.set_index(keys, inplace=True)
    return frame

子集化DF's含有NaN values:

def nulls(frame):
    nulls_in_frame = frame[frame.isnull().any(axis=1)].reset_index()
    return nulls_in_frame

加入两个Df's。连接已连接的DF与每个子集NaN含有DF's并删除填充剩余的重复值NaN留下0。

然后,使用combine_first使用链接操作和连接来修补值DF.

def perform_join(fr_1, fr_2, keys=['key1', 'key2']):
    fr_1 = index_set(fr_1); frame_2 = index_set(fr_2)
    frame = fr_1.join(fr_2, how='outer').reset_index()
    cat_fr_1 = pd.concat([frame, nulls(fr_1)]).drop_duplicates(keys, keep=False).fillna(0)
    cat_fr_2 = pd.concat([frame, nulls(fr_2)]).drop_duplicates(keys, keep=False).fillna(0)
    fr_1_join = frame.combine_first(frame.fillna(cat_fr_1[fr_1.columns]))
    joined_frame = fr_1_join.combine_first(frame.fillna(cat_fr_2[fr_2.columns]))
    return joined_frame

Finally,

perform_join(A, B)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于*多键*外连接的默认/填充值 的相关文章

随机推荐

  • 使用 Python37 运行时通过 Cloud Functions 生成缩略图

    我有一个由 Firebase 存储触发的 Google Cloud 函数 我想生成缩略图 虽然 Node js 文档有一个使用 ImageMagick 的示例 https cloud google com functions docs tu
  • 如何拦截全局资源加载?

    背景 我需要使用翻译 SDK Lokalise 文档here https docs lokalise com en articles 3487109 lokalise android sdk 2 0 beta 旨在从其服务器加载字符串资源
  • 简单循环的速度[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我用Java做了一个简单的循环只是为了测试速度 与 C 中的相同循环相比 它需要更多的时间 20亿次迭代大约需要6 5秒当它被执行时
  • 您可以使用未命名的命名空间来隐藏标头中的常量吗?

    我在头文件的命名空间中包含一些内联函数 目前无法将它们移动到 cpp 文件中 其中一些内联函数使用魔术常量 例如 Foo h namespace Foo const int BAR 1234 inline void someFunc Do
  • 如何授予 SQL Server 代理访问权限以便能够写入/修改系统文件?

    我的工作有一个存储过程 运行 BCP 来查询一些数据 如果我单独运行 QUERYOUT 命令 它就会起作用 但是 如果我尝试在作业中运行它 它会创建文件但 挂起 并且数据永远不会放入文件中 这会永远挂起 所以我通常终止 BCP exe 我的
  • 向 Laravel 的 Mailer 添加新的传输驱动程序

    我需要向 Laravel 的邮件包添加一个新的传输驱动程序 以便我可以通过默认情况下不支持的外部服务 Mailjet 发送电子邮件 编写传输驱动程序不会成为问题 但我找不到一种方法来连接并添加新的驱动程序 以便我可以继续正常使用 Larav
  • 将空行添加到文字输出 RMarkdown

    再会 我正在尝试使用导出到 Word 文档的 rmarkdown 文件创建会议摘要提交 我正在尝试找到一种在输出的word文档中插入空行的方法 我发现可以通过在 Markdown 文件末尾添加两个空格来插入换行符 但是 当您只需要一个空行时
  • Plotly:使用循环添加轨迹

    I just learn Plotly and I am trying to make my python code better This is my dataframe 为了形象化 这是我的代码 但我认为它可以通过 For 循环来完成
  • ASP MVC 3 RequireHttps 属性将所有链接更改为 https

    我有一个 ASP MVC 3 网站 其中包含反馈表并且应该需要 SSL 现在 我在名为 ContactUs 的控制器内有一个名为 反馈 的操作 负责查看和处理反馈 当我使用 RequireHttps 该操作上的属性 效果很好 并将 URL
  • Flask SQLAlchemy 无法在 venv 中设置属性错误[重复]

    这个问题在这里已经有答案了 我正在学习身份验证功能Flask SQLAlchemy 因此构建非常基本的应用程序 用户 属性 姓名 电子邮件和密码 能够注册和登录 重定向到虚拟个人资料页面 仅此而已 令人费解的行为是 如果我使用虚拟环境 我所
  • 如何让 TypeScript 从 node_modules 捆绑第 3 方库?

    我想要使 用 TypeScript 编译器node modules firebase firebase d ts检查我的代码并捆绑node modules firebase firebase js到我从 firebase 导入内容的一些文件
  • 将多个 Future[Seq] 连接成一个 Future[Seq]

    如果没有 Future 这就是我将所有较小的 Seq 组合成一个大 Seq 的方式flatmap category getCategoryUrlKey id Int Seq Meta main method val appDomains S
  • Python for ios解释器[重复]

    这个问题在这里已经有答案了 可能的重复 iOS 上的 Python 或 Ruby 解释器 https stackoverflow com questions 4772591 python or ruby interpreter on ios
  • 实体类型处于“影子状态”意味着什么?

    在我的 ASP NET Core 1 0 MVC6 EF7 Web 应用程序中 我添加了一个迁移 该迁移添加了新的相关表 和相应的模型 我有以下模型快照 DbContext typeof ApplicationDbContext parti
  • nginx上传client_max_body_size问题

    我正在运行 nginx ruby on rails 并且有一个简单的多部分表单来上传文件 一切正常 直到我决定限制要上传的文件的最大大小 为此 我设置了 nginxclient max body size to 1m 1MB 并且当该规则被
  • 如何诊断和修复 git fatal: 无法读取树

    我在用着git管理项目上的文件 并不断遇到这个问题 当我跑步时git status我收到消息 fatal unable to read tree e2d920161d41631066945a3cbcd1b043de919570 据我了解 我
  • 检查SQS队列是否为空的有效方法

    我有一个SQS Queue多个主机从中读取消息 我想在处理队列中的所有消息后运行一些作业 业务逻辑 如何检查队列是否为空 是的 我可以检查ApproximateNumberOfMessages and ApproximateNumberOf
  • 比较 jdbc 中的结果集

    在我的java代码中 我获得了两个结果集rs1和rs2 如下所示 rs1 statement executeQuery select from tableA rs2 statement executeQuery select from ta
  • 如何使用 C# 了解 Excel 中的分页符 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 C 创建并格式化 Excel 电子表格 因此我需要格式化 合并单元格 更改字体等 直到第一页的最后 如何知道 Excel 电子
  • 关于*多键*外连接的默认/填充值

    注意 下面的帖子是 多键 对应的先前的问题 https stackoverflow com q 39748976 559827我的 先前问题的解决方案仅适用于连接位于单个键上的情况 并且我不清楚如何将这些解决方案推广到下面介绍的多键情况 因