代码之家  ›  专栏  ›  技术社区  ›  aeiou

对日志表进行矢量化处理,以确定最新的可用性

  •  1
  • aeiou  · 技术社区  · 1 年前

    我有一个包含更改的日志表。符号+表示添加,符号-表示删除。

    import pandas as pd
    
    history = pd.DataFrame({
        "First": 
            ["X","X", "Y", "Y", "X", "X", "Y", "Z"],
        "Last": 
             ["Y", "X", "Y", "Y", "X", "X", "Y", "A"],
        "Change":
            ["+", "+", "-", "+", "-", "+", "+", "-"],
        "Date": 
            ["2022-05-01", "2024-05-01", "2024-06-01", "2024-06-01",
             "2024-05-03", "2024-05-02", "2024-06-02", "2024-06-01"]
    })
        
    history = history.sort_values(by=["Date", "Change"])
    # sort needed to process the entries chronologically
    

    这会产生

      First Last Change        Date
    0     X    Y      +  2022-05-01
    1     X    X      +  2024-05-01
    5     X    X      +  2024-05-02
    4     X    X      -  2024-05-03
    3     Y    Y      +  2024-06-01
    2     Y    Y      -  2024-06-01
    7     Z    A      -  2024-06-01
    6     Y    Y      +  2024-06-02
    

    在下一步中,我只想显示当前可用的内容。

    • 最后一个可用的符号必须是+,项目才能可用。
      • 可用:+、++、+-+、-+、--+等。
      • 不可用:-、++-、+--等。
    • 项是第一列和最后一列的组合
    • 按日期和更改进行排序

    我使用迭代来构建这个逻辑,这是非常缓慢的。大体上

    latest = {}
    item_columns = [
        "First",
        "Last",
    ]  
    
    for _, row in history.iterrows():
        key = tuple(row[column] for column in item_columns)
        if row["Change"] == "+":
            latest[key] = row
        elif row["Change"] == "-" and key in latest:
            del latest[key]
    
    available = pd.DataFrame(latest.keys(), columns=item_columns)
    

    这会产生可用的项目

      First Last
    0     X    Y
    1     Y    Y
    

    问题是大表格的循环很慢,例如20秒以下

    latest = {}
    item_columns = [
        "First",
        "Last",
    ]  
    
    duplicated = pd.concat([history.iloc[[1]]] * 50000, ignore_index=True)
    history = pd.concat([history, duplicated], ignore_index=True)
    for _, row in history.iterrows():
        key = tuple(row[column] for column in item_columns)
        if row["Change"] == "+":
            latest[key] = row
        elif row["Change"] == "-" and key in latest:
            del latest[key]
    
    available = pd.DataFrame(latest.keys(), columns=item_columns)
    

    有办法加快速度吗?

    1 回复  |  直到 1 年前
        1
  •  2
  •   mozway    1 年前

    如果你想保留最后一个 + 行:使用筛选行 + 然后 drop_duplicates :

    out = (history.query('Change == "+"')
                  .drop_duplicates(subset=['First', 'Last'], keep='last')
          )
    

    输出

      First Last Change        Date
    0     X    Y      +  2022-05-01
    5     X    X      +  2024-05-02
    6     Y    Y      +  2024-06-02
    

    如果要按组合保留行,则仅当它是 + ,反转操作:

    out = (history.drop_duplicates(subset=['First', 'Last'], keep='last')
                  .query('Change == "+"')
          )
    

    输出

      First Last Change        Date
    0     X    Y      +  2022-05-01
    6     Y    Y      +  2024-06-02