具有列值条件的 id 的最早和最新记录

Earliest and latest record for an id with a condition on a column value

我有一个 json 数据必须转换成列,我能够成功地做到这一点,它使我得到如下结果:

id phone country country_code status timestamp
abc 123 India 91 open 2021-09-01
abc 123 India 91 closed 2021-09-02
xyz 456 India 91 open 2021-09-01
xyz 456 India 91 closed 2021-09-02
xyz 456 India 91 open 2021-09-03
ijk 789 India 91 open 2021-09-01
ijk 789 India 91 closed 2021-09-02
ijk 789 India 91 open 2021-09-03
ijk 789 India 91 closed 2021-09-04
suv 000 US 1 Open 2021-09-05

这是一个状态数据,表示某个任务的 activity 何时打开或关闭。已关闭的 activity 也可以重新打开,也可以重新关闭或保持打开状态。但状态键的值仅为 open/closed。

现在,我需要的是最早打开的时间戳和最晚关闭的时间戳。这会告诉我他们什么时候第一次打开 activity 以及它最后一次关闭是什么时候。

结果应该是这样的:

id phone country country_code status timestamp
abc 123 India 91 open 2021-09-01
abc 123 India 91 closed 2021-09-02
xyz 456 India 91 open 2021-09-01
xyz 456 India 91 closed 2021-09-02
ijk 789 India 91 open 2021-09-01
ijk 789 India 91 closed 2021-09-04
suv 000 US 1 Open 2021-09-05

status = open 只能跟随 status = closed。它不能在没有关闭的情况下重新打开,但它可以保持打开状态并且永远不会关闭。

对于 id=abc 有一个 open 和 closed 状态,所以我需要这两个;对于 id = xyz 有一个重新打开,但我不在乎并且仍然需要最早打开和唯一关闭的。对于 id = ijk,有一个重新打开和一个重新关闭,所以我需要最早打开和最晚关闭。对于 id = suv 从来没有关闭,所以它应该 return 只打开记录。 (这里只有 id 是唯一的,不能为 null。即使 phone 看起来也很独特,但它也可以为 null)

所以,基本上任何 ID 最多只能有 2 条记录(如果从来没有关联的关闭状态,则为 1 条)。任何 i 的第一条记录是 status = open 和最早的时间戳。但是,当状态关闭并且它有多个关闭时,那么该特定 id 的最后一个关闭。

我必须将数据放入模式中,我可以使用 rank 子句轻松完成此操作,但这在 pandas 中可行吗?

可以groupby,过滤,然后取first/last如下:

# copy, clean df
# df = pd.read_clipboard("\s\s+")
# df["status"] = df.status.str.lower()
# df["timestamp"] = pd.to_datetime(df.timestamp)
# df = df.sort_values("timestamp")

# this stores the original index as a column, creates a new
df = df.reset_index()

df_open = df[df.status == "open"].groupby(["id"], as_index=False).first()
df_closed = df[df.status == "closed"].groupby(["id"], as_index=False).last()

# discard the temp index, set back to original index    
sol = pd.concat([df_open, df_closed]).set_index("index", drop=True).sort_index()

输出:

        id  phone country  country_code  status  timestamp
index
0      abc    123   India            91    open 2021-09-01
1      abc    123   India            91  closed 2021-09-02
2      xyz    456   India            91    open 2021-09-01
3      xyz    456   India            91  closed 2021-09-02
5      ijk    789   India            91    open 2021-09-01
8      ijk    789   India            91  closed 2021-09-04
9      suv      0      US             1    open 2021-09-05