我有一个pandas数据框,我想检查每一列,如果某个值曾经达到.92或以下,我想将其后的每个值都更改为1。是否有一种简单的方法来实现?

最佳答案

考虑数据框df

np.random.seed([3,1415])
df = pd.DataFrame(np.random.rand(10, 10) * 10, columns=list('ABCDEFGHIJ')).round(2)


在布尔数据框上使用cumprod。然后在pd.DataFrame.where中使用它

df.where(df.gt(.92).cumprod().astype(bool), 1)

      A     B    C     D     E    F     G     H     I     J
0  4.45  4.08  4.6  4.65  4.63  1.0  8.50  8.18  7.78  7.58
1  9.35  8.31  8.8  9.27  7.22  1.0  1.46  2.00  4.38  1.01
2  2.79  6.10  1.0  8.37  7.40  1.0  6.91  3.77  2.25  4.35
3  7.01  7.01  1.0  1.00  7.01  1.0  7.65  2.53  5.48  7.79
4  6.52  1.36  1.0  1.00  2.75  1.0  7.14  7.76  5.42  8.37
5  5.38  1.86  1.0  1.00  3.74  1.0  7.76  1.00  5.04  6.71
6  6.20  3.02  1.0  1.00  3.68  1.0  8.82  1.00  4.96  8.06
7  1.00  4.38  1.0  1.00  1.00  1.0  5.85  1.00  6.39  1.33
8  1.00  8.82  1.0  1.00  1.00  1.0  1.00  1.00  6.06  4.02
9  1.00  6.41  1.0  1.00  1.00  1.0  1.00  1.00  1.09  3.15




我的解决方案有些困扰我。所以我asked my own question here.。考虑到链接问题的建议,这是一个更好的解决方案。请考虑点击链接,并对问题和答案表示赞赏。谢谢。

v = df.values
mask = np.logical_and.accumulate(v > .92, 0)
pd.DataFrame(
    np.where(mask, v, 1),
    df.index, df.columns
)

      A     B    C     D     E    F     G     H     I     J
0  4.45  4.08  4.6  4.65  4.63  1.0  8.50  8.18  7.78  7.58
1  9.35  8.31  8.8  9.27  7.22  1.0  1.46  2.00  4.38  1.01
2  2.79  6.10  1.0  8.37  7.40  1.0  6.91  3.77  2.25  4.35
3  7.01  7.01  1.0  1.00  7.01  1.0  7.65  2.53  5.48  7.79
4  6.52  1.36  1.0  1.00  2.75  1.0  7.14  7.76  5.42  8.37
5  5.38  1.86  1.0  1.00  3.74  1.0  7.76  1.00  5.04  6.71
6  6.20  3.02  1.0  1.00  3.68  1.0  8.82  1.00  4.96  8.06
7  1.00  4.38  1.0  1.00  1.00  1.0  5.85  1.00  6.39  1.33
8  1.00  8.82  1.0  1.00  1.00  1.0  1.00  1.00  6.06  4.02
9  1.00  6.41  1.0  1.00  1.00  1.0  1.00  1.00  1.09  3.15




定时

%timeit df.where(df.gt(.92).cumprod().astype(bool), 1)
1000 loops, best of 3: 844 µs per loop

%%timeit
v = df.values
mask = np.logical_and.accumulate(v > .92, 0)
pd.DataFrame(
    np.where(mask, v, 1),
    df.index, df.columns
)
10000 loops, best of 3: 65.8 µs per loop

10-06 00:52