如何计算99%和1%百分位数作为每列的上限和下限,if值> = 99%百分位数然后将该值重新定义为99%百分位数的值;同样,如果值< = 1%百分位数,则将值重新定义为1%百分位值
np.random.seed(2)
df = pd.DataFrame({'value1': np.random.randn(100), 'value2': np.random.randn(100)})
df['lrnval'] = np.where(np.random.random(df.shape[0])>=0.7, 'learning', 'validation')
如果我们有数百列,我们可以使用apply函数而不是do循环吗?
答案 0 :(得分:1)
您可以先定义一个辅助函数,该函数接受series
和value
作为参数,并根据上述条件更改该值:
def scale_val(s, val):
percentiles = s.quantile([0.01,0.99]).values
if val <= percentiles[0]:
return percentiles[0]
elif val >= percentiles[1]:
return percentiles[1]
else:
return val
然后您可以使用pd.DataFrame.apply
和pd.Series.apply
:
df.apply(lambda s: s.apply(lambda v: scale_val(s,v)))
请注意,如果您处理大量数据,这可能会有点慢,但我建议您先试一试,看看它是否能在合理的时间内解决您的问题。
如果您只想获得列df
等于&#34;学习&#34;的lrnval
行的百分位数,您可以修改该函数以仅计算百分位数该条件为真的行:
def scale_val2(s, val):
percentiles = s[df.lrnval.eq('learning')].quantile([0.01,0.99]).values
if val <= percentiles[0]:
return percentiles[0]
elif val >= percentiles[1]:
return percentiles[1]
else:
return val
由于有一个包含字符串的列,我假设您不会对其进行任何计算。所以,我会按如下方式更改代码:
df.filter(regex='[^lrnval]').apply(lambda s: s.apply(lambda v: scale_val2(s,v)))
我希望这证明有用。
答案 1 :(得分:1)
根据Abdou的回答,以下内容可能会为您节省一些时间:
for col in df.columns:
percentiles = df[col].quantile([0.01,0.99]).values
df[col][df[col] <= percentiles[0]] = percentiles[0]
df[col][df[col] >= percentiles[1]] = percentiles[1]