Pandas在特定值之后的第1列中生成所有值

时间:2017-06-14 00:49:38

标签: python pandas dataframe

我有一个pandas数据帧,我想检查每一列,如果某个值达到.92或更低,我想将其后的每个值更改为1.是否有一种简单的方法可以实现此目的?

1 个答案:

答案 0 :(得分:2)

考虑数据框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