Коротко
s.where(условие, другое)оставляет значения, где условиеTrue, остальные заменяет (по умолчанию наNaN).s.mask(условие, другое)— наоборот: заменяет, где условиеTrue.- Замена может быть числом, Series или таблицей той же формы — значения берутся по меткам.
clip(lower, upper)ограничивает значения диапазоном; границы могут быть Series — свои для каждой строки.- Не путайте с
np.where(условие, a, b): там выбирается одно из двух значений, а уwhereв pandas «другое» используется только там, где условие ложно.
Синтаксис
s.where(cond, other=nan) # оставить, где cond
s.mask(cond, other=nan) # заменить, где cond
s.clip(lower=None, upper=None)
np.where(cond, a, b) # NumPy: массив из a или bПараметры
ПараметрЧто делаетПо умолчанию
condусловие: булев Series / DataFrame или функция от объектаобязательныйotherна что заменить: значение, Series, DataFrame или функцияNaNlower, upperв clip: границы — числа или SeriesNoneinplaceизменить на месте; в pandas 3 возвращает сам объектFalseПримеры
temps = pd.Series([12.5, -45.0, 18.0, 99.0, 21.5], name="temp") # два значения — сбой датчикаtemps.where(temps.between(-40, 50)) # оставить, где условие True; иначе NaNВывод
0 12.5 1 NaN 2 18.0 3 NaN 4 21.5 Name: temp, dtype: float64
temps.mask(temps > 50, 50) # заменить, где условие TrueВывод
0 12.5 1 -45.0 2 18.0 3 50.0 4 21.5 Name: temp, dtype: float64
forecast = pd.Series([13.0, 11.0, 17.5, 20.0, 22.0])
temps.where(temps.between(-40, 50), forecast) # замена значениями другого SeriesВывод
0 12.5 1 11.0 2 18.0 3 20.0 4 21.5 Name: temp, dtype: float64
scores = pd.DataFrame({"math": [5, 2, 4], "phys": [3, 5, 1]})
scores.where(scores >= 3, 0) # по всей таблицеВывод
math phys 0 5 3 1 0 5 2 4 0
temps.clip(lower=-40, upper=50) # ограничить диапазономВывод
0 12.5 1 -40.0 2 18.0 3 50.0 4 21.5 Name: temp, dtype: float64
prices = pd.DataFrame({"low": [10, 20], "price": [5, 30], "high": [15, 25]})
prices["price"].clip(lower=prices["low"], upper=prices["high"]) # границы свои для каждой строкиВывод
0 10 1 25 Name: price, dtype: int64
Подводные камни
where оставляет, а не заменяет
Логика обратная привычной: where(temps > 50, 50) заменит на 50 всё, что не больше 50. Для «заменить, если больше» — mask.
np.where возвращает массив
Результат np.where — массив NumPy без индекса. Чтобы получить Series, оберните: pd.Series(np.where(...), index=s.index).
np.where(temps > 20, "тепло", "прохладно") # NumPy: условие → одно из двух значенийВывод
array(['прохладно', 'прохладно', 'прохладно', 'тепло', 'тепло'],
dtype='<U9')