将字符串小时数转换为分钟数 pd.eval

Convert string hours to minute pd.eval

我想将我的 DataFrame 中包含小时和分钟的所有行仅转换为分钟。 我有一个看起来像这样的数据框:

df=
    time
0    8h30
1    14h07
2    08h30
3    7h50
4    8h0 
5    8h15
6    6h15

我正在使用以下方法进行转换:

df['time'] = pd.eval(
    df['time'].replace(['h'], ['*60+'], regex=True))

输出

SyntaxError: invalid syntax

我认为错误来自小时的格式,可能pd.eval不能接受08h308h0,如何解决这个问题?

为了避免 trim 前导零,另一种方法是:

df[['h', 'm']] = df['time'].str.split('h', expand=True).astype(int)
df['total_min'] = df['h']*60 + df['m']

结果:

    time   h   m      total_min
0   8h30   8  30            510
1  14h07  14   7            847
2  08h30   8  30            510
3   7h50   7  50            470
4    8h0   8   0            480
5   8h15   8  15            495
6   6h15   6  15            375
如果字符串中包含单位,

Pandas 已经可以处理此类字符串。虽然 14h07 无法解析(为什么假设 07 是分钟?),但 14h07 可以转换为 Timedelta :

>>> pd.to_timedelta("14h07m")
Timedelta('0 days 14:07:00')

鉴于此数据框:

d1 = pd.DataFrame(['8h30m', '14h07m', '08h30m', '8h0m'],
                  columns=['time'])

您可以将 time 系列转换为具有 pd.to_timedelta 的 Timedelta 系列:

>>> d1['tm'] = pd.to_timedelta(d1['time'])
>>> d1
     time              tm
0   8h30m 0 days 08:30:00
1  14h07m 0 days 14:07:00
2  08h30m 0 days 08:30:00
3    8h0m 0 days 08:00:00

要处理原始数据中缺失的分钟单位,只需追加m:

d1['tm'] = pd.to_timedelta(d1['time'] + 'm')

有了 Timedelta 之后,您就可以计算小时和分钟了。

可以使用 Timedelta.components

检索值的组成部分
>>> d1.tm.dt.components.hours
0     8
1    14
2     8
3     8
Name: hours, dtype: int64

要获取总分钟、秒或小时,请将频率更改为分钟:

>>> d1.tm.astype('timedelta64[m]')
0    510.0
1    847.0
2    510.0
3    480.0
Name: tm, dtype: float64

将所有操作整合在一起:

>>> d1['tm'] = pd.to_timedelta(d1['time'])
>>> d2 = (d1.assign(h=d1.tm.dt.components.hours,
...                 m=d1.tm.dt.components.minutes,
...                 total_minutes=d1.tm.astype('timedelta64[m]')))
>>>
>>> d2
     time              tm   h   m  total_minutes
0   8h30m 0 days 08:30:00   8  30          510.0
1  14h07m 0 days 14:07:00  14   7          847.0
2  08h30m 0 days 08:30:00   8  30          510.0
3    8h0m 0 days 08:00:00   8   0          480.0

只是为了提供一种与上面相同的元素的替代方法,您可以这样做:

df = pd.DataFrame(data=["8h30", "14h07", "08h30", "7h50", "8h0 ", "8h15", "6h15"],
                  columns=["time"])

首先在“h”上拆分你的列

hm = df["time"].str.split("h", expand=True)

然后再次合并这些列,但为了生成有效的时间字符串,zeropad time hours and minutes:

df2 = hm[0].str.strip().str.zfill(2) + hm[1].str.strip().str.zfill(2)

然后将具有适当值的字符串列转换为日期时间列:

df3 = pd.to_datetime(df2, format="%H%M")

最后,通过减去零时间(得到 deltatimes)并除以分钟 deltatime 来计算分钟数:

zerotime= pd.to_datetime("0000", format="%H%M")
df['minutes'] = (df3 - zerotime) / pd.Timedelta(minutes=1)

结果如下:

    time  minutes
0   8h30    510.0
1  14h07    847.0
2  08h30    510.0
3   7h50    470.0
4   8h0     480.0
5   8h15    495.0
6   6h15    375.0