如何更改pandas df中特定行的时间戳

时间:2018-05-25 04:03:58

标签: python pandas indexing

我有pandas df在同一strings内包含不同的时间戳和column。下面显示了一个示例:

一旦时间过了午夜,数据就会吐出这个奇怪的351代码,然后又恢复到12小时的时间。所以低于row 5的时间实际上是12:01:42而row 8的时间是13:00:00。

我可以为这些时间戳添加12小时,但我需要摆脱前3个值。

我尝试通过索引适当的时间(午夜之后)并应用[x[3:] for x in df]来做到这一点。但这会删除此列中的字符串。因此,AABB也会被移除。

我有点坚持如何在不删除未指定值的情况下实现此目的。是否可以在午夜后选择适当的时间(仅限时间戳),删除351,并添加12小时而不会丢失任何数据?

import pandas as pd

k = 5
N = 10

d = ({'Time' : ['18:00:00','AA','BB', '23:00:00','AA','35112:01:42','AA','AA','35113:00:00','AA'],
'Events' : ['ABC','DEF','GHI','JKL','ABC','DEF','GHI','JKL','DEF','JKL'],
'Number1' : ['xx','xx',1,'xx','xx','xx',2,'xx', 'xx', 1]})

df = pd.DataFrame(data=d)

输出:

  Events Number1         Time
0    ABC      xx     18:00:00
1    DEF      xx           AA
2    GHI       1           BB
3    JKL      xx     23:00:00
4    ABC      xx           AA
5    DEF      xx  35112:01:42
6    GHI       2           AA
7    JKL      xx           AA
8    DEF      xx  35113:00:00
9    JKL       1           AA

预期输出:

输出:

  Events Number1         Time
0    ABC      xx     18:00:00
1    DEF      xx           AA
2    GHI       1           BB
3    JKL      xx     23:00:00
4    ABC      xx           AA
5    DEF      xx     24:01:42
6    GHI       2           AA
7    JKL      xx           AA
8    DEF      xx     25:00:00
9    JKL       1           AA

4 个答案:

答案 0 :(得分:2)

str.replace lambda group 添加12

def add_twelve(t):
    return str(int(t[:2]) + 12) + t[2:]

df.Time.str.replace(r'\d{3}(\d{2}:\d{2}:\d{2})', lambda x: add_twelve(x.group(1))) 

0    18:00:00
1          AA
2          BB
3    23:00:00
4          AA
5    24:01:42
6          AA
7          AA
8    25:00:00
9          AA
Name: Time, dtype: object

答案 1 :(得分:2)

让我们尝试使用callable:{/ p> str.replace

df['Time'] = df.Time.str.replace(r'351(\d{2})', lambda x: str(12 + int(x.group(1))))

或者,您可以使用re.compile和列表理解来提高性能:

import re

p = re.compile(r'351(\d{2})')
df['Time'] = [
    p.sub(lambda x: str(12 + int(x.group(1))), y) for y in df['Time'].tolist()
]

df
  Events Number1      Time
0    ABC      xx  18:00:00
1    DEF      xx        AA
2    GHI       1        BB
3    JKL      xx  23:00:00
4    ABC      xx        AA
5    DEF      xx  24:01:42
6    GHI       2        AA
7    JKL      xx        AA
8    DEF      xx  25:00:00
9    JKL       1        AA

答案 2 :(得分:1)

您可以使用掩码然后应用一些字符串操作,即

mask = df['Time'].str.startswith('351')

df.loc[mask,'Time'] = (df[mask]['Time'].str[3:].str[:2].astype(int)+12).astype(str) + df[mask]['Time'].str[3:].str[2:]


    Events Number1    Time
0    ABC      xx  18:00:00
1    DEF      xx        AA
2    GHI       1        BB
3    JKL      xx  23:00:00
4    ABC      xx        AA
5    DEF      xx  24:01:42
6    GHI       2        AA
7    JKL      xx        AA
8    DEF      xx  25:00:00
9    JKL       1        AA

因为它的351需要被删除所以选择的方式就是选择,即

df[mask]['Time'].str[3:]

5    12:01:42
8    13:00:00
Name: Time, dtype: object

(df[mask]['Time'].str[3:].str[:2])

5    12
8    13
Name: Time, dtype: object

答案 3 :(得分:0)

我的尝试是:

创建一个用于索引损坏数据的列:

df['corruptedTime'] = df.Time.str.startswith('351')

删除了奇怪的351':

df.loc[df.corruptedTime, 'Time'] = df.Time[df.corruptedTime].str.slice(3)

每小时加12,以模数24计算:

df.loc[df.corruptedTime, 'Time'] = df.Time[df.corruptedTime].apply(lambda s: str((int(s[:2]) + 12) % 24).zfill(2) + s[2:])

如果不再需要,请删除索引器:

df = df.drop(columns=['corruptedTime'])

  Events Number1      Time
0    ABC      xx  18:00:00
1    DEF      xx        AA
2    GHI       1        BB
3    JKL      xx  23:00:00
4    ABC      xx        AA
5    DEF      xx  00:01:42
6    GHI       2        AA
7    JKL      xx        AA
8    DEF      xx  01:00:00
9    JKL       1        AA