每次 Series 为 True 时拆分 pandas DataFrame
在我们的上一篇文章中,我们探讨了如何每次列为 True 时拆分 pandas DataFrame。
此稍微修改的函数也适用于给定的 Series 不是 DataFrame 中的列的情况:
split_dataframe_by_series.py
def split_dataframe_by_series(df, series):
"""
在给定 series 为 True 的地方拆分 DataFrame。产生多个 dataframe
"""
previous_index = df.index[0]
for split_point in df[series].index:
yield df[previous_index:split_point]
previous_index = split_point
# 产生数据集的剩余部分
try:
yield df[split_point:]
except UnboundLocalError:
pass # 没有分割点 => 忽略完整示例
我们将使用我们在上一篇关于如何检测 pandas 字符串列/series 中的值变化的文章中构建的 ZeroCrossing 列,该文章本身基于我们关于如何创建 pandas 时间序列 DataFrame 示例数据集的文章。基于该示例,我们添加上面显示的修改后的实用函数:
split_dataframe_full_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_series(df, series):
"""
在给定 series 为 True 的地方拆分 DataFrame。产生多个 dataframe
"""
previous_index = df.index[0]
for split_point in df[series].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_series(df, df["ZeroCrossing"]))
print(f"Split DataFrame into {len(split_frames)} separate frames by zero-crossing")注意根据你的应用程序,将 split_dataframe_to_series() 的结果转换为 list 可能不是必要的。如果可能,我建议直接使用 for 循环迭代数据帧,例如:
iterate_split_frames.py
for df_section in split_dataframe_by_series(df, df["ZeroCrossing"]):
pass # TODO: 你的代码放在这里!If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow