我有一种火车交通数据的时间序列数据框。
df = pd.DataFrame({
'train': [1, 1, 1, 2, 1, 2],
'station': [1000, 1001, 1001, 1000, 1002, 1003],
'time': pd.to_datetime(['20200525 13:30:00',
'20200525 13:45:00',
'20200525 13:50:00',
'20200525 13:35:00',
'20200525 14:10:00',
'20200525 14:00:00']),
'mvt': [10, -1, 2, 20, 0, 0],
},
columns=['train', 'station', 'time', 'mvt'])
在车站上,火车要么驶过低谷,要么挂断或挂了一些教练。 由于这是时间序列数据,因此每个事件都在单独的行中。
我必须合并同一站上同一列火车的行,其中两个动作(mvt)依次发生(第二个时间戳记>第一个时间戳记),并将这些动作放在2个单独的列中。 (mvt_x和mvt_y),并保留最后一次操作的时间戳。 在单行中,mvt_y始终为NaN。
这是预期的结果:
train station time mvt_x mvt_y
0 1 1000 2020-05-25 13:30:00 10 NaN
1 1 1001 2020-05-25 13:50:00 -1 2.0
2 2 1000 2020-05-25 13:35:00 20 NaN
3 1 1002 2020-05-25 14:10:00 0 NaN
4 2 1003 2020-05-25 14:00:00 0 NaN
答案 0 :(得分:2)
创建数据框
import pandas as pd
df = pd.DataFrame({
'train': [1, 1, 1, 2, 1, 2],
'station': [1000, 1001, 1001, 1000, 1002, 1003],
'time': pd.to_datetime(['20200525 13:30:00',
'20200525 13:45:00',
'20200525 13:50:00',
'20200525 13:35:00',
'20200525 14:10:00',
'20200525 14:00:00']),
'mvt': [10, -1, 2, 20, 0, 0],
},
columns=['train', 'station', 'time', 'mvt'])
计算等级,以识别(运动)一对运动1对2的对。然后使用等级对数据框进行整形:
df['rank'] = df.groupby(['train', 'station'])['time'].rank().astype(int)
# re-shape the data frame - 'rank' is part of column label
x = (df.set_index(['train', 'station', 'rank'])
.unstack(level='rank')
.reset_index())
# find rows with a time with rank=2 ...
mask = x.loc[:, ('time', 2)].notna()
# ... and replace time-1 with time-2 (keep later time only)
x.loc[mask, ('time', 1)] = x.loc[mask, ('time', 2)]
# drop time-2
x = x.drop(columns=('time', 2))
# re-name columns
x.columns = ['train', 'station', 'time', 'mvt_x', 'mvt_y']
print(x)
train station time mvt_x mvt_y
0 1 1000 2020-05-25 13:30:00 10.0 NaN
1 1 1001 2020-05-25 13:50:00 -1.0 2.0
2 1 1002 2020-05-25 14:10:00 0.0 NaN
3 2 1000 2020-05-25 13:35:00 20.0 NaN
4 2 1003 2020-05-25 14:00:00 0.0 NaN
答案 1 :(得分:1)
打败我,但这里是多次访问同一电台的案例的代码
# change df.time to the last time on each station
# sort by time to account for for multiple visits to a station
df = df.sort_values(['train', 'time', 'station'])
stopid = df.station.diff().cumsum().fillna(0).astype(int)
df.time = df.groupby(['train', 'station', stopid]).time.transform('last')
# create index for mvt on train_station groups
df = df.assign(mvt_id=df.groupby(['train', 'station', 'time']).cumcount())
# reshape df, similar to pivot
df = (
df.set_index(['train', 'station', 'time', 'mvt_id'])
.unstack('mvt_id').droplevel(0, axis=1)
)
df.columns = ['mvt_x', 'mvt_y'] # hardcoded for only 2 movements per station
# might need a generator if expecting more than 2 mvts
df = df.reset_index()
print(df)
输出
train station time mvt_x mvt_y
0 1 1000 2020-05-25 13:30:00 10.0 NaN
1 1 1001 2020-05-25 13:50:00 -1.0 2.0
2 1 1002 2020-05-25 14:10:00 0.0 NaN
3 2 1000 2020-05-25 13:35:00 20.0 NaN
4 2 1003 2020-05-25 14:00:00 0.0 NaN