2017-04-09 72 views
3

我从集群之间移动,如这些被创建的轨迹:的Python:拆分成轨迹步骤

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]] 

目的是然后使用这些作为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) 

如果拆分这种方式是可行的,能不能在处理过程中完成的,作为事后反对?我想在创建时执行它,以消除任何后处理。

回答

2

我认为你可以使用groupbyapplyzip自定义功能,在必要的列表理解列表输出列表:

注意

count函数返回所有没有NaN值,如果过滤通过length没有NaN的更好的是len

#filtering and sorting  
filtered = df.groupby('user_id').filter(lambda x: len(x['user_id'])>1) 
filtered = filtered.sort_values(by='timestamp') 

f = lambda x: [list(a) for a in zip(x[:-1], x[1:])] 
df2 = filtered.groupby('user_id')['cluster_labels'].apply(f).reset_index() 
print (df2) 
    user_id          cluster_labels 
0  11011       [[86, 110], [110, 110]] 
1 2139671          [[89, 125]] 
2 3945641     [[36, 73], [73, 110], [110, 110]] 
3 10024312 [[123, 27], [27, 97], [97, 97], [97, 97], [97,... 
4 14270422        [[0, 110], [110, 174]] 
5 14283758          [[110, 184]] 
6 14373703 [[35, 97], [97, 97], [97, 97], [97, 17], [17, ... 

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

filtered = filtered.sort_values(by='timestamp') 

f = lambda x: [list(a) for a in zip(x[:-1], x[1:])] 
df2 = filtered.groupby('user_id')['cluster_labels'].apply(f).reset_index() 
df2 = df2[df2['cluster_labels'].str.len() > 0] 
print (df2) 
    user_id          cluster_labels 
1  11011       [[86, 110], [110, 110]] 
2 2139671          [[89, 125]] 
3 3945641     [[36, 73], [73, 110], [110, 110]] 
4 10024312 [[123, 27], [27, 97], [97, 97], [97, 97], [97,... 
5 14270422        [[0, 110], [110, 174]] 
6 14283758          [[110, 184]] 
7 14373703 [[35, 97], [97, 97], [97, 97], [97, 17], [17, ... 
2

我的解决方案使用熊猫'.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)) 

输出:

print(df['edges']) 

               edges 
0        [[86, 110], [110, 110]] 
1           [[89, 125]] 
2     [[36, 73], [73, 110], [110, 110]] 
3 [[123, 27], [27, 97], [97, 97], [97, 97], [97,... 
4        [[0, 110], [110, 174]] 
5          [[110, 184]] 
6           [[50, 88]] 
7   [[0, 22], [22, 36], [36, 131], [131, 131]] 
8           [[107, 19]] 
9 [[35, 97], [97, 97], [97, 97], [97, 17], [17, ... 
10            [10] 
11             [] 

至于在那里你可以把这个在您的管道 - 只要把它放在你之后你trajectory列(您加载数据后,这是否是,或之后做任何你需要的过滤)。

+0

这工作完全在我提供的数据子集,但是,当我给它我的全部数据设置为csv格式,我收到了很多空着的动作和存在的动作都没有正确分割。例如'[[[,[8,86,6],] ,,,,[,[1,11,10,0],] ...'。写入csv时也存在这种情况。我看到你正在使用Python 3.5,我在2.7,可能会导致一个问题? –

2

如果你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]] 
+0

我明白这是如何使用我提供的数据子集,我执行它并完美工作,但我怎么可能改变从文件读取?我有一个csv有几千个轨迹,我想要执行此操作。 –

+0

@AndrewR。 Stackoverflow的一个主要观点是获得一系列可回答的问题及其答案。这可以让人们搜索并快速找到信息。我以这样的方式回答了,因为我能。问题顶部提出的问题是可以回答的,因此得到了三个有趣的答案。其他问题更模糊。这个问题已被回答和接受,请创建另一个问题(毕竟他们是免费的),注意创建一个[Minimal,Complete,and Verifiable](http://stackoverflow.com/help/mcve)示例。 –