【发布时间】:2020-02-19 09:19:47
【问题描述】:
我有一个 DataFrame routes,其结构如下:
id nodes traveltimes
0 id-1 [node-A, node-B] [6.0]
1 id-2 [node-A, node-C, node-D, node-E] [4.0, 80.0, 38.0]
2 id-3 [node-B, node-D] [90.0]
3 id-4 [node-A] []
4 id-5 [node-A, node-B, node-C, node-D, node-E, node-D] [35.0, 30.0, 110.0, 20.0, 5.0]
.. ... ...
nodes 列中的值列表是图的节点,traveltimes 列中的值是两个节点之间的时间。每一行对应图中的一个route。
我想将我的routes 拆分为traveltimes 的阈值。例如,对于 70 的阈值,我想得到以下结果:
id route_id nodes traveltimes
0 id-1 0 [node-A, node-B] [6.0]
1 id-2 0 [node-A, node-C] [4.0]
2 id-2 1 [node-D, node-E] [38.0]
3 id-3 0 [node-B] []
4 id-3 1 [node-D] []
5 id-4 0 [node-A] []
6 id-5 0 [node-A, node-B, node-C] [35.0, 30.0]
7 id-5 1 [node-D, node-E, node-D] [20.0, 5.0]
.. ... ...
我编写了以下代码来做我想做的事,但是效率很低。
我有一个分割路线的功能:
def split_routes(row):
newrow = row.copy()
threshold = 70
nodes = newrow['nodes']
traveltimes = newrow['traveltimes']
rows = []
route_id = 0
route_nodes = []
route_traveltimes = []
route_nodes.append(nodes[0])
for i in range(1, len(nodes)):
if(traveltimes[i-1]<threshold):
route_traveltimes.append(traveltimes[i-1])
route_nodes.append(nodes[i])
else :
# Route route_id completed, starting a new one
newrow['route_id'] = route_id
newrow['nodes'] = route_nodes
newrow['traveltimes'] = route_traveltimes
rows.append(newrow)
newrow = row.copy()
route_nodes = []
route_traveltimes = []
route_id+=1
route_nodes.append(nodes[i])
# Route route_id completed
newrow['route_id'] = route_id
newrow['nodes'] = route_nodes
newrow['traveltimes'] = route_traveltimes
rows.append(newrow)
df = pd.DataFrame(rows)
return df
这就是我使用它的方式:
splitted_routes_array = []
for index, row in routes.iterrows(): # Inefficient loop
splitted_routes_array.append(split_routes(row))
splitted_routes = pd.concat(splitted_routes_array).reset_index(drop=True)
我想我可以在不自己迭代行的情况下做一些更有效的事情。但我不知道如何使用apply 同时返回多行和多列。
有人可以给我一些提示吗?
【问题讨论】:
-
我想这已经接近解决我的问题了。但是当我使用它时,我得到了一个奇怪的结果。
splitted_routes = routes.apply(split_routes,axis=1)给我一个系列作为输出,其中每个元素似乎都包含一个数据框。 -
您可以按照答案中的建议尝试使用 stack() 和 reset_index()。