Pandas-замена значений в фрейме данных на основе логического фрейма данных



Я использую Pandas v0. 20. 2, и у меня есть фрейм данных, такой как:



df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]), 
index=['spam', 'ham'])
# a b c
# spam 0 3 6
# ham 1 4 7


И у меня есть еще один фрейм данных, который является маской:



mask = pd.DataFrame(dict(a=[True,False], b=[True,True]), 
index=['spam', 'ham'])
# a b
# spam True True
# ham False True


И я хочу установить значения в df равными 999, где это True в mask.



Я думал, что сработает следующее:



df[mask] = 999


Но это не так. я получаю ошибку ниже:



ValueError                                Traceback (most recent call last)
<ipython-input-65-503f937859ab> in <module>()
----> 1 df[mask] = 999

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in __setitem__(self, key, value)
2326 self._setitem_array(key, value)
2327 elif isinstance(key, DataFrame):
-> 2328 self._setitem_frame(key, value)
2329 else:
2330 # set column

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/frame.pyc in _setitem_frame(self, key, value)
2364 self._check_inplace_setting(value)
2365 self._check_setitem_copy()
-> 2366 self._where(-key, value, inplace=True)
2367
2368 def _ensure_valid_index(self, value):

/home/gbra/anaconda3/envs/outer_disk/lib/python2.7/site-packages/pandas/core/generic.pyc in _where(self, cond, other, inplace, axis, level, try_cast, raise_on_error)
5096 for dt in cond.dtypes:
5097 if not is_bool_dtype(dt):
-> 5098 raise ValueError(msg.format(dtype=dt))
5099
5100 cond = cond.astype(bool, copy=False)

ValueError: Boolean array expected for the condition, not float64


Я был бы признателен за любую помощь в этом вопросе.
521   3  

3 ответов:

Вы можете переиндексировать маску, чтобы она имела ту же форму, что и df, а затем использовать df.mask:

df.mask(mask.reindex(df.index, df.columns, fill_value=False), 999)
Out: 
        a    b  c
spam  999  999  6
ham     1  999  7

На этом этапе также должна работать регулярная индексация:

df[mask.reindex(df.index, df.columns, fill_value=False)] = 999

Это сделает работу:

df = pd.DataFrame(dict(a=[0,1], b=[3,4], c=[6,7]), 
              index=['spam', 'ham'])
mask = pd.DataFrame(dict(a=[True,False], b=[True,True]), 
                index=['spam', 'ham'])
df.iloc[mask] = 999

Тогда df есть

        a   b     c
spam    999 999   6
ham     1   999   7

Другое решение, без обновления mask

df[mask.columns] = df[mask.columns].mask(mask, 999)

Comments

    Ничего не найдено.