【问题标题】:Python Pandas copy a set of cells within a dataframe based on a matching keyPython Pandas 根据匹配键复制数据框中的一组单元格
【发布时间】:2020-06-15 02:22:10
【问题描述】:

我对 Pandas 的了解相对有限,而且我已经在很小的基础 + 所有 SO 的帮助下完成了很多。这是我第一次发现自己陷入了死胡同。

我正在尝试找到执行以下操作的最有效方法:

我有一个 ~150000 行的 df,有 ~40 列。

这是一个用于调查解决方案的示例数据框:

   UniqueID     CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     123      12          1113
1  413-45365    1     889      75          6748
2  413-21165    8     554      13          4536
3  413-24354    1     387      35          7649
4  413-34658    2     121      88          2468
5  413-36889    4     105      76          3336
6  413-23457    5     355      42          7894
7  413-30089    5     146      10          9112
8  413-41158    5     453      91          4545
9  413-51015    9     654      66          2232

其中一列是唯一的 ID,其余列包含与该 ID 的对象对应的数据。示例:

我已经确定了 DF 之外的对象之间的合并样式关系,现在需要将数据粘贴到存在该关系的位置,从“父”ID 到其所有“子”ID。

如果我确定 413-23457 是 413-20012 和 413-21165 的父代,那么我需要从父代复制值仅在 WEIGHT、VOLUME 和 PRODUCTIVITY 列中(但不是 UniqueID 或 CST)到子对象。我还确定 413-41158 是 413-45365 和 413-51015 的父级。

我必须为跨数据框的多组这些类型的关联执行此操作。

我尝试操作大量示例代码以在数据帧之间粘贴,但我的一些要求似乎使搜索足够有用的示例变得困难。我还可以设想一种方法,使用 .itterows() 创建所有对象,然后在循环中相应地匹配和粘贴。但是,对于过去的解决方案,已经降级为 .iterrows(),并注意到它可能需要多长时间,我认为我不能在这里应用它并为更大的数据集维持它。

任何帮助将不胜感激。


根据建议的解决方案编辑附加内容

如果我重新排列输入数据框以更随机地对行进行排序,建议的答案并不能真正起到作用(我的错是没有更好地将实际数据集反映到这个测试样本中)。

起始数据框是:

   UniqueID     CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     123      12          1113
1  413-45365    1     889      75          6748
2  413-21165    8     554      13          4536
3  413-24354    1     387      35          7649
4  413-34658    2     121      88          2468
5  413-36889    4     105      76          3336
6  413-23457    5     355      42          7894
7  413-30089    5     146      10          9112
8  413-41158    5     453      91          4545
9  413-51015    9     654      66          2232

目前建议的解决方案是:

parent_child_dict = {
    '413-51015': '413-41158',
    '413-21165': '413-23457',
    '413-45365': '413-41158',
    '413-20012': '413-23457'
}

(df.merge(df.UniqueID
           .replace(parent_child_dict),
         on='UniqueID',
         how='right')
   .set_index(df.index)
   .assign(UniqueID=df.UniqueID,
          CST=df.CST)
)

结果数据框是:

    UniqueID   CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     387      35          7649
1  413-45365    1     121      88          2468
2  413-21165    8     105      76          3336
3  413-24354    1     355      42          7894
4  413-34658    2     355      42          7894
5  413-36889    4     355      42          7894
6  413-23457    5     146      10          9112
7  413-30089    5     453      91          4545
8  413-41158    5     453      91          4545
9  413-51015    9     453      91          4545

现在的结果不是预期的,因为行是随机顺序的,我不明白发生了什么。 UniqueID 为 413-45365 的行旨在镜像 413-41158 的数据,但具有一些数据组合(121、88、2468),这些数据在任何其他行甚至起始 DF 的单元格中都不存在。

【问题讨论】:

  • 您是否有将父母映射到孩子的 DataFrame 或 Dict?添加到您的帖子会很有帮助。
  • 添加了编辑。谢谢。
  • 我要做的第一件事就是将您的父子关系放入字典中。

标签: python pandas merge copy-paste


【解决方案1】:

我要做的第一件事是将您的父子关系放入字典中。然后我们可以使用replacemerge:

# create a dictionary of parent-child relationship
parent_child_dict = {}
for parent_id in parent_objects:
    children = get_merge(parent_id)
    for child in children:
        child_id = get_object_info(child)
        # update dict
        parent_child_dict[child_id] = parent_id

# parent_child_dict = {
#     '413-20012': '413-23457',
#     '413-21165': '413-23457',
#     '413-45365': '413-41158',
#     '413-51015': '413-41158'
# }

# merge and copy data back
(df.merge(df.UniqueID
           .replace(parent_child_dict),
         on='UniqueID',
         how='right')
   .set_index(df.index)
   .assign(UniqueID=df.UniqueID,
          CST=df.CST)
)

输出:

     UniqueID  CST  WEIGHT  VOLUME  PRODUCTIVITY
1   413-23457    5     355      42          7894
2   413-20012    3     355      42          7894
3   413-21165    8     355      42          7894
4   413-24354    1     387      35          7649
5   413-34658    2     121      88          2468
6   413-36889    4     105      76          3336
7   413-30089    5     146      10          9112
9   413-41158    5     453      91          4545
10  413-45365    1     453      91          4545
11  413-51015    9     453      91          4545

【讨论】:

  • 我的第一次尝试返回了一个错误:ValueError: can not merge DataFrame with instance of type of on this line: ----> 3 how ='right').set_index(df_term.index).assign(UniqueID=df.UniqueID,
  • 您可能使用了不允许与系列合并的旧熊猫。尝试用df[['Unique']]替换df.Unique
  • 是的,你在修复中成功了。代码正在运行,但复制到子 ID 行的值与父代不匹配(但它们是新值) 尝试确定新粘贴的值来自何处。
  • 更新我遇到的另一个问题(抱歉延迟,病毒阻止了一致性)。在应用于我的真实数据集时,此解决方案似乎不起作用,因为数据框中的行排列不是按顺序排列的。换句话说,这个样本数据集中的父节点在第 1 行,然后第 2 行和第 3 行的子节点。在我的实际数据集中,父级位于第 400 行,子级位于第 2384 行和第 4823 行。我不完全确定,但在尝试调试时怀疑这种差异是问题的根源。
  • 用新的示例 DF 和新结果更新了原始帖子。
猜你喜欢
  • 2021-03-04
  • 2021-01-02
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多