使用 Pandas:如何根据一个公共键将多行数据组合成一行?

Posted

技术标签:

【中文标题】使用 Pandas:如何根据一个公共键将多行数据组合成一行?【英文标题】:Using Pandas: How do I combine multiple rows of data into a single row based on a common key? 【发布时间】:2021-08-25 15:49:09 【问题描述】:

需要帮助将多行数据与多列的各种数据类型合并

我有一个包含 14 列和 x 行数据的数据框。数据框的示例切片链接如下:

我的数据框的当前示例

我希望能够根据“工单”列将所有四行数据合并为一行。请参阅下面的链接图片。我目前正在使用 pandas 从四个不同的数据源获取数据,并根据每个工单号创建一个包含我想要的所有相关数据的数据框。我尝试了各种方法,包括groupby、merge、join等,但没有任何好的结果。

我希望我的数据框最终看起来如何

我基本上想按工作订单值进行分组,将所有站点名称合并为一个值,然后将所有数据基本上压缩为一行。如果列中有相同的数据,那么我只想将它合并在一起。如果列中有不同的值(例如在“Operator Ack Timestamp”中),那么我不介意数据是连续的数据字符串(例如,同一单元格中的下一个日期之后的一个日期)。

示例数据框数据:

df = pd.DataFrame('Work Order': [10025,10025,10025,10025],
                   'Site': ['SC1', 'SC1', 'SC1', 'SC1'],
                   'Description_1':['','','Inverter 10A-1 - No Comms',''],
                   'Description_2':['','','Inverter 10A-1 - No Comms',''],
                   'Description_3':['Inverter 10A-1 has lost communications.','','',''],
                   'Failure Type':['','','Communications',''],
                   'Failure Class':['','','2',''],
                   'Start of Fault':['','','2021-05-30 06:37:00',''],
                   'Operator Ack Timestamp':['2021-05-30 8:49:21','','2021-05-30 6:47:57',''],
                   'Timestamp of Notification':['2021-05-30 07:18:58','','',''],
                   'Actual Start Date':['','2021-05-30 6:37:00','','2021-05-30 6:37:00'],
                   'Actual Start Time':['','06:37:00','','06:37:00'],
                   'Actual End Date':['','2021-05-30 08:24:00','',''],
                   'Actual End Time':['','08:24:00','',''])

df.head()

【问题讨论】:

请以文本而非图像的形式包含数据样本,以便人们实际使用它们。这个page 可能会有所帮助。 @joao 刚刚添加了数据框数据 【参考方案1】:

获得预期输出的 4 个步骤:

    pd.NA替换空值, 按Work Order 列对数据进行分组,因为它似乎是索引键, 对于每组,填写NA最后一次有效观察值并保留最后一条记录, 将索引重置为与输入格式相同。

我选择按“工单”分组,因为它似乎是您数据框的索引键。 您的数据框的索引是“工单”:

df = df.set_index("Work Order")
out = df.replace('': pd.NA) \
        .groupby("Work Order", as_index=False) \
        .apply(lambda x: x.ffill().tail(1)) \
        .reset_index(level=0, drop=True)```

>>> out.T  # transpose for better vizualisation
Work Order                                                   10025
Site                                                           SC1
Description_1                            Inverter 10A-1 - No Comms
Description_2                            Inverter 10A-1 - No Comms
Description_3              Inverter 10A-1 has lost communications.
Failure Type                                        Communications
Failure Class                                                    2
Start of Fault                                 2021-05-30 06:37:00
Operator Ack Timestamp                          2021-05-30 6:47:57
Timestamp of Notification                      2021-05-30 07:18:58
Actual Start Date                               2021-05-30 6:37:00
Actual Start Time                                         06:37:00
Actual End Date                                2021-05-30 08:24:00
Actual End Time                                           08:24:00

【讨论】:

如果有帮助,我在上面的原始问题中添加了一个示例数据框。 要保存到excel文件,可以使用out.to_excel('FileLocation.xlsx', index=False) 这正是我想要的。在这片数据来自的较大数据框中,我将“工作订单”列设置为索引。所以我删除了你代码的最后一部分 >>> .reset_index(drop=True) 我更新了我的答案以考虑到您的最后评论。 如果我希望“实际开始日期”和“实际开始时间”列显示最早日期,我该怎么做?假设两个可用的输入值为 21 年 6 月 5 日 1:35:00和 6/7/21 5:23:00 在该列索引中?您能否传递一个参数以确保显示最低日期?

以上是关于使用 Pandas:如何根据一个公共键将多行数据组合成一行?的主要内容,如果未能解决你的问题,请参考以下文章

SQL使用唯一键将多行合并为一行

使用元组键将 Pandas 数据框转换为字典以进行三元图

根据 Pandas 中的公共列值合并两个数据框

如何使用pandas按顺序标记多个类别(多行)?

如何遍历从 snapshot.val() 收到的数据并根据键将其推送到数组

Python pandas:通过代理键将 JSON 扁平化为行的快速方法