【问题标题】:Earliest and latest record for an id with a condition on a column value具有列值条件的 id 的最早和最新记录
【发布时间】:2021-11-03 21:38:24
【问题描述】:

我有一个 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

这是一个状态数据,表示某个任务的活动何时打开或关闭。关闭的活动也可以重新打开,也可以重新关闭或保持打开状态。但是状态键的值只是打开/关闭。

现在,我需要的是最早的打开时间戳和最新的关闭时间戳。这将告诉我他们第一次打开活动的时间以及上次关闭的时间。

结果应该是这样的:

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 有一个打开后关闭状态,所以我需要这两个;对于 id = xyz 有一个重新打开,但我不在乎,仍然需要最早的打开和唯一的关闭。对于 id = ijk 有一个重新打开和一个重新关闭,所以我需要最早的打开和最近的关闭。对于 id = suv 从来没有关闭,所以它应该只返回那个打开的记录。 (这里只有id是唯一的,不能为null。虽然手机看起来也是唯一的,但也可以为null)

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

我必须将数据放入架构中,我可以使用 rank 子句轻松做到这一点,但这在 pandas 中可能吗?

【问题讨论】:

    标签: python pandas data-cleaning


    【解决方案1】:

    您可以按如下方式分组,过滤,然后取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
    

    【讨论】:

    • 我不想把 id 变成索引。它必须保持为一行,索引是自动生成的行号。我必须把它放在一个 sql 数据库中。另外,感谢最后一个功能。我正在尝试一种不同的排名方式,并选择最早的奇数和最后一个偶数,但这会更有效率。你能保持与问题相同的结构吗?
    • 当然,给我一秒钟
    猜你喜欢
    • 2020-11-30
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    相关资源
    最近更新 更多