【问题标题】:Python: Identify breaking points in a data frame columnPython:识别数据框列中的断点
【发布时间】:2021-09-18 10:04:12
【问题描述】:

我有兴趣确定数据集中何时发生不同的旅行。有两种锁定状态,其中 lock 表示车辆处于静止状态,unlocked 表示车辆正在使用中。

由于同一车辆可能被同一用户多次使用,我首先通过 ID 和 按时间排序的时间日期列隔离车辆和唯一用户,我可以看到车辆的使用时间用过的。为了识别同一用户乘坐同一辆车的不同行程,我想通过我的 lock_state 变量进行识别。

我一直在努力寻找如何做到这一点,渗透是我遇到的,但它似乎太复杂而无法理解和实施。我想知道是否有更简单的方法来实现这一点。

我的最终目标是确定行程次数(在本例中应为 2),将它们与用户 ID 和开始/结束日期时间一起添加到新的 df 中(假设所有这些都是随机列)并给出它们是唯一的 ID。所以最终的输出应该是这样的(随机编造的例子):

trip_id      star_time  end_time user_id
jk3b4334kjh  x           x       093723
nbnmvn829nk  x           x       234380

假设以下示例数据按时间顺序排列,我如何通过变量 state 识别不同的行程? (应该有 2 次行程被标识为阵列处于连续“解锁”状态两次,然后被“锁定”状态中断)。

lock_state = ["locked", "unlocked", "unlocked", "unlocked", "locked", "locked", "unlocked", "unlocked"]
# should be 2 trips

random_values = random.sample(range(2,20), 8) 

df = pd.DataFrame(
    {'state': lock_state,
     'random': random_values
    })

df

>>
    state   random
0   locked      5
1   unlocked    12
2   unlocked    17
3   unlocked    13
4   locked      18
5   locked      6
6   unlocked    4
7   unlocked    9

【问题讨论】:

  • 显然,您可以遍历行,观察状态变化,并在转换时记录信息。您在寻找更自动化的东西吗?

标签: python pandas filtering grouping intervals


【解决方案1】:

shift 你的state 列 1 行;与原始版本进行比较,并根据“解锁”状态进行过滤。这些标识了连续“解锁”状态的运行。移位比较部分是

df.state.eq(df.state.shift())

鉴于这个提示,我希望你能完成编码,嗯?

【讨论】:

    【解决方案2】:

    我想出了这个一维 Hoshen-Kopelman 集群标签的实现。

    import random
    import pandas as pd
    import numpy as np
    
    lock_state = ["locked", "unlocked", "unlocked", "unlocked", "locked", "locked", "unlocked", "unlocked"]
    
    random_values = random.sample(range(2,20), 8) 
    
    df = pd.DataFrame(
        {'state': lock_state,
         'random': random_values
        })
        
    
    def hoshen_kopelman_1d(grid, occupied_label):
        """
        Hoshen Kopelman implementation for 1D graphs.
        
        Parameters:
                grid (pd.DataFrame): The 1D grid. 
                ocuppied_label (str): the label that identifies occupied nodes.
    
        Returns:
                labeled_grid (pd.DataFrame): grid with cluster labeled nodes.
        """
        
        # create labeled_grid and assign all nodes to cluster 0
        labeled_grid = df.assign(cluster=0)
        cluster_count = 0
        
        # iterate through the grid's nodes left to right
        for index, node in grid.iterrows():
            # check if node is occupied
            if node["state"] == occupied_label: # node is occupied
                if index == 0:
                    # initialize new cluster
                    cluster_count += 1
                    labeled_grid.loc[0, "cluster"] = cluster_count
                else:
                    # check if left-neighbour node is occupied
                    if labeled_grid.loc[index-1, "cluster"] != 0: # left-neighbour node is occupied
                        # assign node to the same cluster as left-neighbour node
                        labeled_grid.loc[index, "cluster"] = labeled_grid.loc[index-1, "cluster"]
                    else: # left-neighbour node is unoccupied
                        # initialize new cluster
                        cluster_count += 1
                        labeled_grid.loc[index, "cluster"] = cluster_count
                        
        return labeled_grid
                    
    
    M = hoshen_kopelman_1d(grid=df, occupied_label="unlocked")
    

    它返回一个新的pandas.DataFrame,带有一个额外的"cluster"列,表示该节点所属的集群(0表示该节点未被占用,不属于任何集群)。

    有了这个,检索行变得非常简单,例如,trip 1。我们可以做

    trip_1 = M.loc[M['cluster'] == 1]
    

    【讨论】:

      猜你喜欢
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      相关资源
      最近更新 更多