将负日期时间转换为NaT
我有两栏:“问”和“回答”,但“回答”是一个对象,而“询问”是datetime64 [ns],所以我将'已回答'转换为日期时间:将负日期时间转换为NaT
df['answered'] = pd.to_datetime(df['answered'])
index, asked, answered
0 2016-07-04 07/07/2016
1 2016-07-03 07/01/2016
2 2016-07-05 07/09/2016
3 NaT NaN
于是,我做了一个第三列,让我在两者之间的时间差:
df['Days']= df['answered'] - df['asked']
index, asked, answered, Days
0 2016-07-04 07/07/2016 3 days
1 2016-07-03 07/01/2016 -2 days
2 2016-07-05 07/09/2016 4
3 NaT NaN NaT
随着@piRSquared的帮助下,我试图把负天进一个NAT,但当我这样做时什么都没有发生:
df.update(df[['Days']].mask(df < 0))
我该如何将负面日子转换为NaT?
对我来说作品comapre Series
(列)由0 Timedelta
,然后通过Series.mask
或loc
创建NaT
:
mask = df['Days'] < pd.Timedelta(0)
df['Days'] = df['Days'].mask(mask)
print (df)
asked answered Days
0 2016-07-04 2016-07-07 3 days
1 2016-07-03 2016-07-01 NaT
2 2016-07-05 2016-07-09 4 days
3 NaT NaT NaT
或者:
mask = df['Days'] < pd.Timedelta(0)
df.loc[mask, 'Days'] = np.nan
print (df)
asked answered Days
0 2016-07-04 2016-07-07 3 days
1 2016-07-03 2016-07-01 NaT
2 2016-07-05 2016-07-09 4 days
3 NaT NaT NaT
但是,如果与DataFrame
比较0 Timedelta
它是越野车:
print (df)
asked answered Days Days2
0 2016-07-04 2016-07-07 3 days 3 days
1 2016-07-03 2016-07-01 -2 days -2 days
2 2016-07-05 2016-07-09 4 days 4 days
3 NaT NaT NaT NaT
df1 = df.select_dtypes([np.timedelta64])
#return wrong mask
m1 = df1 < pd.Timedelta(0)
print (m1)
Days Days2
0 False False
1 False False
2 False False
3 True True
#if comapre with apply by Series it works
m2 = df1.apply(lambda x: x < pd.Timedelta(0))
print (m2)
Days Days2
0 False False
1 True True
2 False False
3 False False
#compare numpy array works but warning
m3 = df1.values < np.array(0, dtype=np.timedelta64)
print (m3)
[[False False]
[ True True]
[False False]
[ True True]]
FutureWarning:未来,'NAT < x'和'x < NAT'将始终为False。
df[df1.columns] = df1.mask(m2)
print (df)
asked answered Days Days2
0 2016-07-04 2016-07-07 3 days 3 days
1 2016-07-03 2016-07-01 NaT NaT
2 2016-07-05 2016-07-09 4 days 4 days
3 NaT NaT NaT NaT
使用mask
df.mask(df < 0)
Days col2
index
0 20 days NaT
1 61 days 78 days
2 NaT 10 days
pd.DataFrame.mask
需要标识的位置,以掩盖布尔值的阵列。如果传递了可选的第二个参数,它将用可选参数中指定的值替换已标识位置中的值。如果该参数没有通过,就像在我提出的解决方案中一样,那么标识值将被替换为空值。由于这些列的dtypes
是timedelta
,因此适当的空值将是NaT
。
假设您的数据框由许多列组成。您可以专注于您关心的特定列。
df[['Days', 'col2']].mask(df < 0)
然后你就可以更新
df.update(df[['Days', 'col2']].mask(df < 0))
DF就地假设你想抓住那名中的所有列timedelta
df.select_dtypes([np.timedelta]).mask(df < 0)
和更新
df.update(df.select_dtypes([np.timedelta64]).mask(df < 0))
我得到“无效类型比较”。是因为我有更多的专栏,只有这两个我放在这里?我尝试过,但无济于事:df。mask(df ['Days']
@AdamSchroeder我更新了我的帖子。由于某种原因, – piRSquared
仍然无法工作。当我打印出否定日期时,我会得到:“-5天+00:00:00”。您提供的解决方案不会引发错误,但不会将负面变为NaT。有没有其他解决方案可以解决这个问题? –
谢谢@jezrael我一直在为此工作数小时。你的解决方案和详细的解释真的帮了我。 –