如何在Python中将包含小时和分钟的字符串转换为分钟?

6

我有一个数据框 df 中的一列:

Time
2 hours 3 mins
5 hours 10 mins
1 hour 40 mins

我想在df中创建一个新列'Minutes',将该列转换为分钟。
Minutes
123
310
100

有没有Python函数可以做到这一点?

7个回答

11

你需要通过to_datetime将其转换。

s=pd.to_datetime(df.Time.replace({'hours':'hour'},regex=True),format='%H hour %M mins')
s.dt.hour*60+s.dt.minute
Out[406]: 
0    123
1    310
2    100
Name: Time, dtype: int64

我们可以使用 numpydotstr.findall

np.dot(np.array(df.Time.str.findall('\d+').tolist()).astype(int),[60,1])
Out[420]: array([123, 310, 100])

11

使用pd.eval玩转数据分析

df['Minutes'] = pd.eval(
    df['Time'].replace(['hours?', 'mins'], ['*60+', ''], regex=True))
df
              Time Minutes
0   2 hours 3 mins     123
1  5 hours 10 mins     310
2   1 hour 40 mins     100

这个想法是让replace将其转换为数学表达式,然后让pandas对其进行评估:

expr = df['Time'].replace(['hours?', 'mins'], ['* 60 +', ''], regex=True)
expr

0    2 * 60 +  3 
1    5 * 60 + 10 
2    1 * 60 + 40 
Name: Time, dtype: object

pd.eval(expr)
# array([123, 310, 100], dtype=object)

str.extract和乘法

((df['Time'].str.extract(r'(\d+) hour.*?(\d+) min').astype(int) * [60, 1])
            .sum(axis=1))

0    123
1    310
2    100
dtype: int64
写一个简单的正则表达式提取数字,然后使用简单的算术运算转换为分钟。您可以将模式缩短为
(df['Time'].str.extract(r'(\d+)\D*(\d+)').astype(int) * [60, 1]).sum(axis=1)

0    123
1    310
2    100
dtype: int64
根据 @Quang Hoang 的建议。

1
不过,当你总是迟到参加派对时就不行了。 :-). 顺便说一下,我的模式是'(\d+)\D*(\d+)' - Quang Hoang
@QuangHoang 谢谢,这个更短了(如果您不介意的话,我已经更新了),但我的初衷是要在匹配时更加明确。 - cs95
如果某些情况下没有“小时”,该怎么办? - Soufiane Sabiri

2

有没有一个Python函数可以做到这一点?

只有在你自己编写一个之后才有。

def to_minutes(time_string):
    hours, _, minutes, _ = time_string.split(' ')
    return int(hours) * 60 + int(minutes)

结果应该类似于:

结果应该类似于:

>>> to_minutes('2 hours 3 mins')
123

1

我相信你可以将其转换为timedelta并强制转换为timedelta64[m]

pd.to_timedelta(df.Time.str.replace('mins', 'm'), unit='m').astype('timedelta64[m]')

Out[786]:
0    123.0
1    310.0
2    100.0
Name: Time, dtype: float64

0

如果你喜欢lambda函数,你也可以使用:

df.Time.apply(lambda x: sum(np.array([ int(i) for i in re.match(r'(\d+) hour[s]? (\d+) min[s]?', x).groups()]) * [60, 1]))

0
假设时间列始终以相同的格式(相同数量的空格)表示,您可以使用 -。
def Mins(row):
    return int(row['Time'].split(' ')[0])*60 + int(row['Time'].split(' ')[2])

df.apply(Mins,axis=1)

0

我认为没有内置函数,但是你可以自己构建一个函数,然后在pandas中使用.apply()方法。

这可能不是最简短的答案,但它将让你了解如何在Pandas中使用基本的Python函数。我认为这非常有帮助!

我构建的函数:

import re

def calculate_number_of_minutes(hours_string):
    regex = '\d+( )\w+'
    // I build a regex which can find a sequence of digits and a single word


    result = re.finditer(regex, text, re.DOTALL)
    // I find such patterns in the given string

    minutes = 0
    for element in result:
        fragment = element.group()

        if 'hour' in fragment:
            minutes += int(re.search('\d+', fragment).group()) * 60
            // if there are 'hours', the associated number is multiplied by 60
            // and added to the count
        else:
            minutes += int(re.search('\d+', fragment).group())

    return minutes


text = '5 hours 10 mins'
print(calculate_number_of_minutes(text))

它的功能是在字符串中搜索数字,然后计算分钟数。
为了将其应用于您的列,请尝试以下操作:
data.loc[;, 'Time'] = data['Time'].apply(lambda x: calculate_number_of_minutes(x))

希望它有用;)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接