我有以下数据:
Trajectory Direction Resulting_Direction
STRAIGHT NORTH NORTH
STRAIGHT NaN NORTH
LEFT NaN WEST
LEFT NaN WEST
LEFT NaN WEST
STRAIGHT NaN WEST
STRAIGHT NaN WEST
RIGHT NaN NORTH
RIGHT NaN NORTH
RIGHT NaN NORTH我的目标是,每当我遇到三条直线轨迹时,都要改变方向。因此,在本例中,我的新列是Resulting_Direction (假设它最初不在df中)。
目前,我正在通过执行逐行if-语句来完成此操作。然而,这是令人痛苦的缓慢和低效。我希望使用一个掩码来设置产生的方向在它转弯的行,然后使用填充it (method=“ffill”)。这是我的尝试:
df.loc[:,'direction'] = np.NaN
df.loc[df.index == 0, "direction"] = "WEST"
# mask is for finding when a signal hasnt changed in three seconds, but now has
mask = (df.trajectory != df.trajectory.shift(1)) & (df.trajectory == df.trajectory.shift(-1)) & (df.trajectory == df.trajectory.shift(-2))
df.loc[(mask) & (df['trajectory'] == 'LEFT') & (df['direction'].dropna().shift() == "WEST"),'direction'] = 'SOUTH'
df.loc[(mask) & (df['trajectory'] == 'LEFT') & (df['direction'].dropna().shift() == "SOUTH"),'direction'] = 'EAST'
df.loc[(mask) & (df['trajectory'] == 'LEFT') & (df['direction'].dropna().shift() == "EAST"),'direction'] = 'NORTH'
df.loc[(mask) & (df['trajectory'] == 'LEFT') & (df['direction'].dropna().shift() == "NORTH"),'direction'] = 'WEST'
df.loc[(mask) & (df['trajectory'] == 'RIGHT') & (df['direction'].dropna().shift() == "WEST"),'direction'] = 'NORTH'
df.loc[(mask) & (df['trajectory'] == 'RIGHT') & (df['direction'].dropna().shift() == "SOUTH"),'direction'] = 'WEST'
df.loc[(mask) & (df['trajectory'] == 'RIGHT') & (df['direction'].dropna().shift() == "EAST"),'direction'] = 'SOUTH'
df.loc[(mask) & (df['trajectory'] == 'RIGHT') & (df['direction'].dropna().shift() == "NORTH"),'direction'] = 'EAST'
df.loc[:,'direction'] = df.direction.fillna(method="ffill")
print(df[['trajectory','direction']])我相信我的问题是在df'direction'.dropna().shift().如何在不属于NaN的同一列中找到前面的值?
发布于 2019-07-16 23:24:25
问题在于检测方向变化的位置,据推测,在连续三个更改命令的开头:
thresh = 3
# mark the consecutive direction commands
blocks = df.Trajectory.ne(df.Trajectory.shift()).cumsum()
# group by blocks
groups = df.groupby(blocks)
# enumerate each block
df['mask'] = groups.cumcount()
# shift up to mark the beginning
# mod thresh to divide each block into small block of thresh
df['mask'] = groups['mask'].shift(1-thresh) % thresh
# for conversion of direction to letters:
changes = {'LEFT': -1,'RIGHT':1}
# all the directions
directions = ['NORTH', 'EAST', 'SOUTH', 'WEST']
# update directions according to the start direction
start = df['Direction'].iloc[0]
start_idx = directions.index(start)
directions = {k%4: v for k,v in enumerate(directions, start=start_idx)}
# update direction changes
direction_changes = (df.Trajectory
.where(df['mask'].eq(2)) # where the changes happends
.map(changes) # replace the changes with number
.fillna(0) # where no direction change is 0
)
# mod 4 for the 4 direction
# and map
df['Resulting_Direction'] = (direction_changes.cumsum() % 4).map(directions)输出:
Trajectory Direction Resulting_Direction mask
0 STRAIGHT NORTH NORTH NaN
1 STRAIGHT NaN NORTH NaN
2 LEFT NaN WEST 2.0
3 LEFT NaN WEST NaN
4 LEFT NaN WEST NaN
5 STRAIGHT NaN WEST NaN
6 STRAIGHT NaN WEST NaN
7 RIGHT NaN NORTH 2.0
8 RIGHT NaN NORTH NaN
9 RIGHT NaN NORTH NaNhttps://stackoverflow.com/questions/57065100
复制相似问题