【问题标题】:Python Pandas propagate value untill conditionPython Pandas 传播价值直到条件
【发布时间】:2021-04-16 07:56:47
【问题描述】:

DataFrame

我有这个DataFrame(看图)

如果绿色列 (dataframe.Signal) 为 1,我有红色列 (dataframe.Level) 等于我们示例中的某个值 1088.50,否则 dataframe.Level 将是 Nan

现在我想传播红色值 (dataframe.Level),只要它低于或等于棕色值 (dataframe.Brown)

dataframe.Brown低于red值时dataframe.Level必须最后一次等于red值,然后它必须回到nan,就像在照片中一样。

我怎么能做这样的事情? 我尝试对 lops 使用 normal,但这个数据帧包含 600 万行,而且速度太慢。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    TL;DR

    left = df.loc[df["Signal"] == 1].index
    right = df.loc[df["Brown"] - df["Level"].ffill() < 0] \ 
              .groupby(df["Signal"].cumsum(), as_index=False) \
              .nth(0).index
    subsets = pd.cut(df.index, pd.IntervalIndex.from_arrays(left, right, closed="both"))
    df = df.groupby(subsets).ffill()
    

    输入数据:

          Brown  Signal    Level
    0   1089.00       0      NaN
    1   1089.00       0      NaN
    2   1088.50       0      NaN
    3   1088.50       0      NaN
    4   1088.50       1  1088.50  # 1088.50 <= start here (4)
    5   1088.50       0      NaN  # 1088.50
    6   1088.50       0      NaN  # 1088.50
    7   1088.50       0      NaN  # 1088.50
    8   1088.50       0      NaN  # 1088.50
    9   1088.75       0      NaN  # 1088.50
    10  1088.50       0      NaN  # 1088.50
    11  1088.25       0      NaN  # 1088.50 <= stop here (11)
    12  1088.50       0      NaN
    13  1088.25       1  1088.25  # 1088.25 <= start here (13)
    14  1088.50       0      NaN  # 1088.25
    15  1088.50       0      NaN  # 1088.25
    16  1088.00       0      NaN  # 1088.25 <= stop here (16)
    17  1088.50       0      NaN
    18  1088.75       0      NaN
    19  1088.50       0      NaN
    20  1088.25       0      NaN
    21  1088.50       0      NaN
    
    1. 查找起始索引(左区间)
    >>> left = df.loc[df["Signal"] == 1].index
    >>> left
    Int64Index([4, 13], dtype='int64')
    
    1. 查找停止索引(右区间)
    >>> right = df.loc[df["Brown"] - df["Level"].ffill() < 0] \ 
                  .groupby(df["Signal"].cumsum(), as_index=False) \
                  .nth(0).index
    >>> right
    Int64Index([11, 16], dtype='int64')
    
    1. 提取所有子集
    >>> subsets = pd.cut(df.index, pd.IntervalIndex.from_arrays(left, right, closed="both"))
    >>> list(subsets)
    [nan,
     nan,
     nan,
     nan,
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     Interval(4.0, 11.0, closed='both'),
     nan,
     Interval(13.0, 16.0, closed='both'),
     Interval(13.0, 16.0, closed='both'),
     Interval(13.0, 16.0, closed='both'),
     Interval(13.0, 16.0, closed='both'),
     nan,
     nan,
     nan,
     nan,
     nan]
    
    1. 在每个区间填写Level值:
    >>> df.groupby(subsets).ffill()
          Brown  Signal    Level
    0   1089.00       0      NaN
    1   1089.00       0      NaN
    2   1088.50       0      NaN
    3   1088.50       0      NaN
    4   1088.50       1  1088.50
    5   1088.50       0  1088.50
    6   1088.50       0  1088.50
    7   1088.50       0  1088.50
    8   1088.50       0  1088.50
    9   1088.75       0  1088.50
    10  1088.50       0  1088.50
    11  1088.25       0  1088.50
    12  1088.50       0      NaN
    13  1088.25       1  1088.25
    14  1088.50       0  1088.25
    15  1088.50       0  1088.25
    16  1088.00       0  1088.25
    17  1088.50       0      NaN
    18  1088.75       0      NaN
    19  1088.50       0      NaN
    20  1088.25       0      NaN
    21  1087.75       0      NaN
    

    【讨论】:

    • 它似乎不起作用,因为左右长度不同,如果您愿意帮助我,请通过电报联系@claudio314 我将通过贝宝向您捐赠尽可能多的钱。谢谢。
    • 请贴一个不起作用的例子。
    • “左右必须有相同的长度”这是我运行上述脚本时遇到的错误
    • 但它适用于输入数据,因为左右具有相同的长度。为了帮助你,我需要一个不起作用的例子。
    • 我仍然不明白 RIGHT 在做什么,我看到你想使用棕色低于填充水平的索引,这是正确的假设,我不明白这是做什么的,我想这里是问题 .groupby(df["Signal"].cumsum(), as_index=False).nth(0) 我很确定问题是正确的,因为它没有做它应该做的事情,记住我只想在信号为 1 后传播,我想在棕色低于填充水平时停止传播
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2018-02-05
    • 2017-07-29
    • 2022-01-25
    • 2022-10-23
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多