【问题标题】:How to share a ordering between two lists in Python如何在 Python 中的两个列表之间共享排序
【发布时间】:2022-01-19 17:04:44
【问题描述】:

我得到了一个 ID 列表和一个日期列表。两者都是单独的 pandas 数据框列的单个条目。每个日期对应一个id。比如:

[852634, 727417, 881231]   [2018-05-29, 2015-11-23, 2019-06-26]

如何对日期进行排序(升序或降序,无关紧要)并将相同的顺序导出到 ID?

想要的结果是:

[727417, 852634, 881231]   [ 2015-11-23, 2018-05-29, 2019-06-26]

提前感谢您的所有建议, 亚历山德罗

【问题讨论】:

    标签: python pandas list


    【解决方案1】:

    压缩...

    >>> x = [852634, 727417, 881231]
    >>> y = ["2018-05-29", "2015-11-23", "2019-06-26"]
    >>> list(zip(y, x))
    [('2018-05-29', 852634), ('2015-11-23', 727417), ('2019-06-26', 881231)]
    

    排序...

    >>> sorted(zip(y,x))
    [('2015-11-23', 727417), ('2018-05-29', 852634), ('2019-06-26', 881231)]
    

    然后解压。

    >>> [x for _, x in sorted(zip(y,x))]
    [727417, 852634, 881231]
    

    这是一种称为Schwartzian transform 的通用技术的示例。你用相应的日期修饰你想要排序的 ID 列表,对修饰的列表进行排序,然后从结果中提取(未修饰)原始值。

    【讨论】:

    • 感谢您的回答,特别是一般定义。
    【解决方案2】:

    使用 numpy -

    l1_key = np.argsort(l1)
    
    l1_sorted = np.array(l1)[l1_key]
    l2_sorted = np.array(l2)[l1_key]
    

    输出

    print(l1_sorted)
    print(l2_sorted)
    
    [727417 852634 881231]
    ['2015-11-23' '2018-05-29' '2019-06-26']
    

    【讨论】:

    • 非常pythonic的一个。谢谢!
    【解决方案3】:

    如果您已经有一个数据框,那么在导出之前.explode() 'em 和 .sort_values() 可能要容易得多!

    >>> import pandas as pd
    >>> df = pd.DataFrame({"ids": [[852634, 727417, 881231], [90,100,110,115]], "dates": [["2018-05-29", "2015-11-23", "2019-06-26"], ["2015-01-01", "2021-01-01", "2020-01-01", "2021-01-01"]]})
    >>> df
                            ids                                             dates
    0  [852634, 727417, 881231]              [2018-05-29, 2015-11-23, 2019-06-26]
    1       [90, 100, 110, 115]  [2015-01-01, 2021-01-01, 2020-01-01, 2021-01-01]
    >>> df.explode(["ids", "dates"]).sort_values("dates")
          ids       dates
    1      90  2015-01-01
    0  727417  2015-11-23
    0  852634  2018-05-29
    0  881231  2019-06-26
    1     110  2020-01-01
    1     100  2021-01-01
    1     115  2021-01-01
    >>> df.explode(["ids", "dates"]).sort_values("dates")["ids"].to_numpy()
    array([90, 727417, 852634, 881231, 110, 100, 115], dtype=object)
    

    【讨论】:

    • 明白你的意思,但这些列表来自以前的 grouby:group_by 操作将保持排序?
    • hmm .. 好吧,它们将按 groupby 的顺序排序 .. 但是,实际上是否需要这样做,或者 ID 是否已经事先映射?在使用 groupby 之前是否有原生列表?
    【解决方案4】:

    你可以为 int 做list.sort()

    ids = ids.sort()
    

    你可以使用 datetime 来做排序列表:

    from datetime import datetime
    dates = ["2018-05-29", "2015-11-23", "2019-06-26"]
    dates = [datetime.strptime(date,"%Y-%M-%d") for date in dates]
    dates.sort()
    print(dates)
    

    所以代码变成:

    from datetime import datetime
    ids = [852634, 727417, 881231]
    dates = ["2018-05-29", "2015-11-23", "2019-06-26"]
    print("Before: ",ids,dates)
    ids = ids.sort()
    dates = [datetime.strptime(date,"%Y-%M-%d") for date in dates]
    dates.sort()
    print("After: ",ids,dates)
    

    【讨论】:

    • ID 列表必须继承日期列表的相同顺序。你确定这样可以解决问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 2014-02-22
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多