我在python中有一个pandas数据帧,有几列和一个日期时间戳。我想创建一个新列,用于计算输出小于当前时间段的时间。
我目前的表格如下:
datetime output
2014-05-01 01:00:00 3
2014-05-01 01:00:01 2
2014-05-01 01:00:02 3
2014-05-01 01:00:03 2
2014-05-01 01:00:04 1
我正试图让我的桌子有一个额外的列,看起来像这样:
datetime output secondsuntildecrease
2014-05-01 01:00:00 3 1
2014-05-01 01:00:01 2 3
2014-05-01 01:00:02 3 1
2014-05-01 01:00:03 2 1
2014-05-01 01:00:04 1
提前感谢!
答案 0 :(得分:3)
upper_triangle = np.triu(df.output.values < df.output.values[:, None])
df['s_until_dec'] = df['datetime'][upper_triangle.argmax(axis=1)].values - df['datetime']
df.loc[~upper_triangle.any(axis=1), 's_until_dec'] = np.nan
df
datetime output s_until_dec
0 2014-05-01 01:00:00 3 00:00:01
1 2014-05-01 01:00:01 2 00:00:03
2 2014-05-01 01:00:02 3 00:00:01
3 2014-05-01 01:00:03 2 00:00:01
4 2014-05-01 01:00:04 1 NaT
以下是它的工作原理:
df.output.values < df.output.values[:, None]
这会创建一个带有brodcasting的成对比较矩阵([:, None]
创建一个新轴):
df.output.values < df.output.values[:, None]
Out:
array([[False, True, False, True, True],
[False, False, False, False, True],
[False, True, False, True, True],
[False, False, False, False, True],
[False, False, False, False, False]], dtype=bool)
例如,output[0]
小于output[1]
,因此(0,1)的矩阵元素为True。我们需要上三角形,所以我使用np.triu
来获得该矩阵的上三角形。 argmax()
将为我提供第一个True
值的索引。如果我将其传递给iloc,我将得到相应的日期。当然除了最后一个。它包含所有False
,因此我需要将其替换为np.nan
。 .loc
部分检查该案例的矩阵并替换为np.nan
。
答案 1 :(得分:2)
df = pd.DataFrame([3, 2, 3, 2, 1], index=pd.DatetimeIndex(start='2014-05-01 01:00:00', periods=5, freq='S'), columns=['output'])
def f(s):
s = s[s & (s.index > s.name)]
if s.empty:
return np.nan
else:
return (s.index[0] - s.name).total_seconds()
df['secondsuntildecrease'] = df['output'].apply(lambda x: df['output'] < x).apply(f, axis=1)
df
输出
output secondsuntildecrease
2014-05-01 01:00:00 3 1.0
2014-05-01 01:00:01 2 3.0
2014-05-01 01:00:02 3 1.0
2014-05-01 01:00:03 2 1.0
2014-05-01 01:00:04 1 NaN
答案 2 :(得分:1)
这是一个单线
df['seconds_until'] = df.apply(lambda x: pd.to_datetime(df.loc[(df['output'] < x['output']) & (df['datetime'] > x['datetime']), 'datetime'].min()) - pd.to_datetime(x[
'datetime']), axis=1)
输出
datetime output seconds_until
0 2014/05/01 01:00:00 3 00:00:01
1 2014/05/01 01:00:01 2 00:00:03
2 2014/05/01 01:00:02 3 00:00:01
3 2014/05/01 01:00:03 2 00:00:01
4 2014/05/01 01:00:04 1 NaT
答案 3 :(得分:1)
使用numpy的外部减法来获得差异矩阵。
然后使用numpy的三角函数进行过滤,以确保我们仅在未来的时间内采取差异并远离过去。
使用numpy的位置确保我们不会得到所有错误
最后,采取时间差异。
df = pd.DataFrame(
dict(output=[3, 2, 3, 2, 1],
datetime=pd.DatetimeIndex(start='2014-05-01 01:00:00', periods=5, freq='S'))
)
gt0 = np.triu(np.subtract.outer(df.output, df.output), 1) > 0
idx = np.where(gt0.any(1), gt0.argmax(1), np.nan)
-(df.datetime - df.loc[idx, 'datetime'].values).dt.total_seconds()
0 1.0
1 3.0
2 1.0
3 1.0
4 NaN
Name: datetime, dtype: float64
Mine和ayhan似乎比小样本效果最好
ayhan最好超过10,000行