Python:将轨迹拆分为步骤

Python:将轨迹拆分为步骤,python,pandas,graph,networkx,Python,Pandas,Graph,Networkx,我已经从集群之间的移动创建了轨迹,例如: user_id,trajectory 11011,[[[86], [110], [110]] 2139671,[[89], [125]] 3945641,[[36], [73], [110], [110]] 10024312,[[123], [27], [97], [97], [97], [110]] 14270422,[[0], [110], [174]] 14283758,[[110], [184]] 14317445,[[50], [88]] 14

我已经从集群之间的移动创建了轨迹,例如:

user_id,trajectory
11011,[[[86], [110], [110]]
2139671,[[89], [125]]
3945641,[[36], [73], [110], [110]]
10024312,[[123], [27], [97], [97], [97], [110]]
14270422,[[0], [110], [174]]
14283758,[[110], [184]]
14317445,[[50], [88]]
14331818,[[0], [22], [36], [131], [131]]
14334591,[[107], [19]]
14373703,[[35], [97], [97], [97], [17], [58]]
我想将多个动作的轨迹分割成单独的部分,但我不确定如何分割

示例:

14373703,[[35], [97], [97], [97], [17], [58]]
14373703,[[35,97], [97,97], [97,17], [17,58]]
进入

14373703,[[35], [97], [97], [97], [17], [58]]
14373703,[[35,97], [97,97], [97,17], [17,58]]
目的是在NetworkX中将其用作边,以图形的形式对其进行分析,并识别各个簇(节点)之间的密集运动(边)

这是我最初用来创建轨迹的代码:

# Import Data
data = pd.read_csv('G:\Programming Projects\GGS 681\dmv_tweets_20170309_20170314_cluster_outputs.csv', delimiter=',', engine='python')
#print len(data),"rows"

# Create Data Fame
df = pd.DataFrame(data, columns=['user_id','timestamp','latitude','longitude','cluster_labels'])

# Filter Data Frame by count of user_id
filtered = df.groupby('user_id').filter(lambda x: x['user_id'].count()>1)
#filtered.to_csv('G:\Programming Projects\GGS 681\dmv_tweets_20170309_20170314_final_filtered.csv', index=False, header=True)

# Get a list of unique user_id values
uniqueIds = np.unique(filtered['user_id'].values)

# Get the ordered (by timestamp) coordinates for each user_id
output = [[id,filtered.loc[filtered['user_id']==id].sort_values(by='timestamp')[['cluster_labels']].values.tolist()] for id in uniqueIds]

# Save outputs as csv
outputs = pd.DataFrame(output)
#print outputs
headers = ['user_id','trajectory']
outputs.to_csv('G:\Programming Projects\GGS 681\dmv_tweets_20170309_20170314_cluster_moves.csv', index=False, header=headers)

如果可以采用这种方式进行拆分,是否可以在处理过程中而不是事后完成?我希望在创建时执行它,以消除任何后处理。

我的解决方案使用了pandas的
.apply()函数的魔力。我相信这应该行得通(我在你的样本数据上测试了这一点)。请注意,对于只有一次移动和没有移动的情况,我还在末尾添加了一个额外的数据点

# Python3.5
import pandas as pd 


# Sample data from post
ids = [11011,2139671,3945641,10024312,14270422,14283758,14317445,14331818,14334591,14373703,10000,100001]
traj = [[[86], [110], [110]],[[89], [125]],[[36], [73], [110], [110]],[[123], [27], [97], [97], [97], [110]],[[0], [110], [174]],[[110], [184]],[[50], [88]],[[0], [22], [36], [131], [131]],[[107], [19]],[[35], [97], [97], [97], [17], [58]],[10],[]]

# Sample frame
df = pd.DataFrame({'user_ids':ids, 'trajectory':traj})

def f(x):
    # Creates edges given list of moves
    if len(x) <= 1: return x
    s = [x[i]+x[i+1] for i in range(len(x)-1)]
    return s

df['edges'] = df['trajectory'].apply(lambda x: f(x))

至于你可以把它放在你的管道中的地方,只要在你得到你的
轨迹
列之后(无论是在你加载数据之后,还是在你做任何你需要的过滤之后)把它放在正确的位置就行了。

如果你
zip
你的轨迹本身被一个偏移,你就会得到你想要的结果

代码:

for id, traj in data.items():
    print(id, list([i[0], j[0]] for i, j in zip(traj[:-1], traj[1:])))
data = {
    11011: [[86], [110], [110]],
    2139671: [[89], [125]],
    3945641: [[36], [73], [110], [110]],
    10024312: [[123], [27], [97], [97], [97], [110]],
    14270422: [[0], [110], [174]],
    14283758: [[110], [184]],
    14373703: [[35], [97], [97], [97], [17], [58]],
}
11011 [[86, 110], [110, 110]]
14373703 [[35, 97], [97, 97], [97, 97], [97, 17], [17, 58]]
3945641 [[36, 73], [73, 110], [110, 110]]
14283758 [[110, 184]]
14270422 [[0, 110], [110, 174]]
2139671 [[89, 125]]
10024312 [[123, 27], [27, 97], [97, 97], [97, 97], [97, 110]]
测试数据:

for id, traj in data.items():
    print(id, list([i[0], j[0]] for i, j in zip(traj[:-1], traj[1:])))
data = {
    11011: [[86], [110], [110]],
    2139671: [[89], [125]],
    3945641: [[36], [73], [110], [110]],
    10024312: [[123], [27], [97], [97], [97], [110]],
    14270422: [[0], [110], [174]],
    14283758: [[110], [184]],
    14373703: [[35], [97], [97], [97], [17], [58]],
}
11011 [[86, 110], [110, 110]]
14373703 [[35, 97], [97, 97], [97, 97], [97, 17], [17, 58]]
3945641 [[36, 73], [73, 110], [110, 110]]
14283758 [[110, 184]]
14270422 [[0, 110], [110, 174]]
2139671 [[89, 125]]
10024312 [[123, 27], [27, 97], [97, 97], [97, 97], [97, 110]]
结果:

for id, traj in data.items():
    print(id, list([i[0], j[0]] for i, j in zip(traj[:-1], traj[1:])))
data = {
    11011: [[86], [110], [110]],
    2139671: [[89], [125]],
    3945641: [[36], [73], [110], [110]],
    10024312: [[123], [27], [97], [97], [97], [110]],
    14270422: [[0], [110], [174]],
    14283758: [[110], [184]],
    14373703: [[35], [97], [97], [97], [17], [58]],
}
11011 [[86, 110], [110, 110]]
14373703 [[35, 97], [97, 97], [97, 97], [97, 17], [17, 58]]
3945641 [[36, 73], [73, 110], [110, 110]]
14283758 [[110, 184]]
14270422 [[0, 110], [110, 174]]
2139671 [[89, 125]]
10024312 [[123, 27], [27, 97], [97, 97], [97, 97], [97, 110]]
我认为您可以使用with
apply
和带有
zip
的自定义函数,以便在必要的列表理解中输出列表列表:

注意

如果按
length
过滤而不使用NaN,则函数返回所有no
NaN

类似的解决方案,过滤是最后一步:


我知道如何使用我提供的数据子集来实现这一点,我执行了它,并且工作得非常完美,但是我如何才能改变从文件中读取呢?我有一个带有几千条轨迹的csv,我想在上面执行此操作。@AndrewR。Stackoverflow的一个要点是获得一系列可回答的问题及其答案。这使人们能够搜索并快速查找信息。我的回答方式是因为我可以。你问题顶部的问题是可以回答的,因此得到了三个有趣的答案。其他问题则更加模糊。这个问题已经被回答和接受,请创建另一个问题(他们毕竟是免费的),注意创建一个示例。这对我提供的数据子集非常有效,但是,当我将我的完整数据集作为csv提供给它时,我会得到很多空移动,并且当前的移动没有正确分割。例如,
[[,[8,86,6],],,[,[1,11,10,0],]…
。写入csv时也会出现这种情况。我看到您使用的是Python 3.5,我使用的是2.7,这会导致问题吗?