每次列为 True 时拆分 pandas DataFrame

TL;DR

如果你想用于拆分的 SeriesDataFrame 中的列,请继续阅读本文。否则,请阅读每次 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"

Check out similar posts by category: Pandas, Python