【问题标题】:Python: converting Trip duration of h min sec and leave only minute countPython:转换h min sec的行程持续时间,只留下分钟数
【发布时间】:2015-07-10 16:30:02
【问题描述】:

我是 python 和编程的新手(所以请放轻松),希望有人能提供帮助。 我的自行车旅行持续时间为 dtype: object 持续时间 14 小时 26 分钟。 2秒。 0小时8分钟。 34 秒。 0 小时 12 分钟。 17 秒。

理想情况下,我希望创建一个新列,将计算出的分钟持续时间保存为整数。所以 h 需要 *60,并且需要四舍五入的秒数。所以我会: 持续时间 866 9 12

我在拆分和获得数字的第一个障碍时遇到了麻烦。 我很高兴与此分手:

def ConvertDuration(Minutes):
    return Minutes.split(' ')[0].split('.')[1].strip()
WashBike['DurationMin'] = pd.DataFrame({'Duration':WashBike['Duration'].apply(ConvertDuration)})

我可以调整位置并为 h、min 和 sec 分别创建一列。 但是字符串字符将保留。我需要再做一次拆分以进一步分离和删除字符吗?
我还尝试使用以下内容去除字符:

WashBike['DurationInt'] = WashBike['Duration'].str.strip(' ').str.strip('.').str.strip('hHmMiInNsSeEcC')

我还没有达到将值放入单个数字分钟单位测量的阶段。我正在考虑做这样的事情:

WashBike['DurationMn'] = WashBike['Duration'].split(' ').apply(lambda x: int(x[0]) * 60 + int(x[1] + int(x[2].round()) ))

虽然我无法做到这一点。

我花了 2 天时间查看 stackoverflow 和其他内容。我发现了很多关于日期时间等的信息。虽然我试图将 Duration 转换为 hh:mm:ss,但我不确定它是否正确。任何帮助和建议将不胜感激。

【问题讨论】:

  • 第一个问题:我假设持续时间为 14 小时 26 分钟。 2秒。 0小时8分钟。 34 秒。 0 小时 12 分钟。 17 秒。是文本字段吗? “持续时间 14 小时 26 分钟。2 秒。0 小时 8 分钟。34 秒。0 小时 12 分钟。17 秒。”
  • 嗨,亚历山大。是的,它是一个文本字段。很抱歉没有提到这一点
  • 注意引号的位置。 Duration 是列的标题,每个时间值是一个元素吗?例如。 “14 小时 26 分 2 秒”、“0 小时 8 分 34 秒”、“0 小时 12 分 17 秒”。还是都是一长串?
  • 嗨,Alexander,很抱歉没有尽快回复。是的,持续时间 = 每个时间值一个元素的标题。提供的 2 个答案给了我我正在寻找的东西。但是,如果您有/想要贡献,我很乐意接受建议。

标签: python numpy time pandas duration


【解决方案1】:

这是直接变频,见here

In [16]: df = pd.DataFrame({'Duration': ['4h 26min. 2sec.',
                                        '0h 8min. 34sec.',
                                        '0h 12min. 17sec.']})

In [17]: df
Out[17]: 
           Duration
0   4h 26min. 2sec.
1   0h 8min. 34sec.
2  0h 12min. 17sec.

这些几乎都是标准格式,只是 zonk 。

In [18]: pd.to_timedelta(df.Duration.str.replace('\.',''))                        
Out[18]: 
0   04:26:02
1   00:08:34
2   00:12:17
Name: Duration, dtype: timedelta64[ns]

几分钟后的浮动结果

In [19]: pd.to_timedelta(df.Duration.str.replace('\.','')) / np.timedelta64(1,'m')
Out[19]: 
0    266.033333
1      8.566667
2     12.283333
Name: Duration, dtype: float64

这会截断

In [20]: pd.to_timedelta(df.Duration.str.replace('\.','')).astype('timedelta64[m]')
Out[20]: 
0    266
1      8
2     12
Name: Duration, dtype: float64

【讨论】:

    【解决方案2】:

    这是一种不使用任何日期解析模块的方法。

    单行 - 您可以通过正则表达式和 applyduration 列上提取数字,例如拆分为多行以提高可读性

    (df['Duration']
     .apply(lambda x: sum([a*int(b) 
                           for a,b in zip([60., 1., 1./60],
                                          re.findall(r'\d+', x))]))
    )
    

    基本上,对于像'4h 26min. 2sec.' 这样的字符串,您首先要找到模式re.findall(r'\d+', x),即[4, 26, 2],现在将其与分钟[60., 1., 1./60]sum 的值相乘。

    假设df 就像

    In [7]: df = pd.DataFrame({'Duration': ['4h 26min. 2sec.',
                                            '0h 8min. 34sec.',
                                            '0h 12min. 17sec.']})
    In [8]: df
    Out[8]:
               Duration
    0   4h 26min. 2sec.
    1   0h 8min. 34sec.
    2  0h 12min. 17sec.
    

    然后,分钟可以像这样提取

    In [9]: (df['Duration']
       ...:  .apply(lambda x: sum([a*int(b)
       ...:                        for a,b in zip([60., 1., 1./60],
       ...:                                       re.findall(r'\d+', x))]))
       ...: )
    Out[9]:
    0    266.033333
    1      8.566667
    2     12.283333
    Name: Duration, dtype: float64
    

    为了可读性,你也可以创建一个自定义函数minutes

    def minutes(string):
        pattern = re.findall(r'\d+', string)
        minutes_mul =  [a*int(b) for a,b in zip([60., 1., 1./60], pattern)]
        return sum(minutes_mul)
    

    然后,然后申请

    df['Duration'].apply(minutes)
    

    【讨论】:

    • 你好约翰高尔特和@Jeff。非常感谢爱尔兰人。我尝试了各种功能,但从未想到过图案。我会为未来记住的东西。使用 Time 是我不习惯的事情,Jeff 提供的链接非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 2022-01-01
    • 2018-10-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    相关资源
    最近更新 更多