【问题标题】:Fill DataFrame Non-Zero Row Value with The Nearest Maximum Value and Reset After Zero Occurrence用最近的最大值填充DataFrame非零行值并在零出现后重置
【发布时间】:2021-07-15 22:35:02
【问题描述】:

我有两个 MultiIndex 列 DataFrame,“Boolean DataFrame”和“Consecutive Boolean Count DataFrame”。

“Consecutive Boolean Count DataFrame”的值使用cumsum(列轴,正向)标记相应位置连续出现的布尔数。 False 被标记为零。布尔值连续出现的次数从 1 开始再次计数为零值。

我想用“连续布尔计数数据帧”做一些事情,比如向后填充最近的最大值,并在零值发生后重置要填充的值。有些行为类似于pandas.DataFrame.bfill,但不完全相同。我找不到与行为完全匹配的 API。

目的是标记不同组的连续布尔值出现的次数,显示对应组中每个连续布尔位置的最后一个cumsum值。 (一组指连续的布尔值)

布尔数据框:

A B C
Boolean Boolean Boolean
0 True True True
1 True False False
2 True True False
3 False True True
4 False False True
5 True True True
6 False True True
7 True False False
8 True False True
9 False True True
10 False False False

连续布尔计数数据帧:

A B C
Boolean Boolean Boolean
0 1 1 1
1 2 0 0
2 3 1 0
3 0 2 1
4 0 0 2
5 1 1 3
6 0 2 4
7 1 0 0
8 2 0 1
9 0 1 2
10 0 0 0

预期输出:

A B C
Boolean Boolean Boolean
0 3 1 1
1 3 0 0
2 3 2 0
3 0 2 4
4 0 0 4
5 1 2 4
6 0 2 4
7 2 0 0
8 2 0 2
9 0 1 2
10 0 0 0

代码:

columns = pd.MultiIndex.from_product( [ [ 'A', 'B', 'C' ], [ 'Boolean' ] ] )

boolean_df = pd.DataFrame( [ [True, True, True ], 
[ True, False, False ], 
[ True, True, False ],
[ False, True, True ],
[ False, False, True ],
[ True, True, True ],
[ False, True, True ],
[ True, False, False ],
[ True, False, True ],
[ False, True, True ],
[ False, False, False ],
], columns=columns )

consecutive_boolean_df = boolean_df .cumsum() - boolean_df .cumsum().where( ~boolean_df ).ffill().fillna( 0 )

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    这是一种方法:

    def max_streak(srs):
        groups = (srs!=srs.shift()).cumsum()
        streaks = srs.groupby(groups).transform("size")
        streaks[~srs] = 0 #streaks is 0 where the series is False
        return streaks
    
    >>> boolean_df.apply(max_streak)
             A       B       C
       Boolean Boolean Boolean
    0        3       1       1
    1        3       0       0
    2        3       2       0
    3        0       2       4
    4        0       0       4
    5        1       2       4
    6        0       2       4
    7        2       0       0
    8        2       0       2
    9        0       1       2
    10       0       0       0
    

    要在一行中完成以上所有操作,您可以:

    >>> boolean_df.apply(lambda srs: srs.groupby((srs!=srs.shift()).cumsum()).transform("size").where(srs, 0))
    

    【讨论】:

      猜你喜欢
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 2023-01-31
      • 2022-06-16
      • 2020-03-25
      • 1970-01-01
      相关资源
      最近更新 更多