【问题标题】:Conditional merge and transformation of data in pandaspandas中数据的条件合并和转换
【发布时间】:2022-01-05 20:56:35
【问题描述】:

我有两个数据框,我想使用第 2 帧的属性在第 1 帧中创建新列

第 1 帧

    Name
    alice
    bob
    carol

第 2 帧

    Name  Type  Value
    alice lower 1
    alice upper 2
    bob   equal 42
    carol lower 0

想要的结果

第 1 帧

    Name   Lower Upper
    alice      1     2
    bob       42    42
    carol      0    NA
    

因此,两个框架的共同列是名称。您可以使用 Name 来查找(变量的)边界,这些边界在第二帧中指定。框架 1 将每个名称仅列出一次。第 2 帧每帧可能有一个或两个条目,它们可能指定一个下限或一个上限(或者如果类型相同,则同时指定两者)。我们不需要为每个变量设置两个边界,其中一个边界可以保持为空。我想要一个列出每个变量范围的框架。我知道如何在列上使用 for 循环来做到这一点,但这似乎不符合 pandas 的精神。您对紧凑型解决方案有什么建议吗? :-) 提前致谢

【问题讨论】:

    标签: pandas dataframe csv merge


    【解决方案1】:

    您不是在寻找合并,而是在寻找 pivot

    (df2[df2['Name'].isin(df1['Name'])]
     .pivot('Name', 'Type', 'Value')
     .reset_index()
    )
    

    但这并不能处理特殊的“相等”情况。

    为此,您可以使用一个小技巧。将 'equal' 替换为具有其他两个值和 explode 的列表以创建两行。

    (df2[df2['Name'].isin(df1['Name'])]
     .assign(Type=lambda d: d['Type'].map(lambda x: {'equal': ['lower', 'upper']}.get(x,x)))
     .explode('Type')
     .pivot('Name', 'Type', 'Value')
     .reset_index()
     .convert_dtypes()
    )
    

    输出:

        Name  lower  upper
    0  alice      1      2
    1    bob     42     42
    2  carol      0   <NA>
    

    【讨论】:

    • 它不处理 'equal' 值。
    • 对,我不得不说我没看过。你可以用where填写,有机会我会更新的
    • @Alex867 修复了它(我使用了不同的方法)
    • 这非常有帮助,非常感谢!事后看来,我可能已经找到了第一部分,但如果没有你的帮助,我不可能在任何合理的时间内找到第二部分。现在我知道了一些需要阅读和研究的新功能。
    • @T-Mo 第二部分还有其他策略。可以在旋转后检查“equal”中是否有值,如果为 True,则将其他列设置为该值,然后删除“equal”,但我发现这个 hack 很好 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    相关资源
    最近更新 更多