首页 > 解决方案 > 为每个内部 DataFrame 设置 Multi-Index DataFrame 值

问题描述

我有一个(非常)大的带有单个布尔列的多索引数据框。例如:

bool_arr = np.random.randn(30)<0
df = pd.concat(3*[pd.DataFrame(np.random.randn(10, 3), columns=['A','B','C'])],
           keys=np.array(['one', 'two', 'three']))
df['bool'] = bool_arr
df.index.rename(['Ind1', 'Ind2'], inplace=True)

我试图在每个内部数据帧的 2 个第一个和 2 个最后一个索引上将布尔列设置为 False,但前提是第三个(或倒数第三个)不是 True。意思是,我希望第一个和最后 3 个布尔条目相同。

我可以通过迭代每个索引级别,一个一个地提取内部数据帧并重置相关值,然后将新系列插入原始数据帧的副本来做到这一点。但这在时间和内存上都是非常浪费的。
有没有更快的方法来做到这一点?
(我应该补充一点,在我的示例中,所有内部数据帧的长度都相同,但对我来说不一定是这种情况)

标签: pythonpandasdataframe

解决方案


您可以groupby.transform使用 'bool' 列获取第三个值nth,然后intersection使用前两个元素的索引以及每组head(最后 2 个元素)来获取 。tail然后,您可以locunion索引设置为False

# used per group action several times
gr = df.groupby(level=0)

# get the third value per group
s1 = gr['bool'].transform('nth',2)
# intersection of index with False at 3rd position per group 
# and index of first 2 rows per group
index_head = df.index[~s1].intersection(gr.head(2).index)

# get the last third value per group
s2 = gr['bool'].transform('nth', -3) #note -3 and not -2
# same idea but with tail
index_tail = df.index[~s2].intersection(gr.tail(2).index)

# loc the union of all the index to change
df.loc[index_head.union(index_tail), 'bool'] = False

推荐阅读