【问题标题】:Appending a dataframe row with specific values of other dataframes - python使用其他数据框的特定值附加数据框行 - python
【发布时间】:2023-03-19 17:23:02
【问题描述】:

我正在努力在 python 中实现连接扫描算法,因为我需要访问最短的公共交通路径。所以我正在尝试从 gtfs 文件创建一个连接表。

我有一个包含以下列的数据框 (stop_times):

    trip_id    arrival_time  departure_time  stop_sequence  stop_id
0   id1        06:02:00      06:02:00        0              stop_id1
1   id1        06:05:00      06:05:00        1              stop_id2
2   id1        06:06:00      06:06:00        2              stop_id3
3   id1        06:08:00      06:08:00        3              stop_id4

原始文件要长得多,包含许多由trip_id定义的行程的数据。

我想将第一个数据帧中包含的一些值保存在第二个数据帧中,该数据帧将列出站点之间的连接并且基本上有四列:

    departure_station  arrival_station  departure_time   arrival_time   

我的目标是从 stop_times 数据框中提取值并将它们插入到我创建的空行中的正确行中。但是,我遇到了一些问题,而且我已经卡了很长时间了。


我需要迭代 stop_times 数据帧 2“一次行”并在前一行开始新的迭代。第一次迭代将在索引 0-1 上,第二次在 1-2 上,第三次在 2-3 上等等。

目前,我只能使用以下代码对第 0-1、2-3 行等进行迭代,但这不是我在这里想要做的。

for i, g in course.groupby(np.arange(len(course)) // 2):

知道我该如何处理吗?


现在让我们考虑第 0-1 行的第一次迭代:我需要在第一行追加空数据框:

  • stop_times 第一行的离开时间
  • stop_times 第二行的到达时间
  • stop_times第一行的stop_sequence(对应department_station列)
  • stop_times第二行的stop_sequence(对应arranty_station列)

这会给我以下信息:

    departure_station  arrival_station  departure_time   arrival_time
0   0                  1                06:02:00         06:05:00

然后对数据框的其余部分重复此操作:

    departure_station  arrival_station  departure_time   arrival_time
0   0                  1                06:02:00         06:05:00
1   1                  2                06:05:00         06:06:00
2   2                  3                06:06:00         06:08:00

这是我迄今为止尝试过的:

stop_time = pd.read_csv('/Users/im/Downloads/IDFM_gtfs/stop_times.txt')
stop_time = stop_time[:30]

course = stop_time.loc[stop_time['trip_id'] == 'id1']

for i, g in course.groupby(np.arange(len(course)) // 2):
    connexion = g.reset_index()
    connexion = connexion[['trip_id', 'arrival_time', 'departure_time', 'stop_id', 'stop_sequence']]

    dep_hor = connexion.loc[connexion.index == 0, ['departure_time']]
    arriv_hor = connexion.loc[connexion.index == 1, ['arrival_time']]

    table_horaire = table_horaire.append(dep_hor)
    table_horaire = table_horaire.append(arriv_hor)

这给了我以下数据框:

    arrival_time    departure_time  arrival_station  departure_station
0   NaN             06:02:00        NaN              NaN
1   06:05:00        NaN             NaN              NaN
0   NaN             06:06:00        NaN              NaN
1   06:08:00        NaN             NaN              NaN
0   NaN             06:10:00        NaN              NaN
1   06:12:00        NaN             NaN              NaN
0   NaN             06:14:00        NaN              NaN
1   06:16:00        NaN             NaN              NaN

任何帮助将不胜感激,如果某些部分没有得到很好的解释,请告诉我,我对编程还是很陌生,还不知道所有正确的术语。

【问题讨论】:

  • 在大数据帧上迭代计算成本很高。您是否尝试过使用矢量化方法?如果您需要将新列从第一个数据帧附加到第二个数据帧,您是否尝试过使用 map,因为您有 id 作为唯一标识符。
  • 您好,stop_id 是您数据中站的同义词吗?
  • @Joe 感谢您的意见。我考虑了计算成本,并正在考虑解决这个问题。我从未听说过任何矢量化方法,但我一定会研究一下。
  • @jottbe stop_id 是电台的标识符,这里我简化了数据框以便于阅读,但每个电台都有一个 id,让我以后可以得到它的名字。

标签: python pandas loops dataframe gtfs


【解决方案1】:

如果我的问题是正确的,那么您根本不需要 groupby 并且可以使用 shift(1) 和 concat 的组合来获得您想要的:

import numpy as np
# make sure the dataframe is sorted by trip_id and arrival_time
# please choose what is better according your data arrival_time 
# or stop_sequence (in case your public transport goes near the
# speed of light :-)
df.sort_values(['trip_id', 'arrival_time'], inplace=True)

# shift the columns, we need for the departure part 
# by one row and rename the columns
df_departure= df[['trip_id', 'stop_id', 'arrival_time']].shift(1)
df_departure.columns= ['departure_trip_id', 'departuere_station', 'departure_time']

# create a subset of the dataframe with the arrival-columns
df_arrival= df[['trip_id', 'arrival_time', 'stop_id']].copy()
df_arrival.columns= ['trip_id', 'arrival_time', 'arrival_station']

# concat both together
df_combined= pd.concat([df_departure, df_arrival], axis='columns')

# now take care of the rows at the beginning of each group 
# of rows that belong to the same trip_id and delete the 
# departure values of theses rows since they belong to another 
# trip
df_combined.loc[df_combined['trip_id'] != df_combined['departure_trip_id'], ['departuere_station', 'departure_time']]= (np.NaN, np.NaN)
df_combined.drop(['departure_trip_id'], axis='columns', inplace=True)

有以下测试数据:

raw="""    trip_id    arrival_time  departure_time  stop_sequence  stop_id
0   id1        06:02:00      06:02:30        0              stop_id1
1   id1        06:05:00      06:05:30        1              stop_id2
2   id1        06:06:00      06:06:30        2              stop_id3
3   id1        06:08:00      06:08:30        3              stop_id4
4   id2        06:12:00      06:12:30        4              stop_id5
5   id2        06:15:00      06:15:30        5              stop_id6
6   id2        06:16:00      06:16:30        6              stop_id7
7   id2        06:18:00      06:18:30        7              stop_id8
"""
df= pd.read_csv(io.StringIO(raw), index_col=0, sep='\s+')

上面的代码输出:

Out[65]: 
  departuere_station departure_time trip_id arrival_time arrival_station
0                NaN            NaN     id1     06:02:00        stop_id1
1           stop_id1       06:02:00     id1     06:05:00        stop_id2
2           stop_id2       06:05:00     id1     06:06:00        stop_id3
3           stop_id3       06:06:00     id1     06:08:00        stop_id4
4                NaN            NaN     id2     06:12:00        stop_id5
5           stop_id5       06:12:00     id2     06:15:00        stop_id6
6           stop_id6       06:15:00     id2     06:16:00        stop_id7
7           stop_id7       06:16:00     id2     06:18:00        stop_id8

如果stop_id 不是station 的同义词,您可以在执行shift 之前执行merge(或map)来翻译它。

希望这就是您要搜索的内容。

【讨论】:

  • 非常感谢,这是获取连接表的一种非常有效的方法。我有一个问题,我正在使用一个非常大的数据框(并且我想考虑站之间的传输),这将导致一个巨大的连接表。创建 df_departure 和 df_arrival 来获得 df_combined 不是计算量很大吗?
  • 我无法确定,但凭直觉我会说,它应该是有效的,因为shift 可能只是一个简单的复制语句,而且肯定比@987654332 更有效@。最耗费成本的操作可能是sort,但如果您仍然按该顺序维护数据,则可以跳过它。也许 concat 的成本也更高(不确定)。如果是这样并且您想要优化,您可以检查ignore_index=True 是否对concat 有帮助(但前提是您不需要索引值)。
  • 所以总结一下,我预计,shift 只有在内存消耗成为问题的情况下才会产生更大的影响,否则它可能不是很大的影响,因为它应该具有线性复杂性(运行时间应该随着记录的数量线性增加)而像sort 这样的操作是非线性的。对于concat,我不确定,但很可能也没问题(这里的执行方式也应该是线性的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 2022-12-06
  • 2022-01-01
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
相关资源
最近更新 更多