仅将布尔掩码应用于数据框列的索引部分

Apply boolean mask only to indexed portion of a dataframe column

我有一个包含一些列的数据框:

>>> np.random.seed(0xFEE7)
>>> df = pd.DataFrame({'A': np.random.randint(10, size=10), 
                       'B': np.random.randint(10, size=10),
                       'C': np.random.choice(['A', 'B'], size=10)})
>>> df
   A  B  C
0  0  0  B
1  4  0  B
2  6  6  A
3  8  3  B
4  0  2  A
5  8  4  A
6  4  1  B
7  8  7  A
8  4  4  A
9  1  1  A

我还有一个布尔系列匹配 df 的索引的一部分:

>>> g = df.groupby('C').get_group('A')
>>> ser = g['B'] > 5
>>> ser
2     True
4    False
5    False
7     True
8    False
9    False
Name: B, dtype: bool

我希望能够使用 serdf 设置或提取数据。例如:

>>> df.loc[ser, 'A'] -= 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\jfoxrabinovitz\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1762, in __getitem__
    return self._getitem_tuple(key)
  File "C:\Users\jfoxrabinovitz\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1289, in _getitem_tuple
    retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
  File "C:\Users\jfoxrabinovitz\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1914, in _getitem_axis
    return self._getbool_axis(key, axis=axis)
  File "C:\Users\jfoxrabinovitz\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1782, in _getbool_axis
    key = check_bool_indexer(labels, key)
  File "C:\Users\jfoxrabinovitz\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py", line 2317, in check_bool_indexer
    raise IndexingError(
pandas.core.indexing.IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match).

错误是有道理的,因为 serdf 的长度不同。如何告诉数据框更新与 ser 的索引匹配并设置为 True 的行?

具体来说,我只想修改索引 2 和 7 处的条目:

>>> df   # after modification
   A  B  C
0  0  0  B
1  4  0  B
2  3  6  A
3  8  3  B
4  0  2  A
5  8  4  A
6  4  1  B
7  5  7  A
8  4  4  A
9  1  1  A

我猜你可以在 loc 中添加索引到 ser,因为两者都来自一个公共索引。

df.loc[ser.index, 'A'] -= 3

正如@Shubham Sharma 评论的那样,OP 只需要过滤 True 值。这种方法获取所有索引 'A'.

@anky 提供了一种方法:

df.loc[ser[ser].index, 'A'] -= 3

由于 ser 的索引与原始数据帧不匹配,因此出现该错误。

您可以通过两种方式解决:

要么将 series.reindexFalse(布尔值)的 fill_value 一起使用,然后使用 loc 以便索引对齐。

df.loc[ser.reindex(df.index,fill_value=False),'A'] = ... #setvalue

或者您可以对 ser 系列进行布尔索引,因此它 returns 只有 True 值并生成可以与 loc:[=20 一起使用的索引=]

df.loc[ser[ser].index,'A'] = ... #setvalue