// I do here a copy because a "inplace=True" would sort the original "traj" which is perhaps unwanted/unexpected
traj = pandas_sort(traj, "frame")
// Probe by particle, take the difference between frames.
delta = traj.groupby("particle", sort=False).apply(lambda x :
x.set_index("frame", drop=False).diff())
// Keep only deltas between frames that are consecutive.
delta = delta[delta["frame"] == 1]
// Restore the original frame column (replacing delta frame).
del delta["frame"]
After Change
if pos_columns is None:
pos_columns = ["x", "y"]
f_sort = traj.sort_values(["particle", "frame"])
// Compute the difference list of positions, particle, and frame columns.
f_diff = f_sort[list(pos_columns) + ["particle", "frame"]].diff()