【问题标题】:Replace negative values and 'blocks" of consecutive zeros up to first positive value in pandas series with NaN用 NaN 替换熊猫系列中连续零的负值和“块”直到第一个正值
【发布时间】:2019-06-26 09:22:09
【问题描述】:

我有一个 pandas 数据框,我想识别所有负值并将它们替换为 NaN。此外,所有跟在负值后面的零也应替换为 NaN,直到出现第一个正值。

我认为使用 for 循环遍历数据框中的所有负值应该可以实现我的目标。

例如,对于索引标签为 1737 的负值,我可以使用如下内容:

# list indexes that follow the negative value
indexes = df['counter_diff'].loc[1737:,]
# find first value greater than zero
first_index = next(x for x, val in enumerate(indexes) if val > 0)

然后用 NaN 填充从索引 1737 到 first_index 的值。

但是,我的数据框非常大,所以我想知道是否有可能提出一种利用 pandas 的计算效率更高的方法。

这是一个输入示例:

# input column
In[]
pd.Series({0 : 1, 2 : 3, 3 : -1, 4 : 0, 5 : 0, 7 : 1, 9 : 3, 10 : 0, 11 : -2, 14 : 1})

Out[]
0     1
2     3
3    -1
4     0
5     0
7     1
9     3
10    0
11   -2
14    1
dtype: int64

以及所需的输出:

# desired output
In[]
pd.Series({0 : 1, 2 : 3, 3 : np.nan, 4 : np.nan, 5:np.nan, 7:1, 9:3, 10:0, 11 : np.nan, 14:1})

Out[]
0     1.0
2     3.0
3     NaN
4     NaN
5     NaN
7     1.0
9     3.0
10    0.0
11    NaN
14    1.0
dtype: float64

任何帮助将不胜感激!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以mask 所有0s 并用ffill 向前填充它们,并检查系列中的哪些值小于0。然后使用生成的布尔系列来掩盖原始系列:

    s = pd.Series({0 : 1, 2 : 3, 3 : -1, 4 : 0, 5 : 0, 7 : 1, 9 : 3, 10 : 0, 11 : -2, 14 : 1})
    
    s.mask(s.mask(s.eq(0)).ffill().lt(0))
    
    0     1.0
    2     3.0
    3     NaN
    4     NaN
    5     NaN
    7     1.0
    9     3.0
    10    0.0
    11    NaN
    14    1.0
    dtype: float64
    

    【讨论】:

    • 谢谢,这很好用!您知道是否可以在包含填充值的行的不同列上设置填充条件?例如。如果该行的 B 列等于“a”,则仅在 A 列中填充“-1”。
    • 我不太清楚你的意思@hilde 我建议你在一个新问题中问这个!如果您这样做,请在此处联系我 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 2019-03-04
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多