【问题标题】:Company Data formatting公司数据格式
【发布时间】:2022-01-25 00:09:54
【问题描述】:

我有以下数据集:

EID CLEAN_NAME Start_Date End_Date
A111 ABC 2003-11-01 2005-12-31
A111 DEF 2005-12-01 2007-08-31
A111 GHI 2007-09-01 2012-01-31
A111 GHI 2012-01-01 2013-05-31
A111 JKL 2013-06-01 2015-03-31
A111 MNO 2015-04-01 2016-04-30
A111 GHI 2016-04-18 2017-11-07
A111 GHI 2017-11-01 NaT

以下是预期的结果:

EID CLEAN_NAME Start_Date End_Date
A111 ABC 2003-11-01 2005-12-31
A111 DEF 2005-12-01 2007-08-31
A111 GHI 2007-09-01 2013-05-31
A111 JKL 2013-06-01 2015-03-31
A111 MNO 2015-04-01 2016-04-30
A111 GHI 2016-04-18

我在这里尝试做的是让公司根据 EID 和 CLEAN_NAME 汇总公司数据,并取 Start_Date 的最小值和 End_Date 的最大值。如果我对 GHI 公司进行简单聚合,则 Start_Date 的最小值为 2007-09-01,End_Date 的最大值为 2017-11-07,这是不正确的。

基本上我想将 GHI 公司分开,因为它们是两个不同的数据。我知道我可能必须对 EID、CLEAN_NAME 和 Start_Date 和 End_Date 使用嵌套的 for 循环来比较每一行之间的数据,但我似乎无法让它工作,因为我无法理解实现它的用法和逻辑循环。这是我开始的(虽然不多,但仍然......):

   for i in df['EID']:
        for j in df['CLEAN_NAME']:
             if j == j-1
        for k in df['Start_Date']:
             print(df['EID'])

这只是一个检查嵌套 for 循环如何工作的示例(它没有这样做,因为如果 j == j-1,我在行中遇到错误)。我是 python 新手,仍在试图弄清楚事情是如何工作的。

另请注意,数据集已根据 EID、Start_date、End_date 和 CLEAN_NAME 进行了排序。所以基本上我必须将连续重复行与 Start_date 的 min 和 End_date 的 max 以及 Start_date 和 End_date 的 min 为 NULL 的最后一个公司合并,因为它表明该员工目前在这家公司工作..

任何线索将不胜感激。!

【问题讨论】:

  • EID 会是这样,还是对所有事物都是独一无二的?而j==j-1 在这个世界上永远不会是真的!。
  • 这对于整个集合来说都是独一无二的......我的意思是我有一个包含几乎数百个 EID 及其各自公司数据的列表。在这种情况下,我只发布了一个 EID 的数据。我将在数据集中有多个 EID。所以这里我有 A111 的数据,然后我会有 B111、C111 等的数据......
  • 是的,但正如您所见,GHI 有 4 行具有相同的 EID,但您想将它们聚合为 2 个不同的公司,对吗?
  • yupp yupp...正确!我想要相同的 EID。
  • 如果您正在聚合,所有 EID-CLEAN_NAME 唯一的组合,那么它是直接的,你不需要任何循环。

标签: python loops for-loop


【解决方案1】:

嗯,这是一种不使用循环的解决方案。

df['groups'] = (df['CLEAN_NAME'].ne(df['CLEAN_NAME'].shift())).cumsum()
df = df.groupby(["groups"]).agg({"EID": "first", "CLEAN_NAME": "first", "Start_Date": min, "End_Date": max}).reset_index()
print(df[["EID", "CLEAN_NAME", "Start_Date", "End_Date"]])

在这种方法中,我们创建了具有相同 CLEAN_NAME 且连续出现的行组。然后,根据组聚合 df。

输出如下所示

    EID CLEAN_NAME  Start_Date    End_Date
0  A111        ABC  2003-11-01  2005-12-31
1  A111        DEF  2005-12-01  2007-08-31
2  A111        GHI  2007-09-01  2013-05-31
3  A111        JKL  2013-06-01  2015-03-31
4  A111        MNO  2015-04-01  2016-04-30
5  A111        GHI  2016-04-18         NaT

这对你有用吗?

【讨论】:

  • 这工作....除了我得到的最后一行看起来像这样:|E401494 |霍尼韦尔 / HON | 2016-04-18 | 2017-11-07。所以我只需要用 Null 替换最后一行的 End_Date 就可以了......对吧?
  • 可能是数据清理问题。
  • 您能详细说明一下吗?这可能是什么问题,以便我可以修复我编写的代码本身。?
  • 如果您想保留缺失值(即 NaT),请将 "End_Date" 列的 max 聚合器替换为此 lambda lambda s: s.max(skipna=False),告诉系列不要跳过它们。
  • @Kris 得到了解决方案。!我只需要改变这个: df = df.groupby(["groups","EID"]).agg({"CLEAN_NAME": "first", "Start_Date": min, "End_Date": max}).reset_index ()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
相关资源
最近更新 更多