我有表.csv:
ID,X,X_2,X_3,Rank
XJ5,30,24,37,1
XK4,20,22,20,1
XK5,33,27,38,1
XK7,22,19,22,1
XJ5,33,22,21,2
XK4,20,22,22,2
XK5,33,24,29,2
XK6,23,21,22,2
XJ5,24,22,19,3
XK4,21,20,34,3
XK5,19,22,32,3
XK6,44,24,21,3
XK7,32,21,23,3
并且想要输出表格:
ID,X,X_2,X_3,Rank,PrevX
XJ5,30,24,37,1,NA
XK4,20,22,20,1,NA
XK5,33,27,38,1,NA
XK7,22,19,22,1,NA
XJ5,33,22,21,2,30
XK4,20,22,22,2,20
XK5,33,24,29,2,33
XK6,23,21,22,2,NA
XJ5,24,22,19,3,33
XK4,21,20,34,3,20
XK5,19,22,32,3,33
XK6,44,24,21,3,23
XK7,32,21,23,3,NA
新的 PrevX 列是 Rank-1 行中 ID 的 X 值
这是我到目前为止所拥有的:
import pandas
df = pandas.read_csv('table.csv')
最佳答案
更新
一种方法是:
- 使用
groupby
对每个id
的数据进行分组为每个组申请以下内容: - 使用
sort_values
按排名
排序 - 使用
shift
创建一个临时列,其中排名
移动一位 - 使用
add
将1
添加到此新列 - 使用
np.where
将此新列与rank
列进行比较:如果相等,则分配之前的X
值,否则分配NaN
可选以匹配预期输出:
- 使用
drop
删除无用的列 - 使用
reset_index
重置索引 - 使用
sort_values
按排名
排序.
- 使用
代码如下:
def get_previous(df):
df = df.sort_values(by="Rank")
df["rank_shifted"] = df.Rank.shift().add(1)
df["PrevX"] = np.where(df.rank_shifted == df.Rank, df.X.shift(), np.NaN)
return df
df = df.groupby('ID').apply(get_previous)
print(df)
# ID X X_2 X_3 Rank rank_shifted PrevX
# ID
# XJ5 0 XJ5 30 24 37 1 NaN NaN
# 3 XJ5 33 22 21 2 2.0 30.0
# 6 XJ5 24 22 19 3 3.0 33.0
# XK4 1 XK4 20 22 20 1 NaN NaN
# 4 XK4 20 22 22 2 2.0 20.0
# 7 XK4 21 20 34 3 3.0 20.0
# XK5 2 XK5 33 27 38 1 NaN NaN
# 5 XK5 33 24 29 2 2.0 33.0
# 8 XK5 19 22 32 3 3.0 33.0
# Match output
df = df.reset_index(drop=True).sort_values(by="Rank").drop("rank_shifted", axis=1)
print(df)
# ID X X_2 X_3 Rank PrevX
# 0 XJ5 30 24 37 1 NaN
# 3 XK4 20 22 20 1 NaN
# 6 XK5 33 27 38 1 NaN
# 1 XJ5 33 22 21 2 30.0
# 4 XK4 20 22 22 2 20.0
# 7 XK5 33 24 29 2 33.0
# 2 XJ5 24 22 19 3 33.0
# 5 XK4 21 20 34 3 20.0
# 8 XK5 19 22 32 3 33.0
原始答案
假设排名始终由 3 行组成,您可以使用 shift
:
df["PrevX"] = df.X.shift(3)
print(df)
# ID X X_2 X_3 Rank PrevX
# 0 XJ5 30 24 37 1 NaN
# 1 XK4 20 22 20 1 NaN
# 2 XK5 33 27 38 1 NaN
# 3 XJ5 33 22 21 2 30.0
# 4 XK4 20 22 22 2 20.0
# 5 XK5 33 24 29 2 33.0
# 6 XJ5 24 22 19 3 33.0
# 7 XK4 21 20 34 3 20.0
# 8 XK5 19 22 32 3 33.0
如果您不知道每个rank
组的行数,可以使用 groupby
找到它和 size
:
print(df.groupby('Rank').size())
# Rank
# 1 3
# 2 3
# 3 3
希望有帮助!
关于python - 如何从Python数据帧中行的前一个密集等级读取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57348392/