Python 计算dataframe中多行上的日期时间差异
我有一个关于数据帧中日期时间的python相关问题。我通过Python 计算dataframe中多行上的日期时间差异,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个关于数据帧中日期时间的python相关问题。我通过pd.read\u csv() 我想知道标有A、B、C的行之间的时差,如下所示: datetime label d_time 0 2017-01-03 23:52:00 1 2017-01-03 23:53:00 A 0:02 2 2017-01-03 23:54:00 A 3 2017-01-03 23:55:00 A 4 2017
pd.read\u csv()
我想知道标有A、B、C的行之间的时差,如下所示:
datetime label d_time
0 2017-01-03 23:52:00
1 2017-01-03 23:53:00 A 0:02
2 2017-01-03 23:54:00 A
3 2017-01-03 23:55:00 A
4 2017-01-04 00:01:00
5 2017-01-04 00:02:00 B 0:09
6 2017-01-04 00:06:00 B
7 2017-01-04 00:09:00 B
8 2017-01-04 00:11:00 B
9 2017-01-04 00:12:00
10 2017-01-04 00:14:00
11 2017-01-04 00:16:00
12 2017-01-04 00:18:00 C 0:02
13 2017-01-04 00:20:00 C
14 2017-01-04 00:22:00
因此,
d_time
应该是标记行上的总时间差。大约有100种不同的标签,它们可以从1到x连续变化。必须对+100万行执行此计算,因此循环可能不起作用。有人知道怎么做吗?提前谢谢 如果日期时间是datetime
对象(或pandas.TimeStamp
),则可以将其用于循环
a_rows = []
for row in df.itertuples():
if row.label == 'A':
a_rows.append(row)
elif a_rows:
d_time = a_rows[-1].datetime - a_rows[0].datetime
df.loc[a_rows[0].Index, 'd_time'] = d_time
a_rows = []
有了这个结果
datetime label d_time
0 2017-01-03 23:52:00
1 2017-01-03 23:53:00 A 0 days 00:02:00
2 2017-01-03 23:54:00 A
3 2017-01-03 23:55:00 A
4 2017-01-04 00:01:00
5 2017-01-04 00:02:00 A 0 days 00:07:00
6 2017-01-04 00:06:00 A
7 2017-01-04 00:09:00 A
8 2017-01-04 00:11:00
如果需要,以后可以格式化timedelta
对象
如果datetime列是
string
s,您可以使用df['datetime']=pd.轻松地将它们转换为\u datetime(df['datetime'])
如果datetime是datetime
对象(或pandas.TimeStamp
),您可以将其用于循环
a_rows = []
for row in df.itertuples():
if row.label == 'A':
a_rows.append(row)
elif a_rows:
d_time = a_rows[-1].datetime - a_rows[0].datetime
df.loc[a_rows[0].Index, 'd_time'] = d_time
a_rows = []
有了这个结果
datetime label d_time
0 2017-01-03 23:52:00
1 2017-01-03 23:53:00 A 0 days 00:02:00
2 2017-01-03 23:54:00 A
3 2017-01-03 23:55:00 A
4 2017-01-04 00:01:00
5 2017-01-04 00:02:00 A 0 days 00:07:00
6 2017-01-04 00:06:00 A
7 2017-01-04 00:09:00 A
8 2017-01-04 00:11:00
如果需要,以后可以格式化timedelta
对象
如果datetime列是
字符串
s,您可以使用df['datetime']=pd.轻松地将它们转换为_datetime(df['datetime'])
假设连续标签都相同,并且由1nan分隔
你可以这样做
idx = pd.Series(df[pd.isnull(df['label'])].index)
idx_begin = idx.iloc[:-1] + 1
idx_end = idx.iloc[1:] - 1
d_time = df.loc[idx_end, 'datetime'].reset_index(drop=True) - df.loc[idx_begin, 'datetime'].reset_index(drop=True)
d_time.index = idx_begin
df.loc[idx_begin, 'd_time'] = d_time
如果您的数据集看起来不同,您可能会寻找不同的方法来访问idx\u begin
和idx\u end
,但这适用于您发布的数据集
多个连续的nan
s
如果有多个连续的nan
-值,可以通过将其添加到末尾来解决此问题
df.loc[df[pd.isnull(df['label'])].index, 'd_time'] = None
连续不同标签
这将不同的标签标记为不同的开始和开始。为了实现这一点,您需要在末尾添加df.loc[df[pd.isnull(df['label'])]索引'd_time']=None
df.loc[df[pd.isnull(df['label'])].index, 'd_time'] = None
&(pd.notnull(df['label'])|(pd.notnull(df['label'].shift(1))
部分是因为None!=None
结果
屈服
datetime label d_time
0 2017-01-03 23:52:00 NaN NaT
1 2017-01-03 23:53:00 A 00:01:00
2 2017-01-03 23:54:00 A NaT
3 2017-01-03 23:52:00 NaN NaT
4 2017-01-03 23:53:00 B 00:01:00
5 2017-01-03 23:54:00 B NaT
6 2017-01-03 23:55:00 NaN NaT
7 2017-01-03 23:56:00 NaN NaT
8 2017-01-03 23:57:00 NaN NaT
9 2017-01-04 00:02:00 A 00:07:00
10 2017-01-04 00:06:00 A NaT
11 2017-01-04 00:09:00 A NaT
12 2017-01-04 00:02:00 B 00:07:00
13 2017-01-04 00:06:00 B NaT
14 2017-01-04 00:09:00 B NaT
15 2017-01-04 00:11:00 NaN NaT
最后一系列
如果最后一行与前一行相比没有更改标签,则最后一个系列将不会注册
您可以通过在第一行之后包含此项来防止此问题
if idx[-1] != df.index[-1]:
idx = idx.append(df.index[[-1]]+1)
假设连续的标签都相同,并且由1nan
你可以这样做
idx = pd.Series(df[pd.isnull(df['label'])].index)
idx_begin = idx.iloc[:-1] + 1
idx_end = idx.iloc[1:] - 1
d_time = df.loc[idx_end, 'datetime'].reset_index(drop=True) - df.loc[idx_begin, 'datetime'].reset_index(drop=True)
d_time.index = idx_begin
df.loc[idx_begin, 'd_time'] = d_time
如果您的数据集看起来不同,您可能会寻找不同的方法来访问idx\u begin
和idx\u end
,但这适用于您发布的数据集
多个连续的nan
s
如果有多个连续的nan
-值,可以通过将其添加到末尾来解决此问题
df.loc[df[pd.isnull(df['label'])].index, 'd_time'] = None
连续不同标签
这会将不同的标签标记为不同的开始和开始。为了实现这一点,需要在末尾添加df.loc[df[pd.isnull(df['label'])]].index,“d_time']=None
df.loc[df[pd.isnull(df['label'])].index, 'd_time'] = None
&(pd.notnull(df['label'])|(pd.notnull(df['label'].shift(1))
部分是因为None!=None
结果
屈服
datetime label d_time
0 2017-01-03 23:52:00 NaN NaT
1 2017-01-03 23:53:00 A 00:01:00
2 2017-01-03 23:54:00 A NaT
3 2017-01-03 23:52:00 NaN NaT
4 2017-01-03 23:53:00 B 00:01:00
5 2017-01-03 23:54:00 B NaT
6 2017-01-03 23:55:00 NaN NaT
7 2017-01-03 23:56:00 NaN NaT
8 2017-01-03 23:57:00 NaN NaT
9 2017-01-04 00:02:00 A 00:07:00
10 2017-01-04 00:06:00 A NaT
11 2017-01-04 00:09:00 A NaT
12 2017-01-04 00:02:00 B 00:07:00
13 2017-01-04 00:06:00 B NaT
14 2017-01-04 00:09:00 B NaT
15 2017-01-04 00:11:00 NaN NaT
最后一系列
如果最后一行与前一行相比没有更改标签,则最后一个系列将不会注册
您可以通过在第一行之后包含此项来防止此问题
if idx[-1] != df.index[-1]:
idx = idx.append(df.index[[-1]]+1)
你的回答总是3行,还是仅仅针对所有连续的AWA?总是3行,还是仅仅针对所有连续的AThanks Maarten。也许我应该更精确一些,因为标签A并不总是A,而是来自另一个列表的一些标签。我必须迭代超过100万行,因此使用df.itertuples()进行for循环行不通……第一个问题不是什么大问题,你只需要调整行。label==“a”
。while数据帧的标签总是相同的,还是有更多的标签。一行中总是有3个a
?迭代问题是一个更大的问题,这取决于你需要执行此计算的次数e是多个标签(约100个),并且不总是一行3个,它们可以在一行1到x之间变化。对于每个数据帧,此计算必须进行大约300-400次。也许可以将此澄清添加到您的原始答案中,并添加一个更为复杂的数据集,更像您自己的数据集。感谢Maarten的回复。也许我应该更精确一些,因为标签是a不总是一个,而是另一个列表中的一些标签。而且我必须迭代超过100万行,因此使用df.itertuples()进行for循环行不通……第一个问题不是什么大问题,你只需要调整行。label==“a”
。while数据帧的标签总是相同的,还是有更多的标签。一行中总是有3个a
?迭代问题是一个更大的问题,这取决于你需要执行此计算的次数e是多个标签(大约100个),并非总是一行3个,它们可以在一行1到x之间变化。每个数据帧必须进行大约300-400次计算。也许可以将此澄清添加到原始答案中,并添加一个更复杂的数据集,更像您自己的数据集