每次列为 True 时拆分 pandas DataFrame
TL;DR
如果你想用于拆分的 Series 是 DataFrame 中的列,请继续阅读本文。否则,请阅读每次 Series 为 True 时拆分 pandas DataFrame。
使用此实用函数:
split_dataframe_by_column.py
def split_dataframe_by_column(df, column):
"""
在列为 True 的地方拆分 DataFrame。产生多个 dataframe
"""
previous_index = df.index[0]
for split_point in df[df[column]].index:
yield df[previous_index:split_point]
previous_index = split_point
# 产生数据集的剩余部分
try:
yield df[split_point:]
except UnboundLocalError:
pass # 没有分割点 => 忽略
# 使用示例:
list(split_dataframe_by_column(df, "ZeroCrossing"))注意这些 dataframe 中的一个或多个可能为空。
完整示例:
我们将使用我们在上一篇关于如何检测 pandas 字符串列/series 中的值变化的文章中构建的 ZeroCrossing 列,该文章本身基于我们关于如何创建 pandas 时间序列 DataFrame 示例数据集的文章。基于该示例,我们添加上面显示的实用函数:
split_timeseries_example.py
import pandas as pd
# 加载预构建的时间序列示例数据集
df = pd.read_csv("https://techoverflow.net/datasets/timeseries-example.csv", parse_dates=["Timestamp"])
df.set_index("Timestamp", inplace=True)
# 创建包含 "Positive" 或 "Negative" 的新列
df["SinePositive"] = (df["Sine"] >= 0).map({True: "Positive", False: "Negative"})
# 创建 "change" 列(布尔值)
df["ZeroCrossing"] = df["SinePositive"].shift() != df["SinePositive"]
# 将第一个条目设置为 False
df["ZeroCrossing"].iloc[0] = False
def split_dataframe_by_column(df, column):
"""在列为 True 的地方拆分 DataFrame。产生多个 dataframe"""
previous_index = df.index[0]
for split_point in df[df[column]].index:
yield df[previous_index:split_point]
previous_index = split_point
# 产生数据集的剩余部分
try:
yield df[split_point:]
except UnboundLocalError:
pass # 没有分割点 => 忽略
# 打印结果
split_frames = list(split_dataframe_by_column(df, "ZeroCrossing"))
print(f"Split DataFrame into {len(split_frames)} separate frames by zero-crossing")
# 这打印 "Split DataFrame into 20 separate frames by zero-crossing"If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow