Python:识别数据框列中的断点

Python: Identify breaking points in a data frame column

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

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

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

我的最终目标是确定行程次数(在本例中应为 2),将它们与用户 ID 和 start/end 日期时间一起添加到新的 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

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

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

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

我想出了这个一维 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")

它returns一个新的pandas.DataFrame,多了一个"cluster"列,表示该节点所属的集群(0表示该节点未被占用,不属于任何集群)。

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

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