基于模式筛选熊猫系列



新年快乐!

我有一个快速的问题:假设我有一场熊猫系列赛,有3场像这样的比赛

myEvents = pd.Series(['up', 'down', 'None', 'None, 'up', 'down', 'down', 'up', 'up'])

我只想保留"有效"事件:有效事件是一个向上后跟向下或向下后跟向上,即使两者之间有一个或多个"无"。此外,应忽略"向上"之后的所有"上"(与连续"向下"相同(

因此,举个例子,我想最终得到类似的东西

myEvents_filtered = pd.Series(['up', 'down', 'up', 'down', 'up'])

这里最优雅的解决方案是什么?我可以完全用熊猫来做吗?或者我应该使用状态机或类似的东西,因为我会有其他类似的用例(比如在"down"后面得到所有的None(?

谢谢!

算法:

  1. 删除所有";无";序列中的行
  2. 获取上一行值的列
  3. 筛选出当前值等于前一行值的行

代码:

# 1)
df = pd.DataFrame(
{"my_events": my_events}
)
df = df[df["my_events" != "None"]]
# 2)
df["my_events_previous"] = df["my_events"].shift(1)
# 3)
final_result_df = df[
df["my_events_previous"] != df["my_events"]
]
print(final_result_df["my_events"])

关键的见解是使用.shift((,它可以应用于其他用例。

这应该会得到您想要的输出。它基本上删除"None"的值,然后删除连续的重复项。

import pandas as pd
myEvents = pd.Series(['up', 'down', 'None', 'None', 'up', 'down', 'down', 'up', 'up'])
myEvents_filtered = myEvents.mask(myEvents.eq('None')).dropna()
myEvents_filtered = myEvents_filtered.loc[myEvents_filtered.shift() != myEvents_filtered]
print(myEvents_filtered)

就保留最后一个任务而不是第一个任务而言,您需要按索引对序列进行反向排序,删除第一个任务,然后将序列反向排序回原始顺序:

import pandas as pd
myEvents = pd.Series(['up', 'down', 'None', 'None', 'up', 'down', 'down', 'up', 'up'])
myEvents_filtered = myEvents.mask(myEvents.eq('None')).dropna()
myEvents_filtered_rev = myEvents_filtered.iloc[::-1]
myEvents_filtered_rev = myEvents_filtered_rev.loc[myEvents_filtered_rev.shift() != myEvents_filtered_rev]
myEvents_filtered = myEvents_filtered_rev.iloc[::-1]
print(myEvents_filtered)

最新更新