优化 python 插值脚本时遇到问题



我正在为我拥有的一些公共交通数据插入到达时间。我有一个工作脚本,但它似乎在二次时间内运行。这是脚本:

import pandas as pd
#read the txt file
st = pd.read_csv('interpolated_test.csv')
# sort first by trip_id, then by stop_sequence
sorted_st = st.sort(['trip_id','stop_sequence'], ascending=[False,True])
# reset the index values in prep. for iteration
reindexed = sorted_st.reset_index(drop=True)
# for each row in 'arrival_time' that has a value of hh:mm:ss
for i in reindexed['arrival_time']:
# for i in range(len(reindexed['arrival_time'])):
    if pd.isnull(i) == False:
        # splice hh:mm:ss
        hour = int(i[:2])
        minute = int(i[3:5])
        # assign hh:mm:ss to numeric value
        minute_value = (hour * 60) + minute
        # replace current string with int value
        # takes ~655s to execute on Macbook Pro w/ entire stop_times.txt
        # runs in quadratic time
        reindexed = reindexed.replace(i,minute_value)
# interpolate and write out
new = reindexed.apply(pd.Series.interpolate)
print(new)

这是csv的链接:https://gist.github.com/adampitchie/0192933ed0eba122ba7e

我缩短了 csv,以便您可以运行文件而无需等待它完成。

对于任何熟悉熊猫的人来说,这应该是唾手可得的果实,但我被困住了,任何帮助将不胜感激。

[更新]所以我尝试使用完整的 CSV 文件运行相同的代码,但出现此错误:

Traceback (most recent call last):
  File "/Users/tester/Desktop/ETL/interpolate.py", line 49, in <module>
    reindexed[col].dt.hour * 60
  File "pandas/src/properties.pyx", line 34, in pandas.lib.cache_readonly.__get__ (pandas/lib.c:40664)
  File "/Library/Python/2.7/site-packages/pandas/core/series.py", line 2513, in dt
    raise TypeError("Can only use .dt accessor with datetimelike values")
TypeError: Can only use .dt accessor with datetimelike values

看起来pd.to_datetime(reindexed[col])不起作用。这是代码,为了完成:

import pandas as pd
st = pd.read_csv('csv/stop_times.csv')
sorted_st = st.sort(['trip_id','stop_sequence'], ascending=[False,True])
reindexed = sorted_st.reset_index(drop=True)
for col in ('arrival_time', 'departure_time'):
    reindexed[col] = pd.to_datetime(reindexed[col])
    reindexed[col] = (
        reindexed[col].dt.hour * 60
        + reindexed[col].dt.minute)
    reindexed[col] = reindexed[col].interpolate()
print(reindexed.iloc[:, :3])

只要有可能,请尝试将计算表述为对整列而不是行的操作,或者逐项操作。您可以使用 pd.to_datetime 将整个列转换为 datetime64,而不是一次处理一个reindexed['arrival_time']中的每个值。一系列datetime64具有dt属性,允许您以整数形式访问小时和分钟。因此,您可以像这样表示整个列的计算:

for col in ('arrival_time', 'departure_time'):
    reindexed[col] = pd.to_datetime(reindexed[col])
    reindexed[col] = (
        reindexed[col].dt.hour * 60
        + reindexed[col].dt.minute)
    reindexed[col] = reindexed[col].interpolate()
print(reindexed.iloc[:5, :3])

收益 率

    trip_id  arrival_time  departure_time
0   1423492    647.000000      647.000000
1   1423492    649.666667      649.666667
2   1423492    652.333333      652.333333
3   1423492    655.000000      655.000000
4   1423492    655.750000      655.750000

调试TypeError: Can only use .dt accessor with datetimelike values

事实上,正如你所指出的,pd.to_datetime并没有将时间转换为 datetime64s。相反,它是只是返回与字符串相同的数据。 pd.to_datetime在尝试将输入转换为日期时间时遇到错误时返回输入。您可以通过添加 errors='raise' 参数来收集有关出错的更多信息:

pd.to_datetime(reindexed['arrival_time'], errors='raise')

提高

ValueError: hour must be in 0..23

所以啊哈 - 时间格式可能有小时数超过23的时间。

col = 'arrival_time'
x = reindexed[col]
mask = x.str.extract(r'(d+):(d+):(d+)')[0].astype('int')  > 23

我们可以看到小时数大于 23 的行示例:

In [48]: x[mask].head()
Out[48]: 
42605    26:09:00
42610    26:12:00
42611    26:20:00
42612    26:30:00
42613    26:35:00
Name: arrival_time, dtype: object

x.str.extract 使用正则表达式模式拆分到达时间字符串 r'(d+):(d+):(d+)' .它返回一个包含三列的数据帧。

这段调试代码建议了一种解决方法。而不是pd.to_datetime,我们可以用x.str.extract来查找小时和分钟:

import pandas as pd
st = pd.read_csv('csv/stop_times.csv')
sorted_st = st.sort(['trip_id','stop_sequence'], ascending=[False,True])
reindexed = sorted_st.reset_index(drop=True)
for col in ('arrival_time', 'departure_time'):
    df = reindexed[col].str.extract(
        r'(?P<hour>d+):(?P<minute>d+):(?P<second>d+)').astype('float')
    reindexed[col] = df['hour'] * 60 + df['minute']
    reindexed[col] = reindexed[col].interpolate()
print(reindexed.iloc[:5, :3])

收益 率

   trip_id  arrival_time  departure_time
0  1423492    647.000000      647.000000
1  1423492    649.666667      649.666667
2  1423492    652.333333      652.333333
3  1423492    655.000000      655.000000
4  1423492    655.750000      655.750000

最新更新