当列值满足特定顺序时对Pandas DataFrame进行条件判断
假设我有一个这样的数据表:
Placement Value Order
0 high 10 1
1 med 5 2
2 high 9 3
3 low 3 4
4 med 7 5
5 low 2 6
6 med 6 7
7 high 9 8
8 med 4 9
9 low 2 10
10 high 8 11
11 med 6 12
12 high 8 13
13 med 5 14
14 low 1 15
当我遇到“Placement”序列,比如“高 -> 低”、“低 -> 高”、“高 -> 中 -> 低”或“低 -> 中 -> 高”时,我想计算这个序列中“高”和“低”之间的差值,并把这个差值放到一个新列“Diff”的最后一行里。同时,我还想要另一个列“Measured From”,这个列的值是序列第一行的“Order”值。最后,我会删除所有没有新列值的行,这样就能得到一个像这样的数据表:
Placement Value Order Diff Measured From
3 low 3 4 -6 3
7 high 9 8 7 6
9 low 2 10 -7 8
10 high 8 11 6 10
14 low 1 15 -7 13
我想过一种方法,就是查看每一行之前的两个“Placement”值,但我听说在使用Pandas时应该避免使用循环。有没有更有效的方法来找到这些模式并进行计算呢?
2 个回答
2
一种可能的解决办法是,创建三个布尔掩码(也就是用来过滤数据表的工具),然后根据需要移动这些掩码。接着,把不同的数据表合并在一起:
def get_frame(m, nshift):
x = df.loc[m.shift(nshift, fill_value=False), ["Placement", "Value", "Order"]]
x["Diff"] = x["Value"] - df.loc[m, "Value"].values
x["Measured From"] = df.loc[m, "Order"].values
return x
l, m, h = (
df["Placement"].eq("low"),
df["Placement"].eq("med"),
df["Placement"].eq("high"),
)
m1 = l & h.shift(-1)
m2 = h & l.shift(-1)
m3 = l & m.shift(-1) & h.shift(-2)
m4 = h & m.shift(-1) & l.shift(-2)
out = pd.concat(
[get_frame(m1, 1), get_frame(m2, 1), get_frame(m3, 2), get_frame(m4, 2)]
).sort_index()
print(out)
输出结果:
Placement Value Order Diff Measured From
3 low 3 4 -6 3
7 high 9 8 7 6
9 low 2 10 -7 8
10 high 8 11 6 10
14 low 1 15 -7 13
2
代码
out = (df[df['Placement'].ne('med')]
.assign(Diff=lambda x: x['Value'].diff(),
Measured_From=lambda x: x['Order'].shift()
)[lambda x: x['Placement'].ne(x['Placement'].shift())]
.dropna(subset='Measured_From'))
输出
Placement Value Order Diff Measured_From
3 low 3 4 -6.0 3
7 high 9 8 7.0 6
9 low 2 10 -7.0 8
10 high 8 11 6.0 10
14 low 1 15 -7.0 13