如何使用 MultiIndex 重新索引?
Posted
技术标签:
【中文标题】如何使用 MultiIndex 重新索引?【英文标题】:How to reindex with MultiIndex? 【发布时间】:2021-01-31 14:36:41 【问题描述】:我有一个这样的 DataFrame:
import pandas as pd
df = pd.DataFrame.from_dict('var1': 0: 0.0,
1: 0.0,
2: 0.0,
3: 0.0,
4: 0.0,
6: 0.0,
7: 0.0,
8: 0.0,
10: 0.0,
'var2': 0: 0.0,
1: 0.0,
2: 0.0,
3: 0.0,
4: 0.0,
6: 0.0,
7: 0.0,
8: 0.0,
10: 0.0,
'var3': 0: 0.0,
1: 0.0,
2: 0.0,
3: 0.0,
4: 0.0,
6: 0.0,
7: 0.0,
8: 0.0,
10: 0.0,
'var4': 0: 0.0,
1: 0.0,
2: 0.0,
3: 0.0,
4: 0.0,
6: 0.0,
7: 0.0,
8: 0.0,
10: 0.0)
我想填补缺失的索引,所以我首先使用了.reindex
:
df.reindex(np.arange(1, 11))
我得到了:
var1 var2 var3 var4
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0
5 NaN NaN NaN NaN
6 0.0 0.0 0.0 0.0
7 0.0 0.0 0.0 0.0
8 0.0 0.0 0.0 0.0
9 NaN NaN NaN NaN
10 0.0 0.0 0.0 0.0
但是,我需要跟踪多个索引,当我尝试构建 MultiIndex 并将其传递给 .reindex
时,它并没有像我预期的那样工作:
df.reindex(pd.MultiIndex.from_product([["A"], np.arange(1, 11)]))
var1 var2 var3 var4
A 1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
6 NaN NaN NaN NaN
7 NaN NaN NaN NaN
8 NaN NaN NaN NaN
9 NaN NaN NaN NaN
10 NaN NaN NaN NaN
我真的不明白这里发生了什么,.reindex
的文档对我来说不是很清楚。有人可以就此提出建议并告诉我为什么不能将 MultiIndex 传递给 .reindex
或者我做错了什么?
@编辑:
@jazrael 在我们从 1 级到 2 级 MultiIndex 时提供了一个很好的解决方案。但是,如果我们想从 2-level MultiIndex 重新索引到 3-level MultiIndex,该怎么办?
例如:
df.index = pd.MultiIndex.from_arrays([np.repeat([1, 2], [4, 5]), df.index])
var1 var2 var3 var4
1 0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
2 4 0.0 0.0 0.0 0.0
6 0.0 0.0 0.0 0.0
7 0.0 0.0 0.0 0.0
8 0.0 0.0 0.0 0.0
10 0.0 0.0 0.0 0.0
我想得到:
var1 var2 var3 var4
A 1 0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
2 4 0.0 0.0 0.0 0.0
5 NaN NaN NaN NaN
6 0.0 0.0 0.0 0.0
7 0.0 0.0 0.0 0.0
8 0.0 0.0 0.0 0.0
9 NaN NaN NaN NaN
10 0.0 0.0 0.0 0.0
【问题讨论】:
这个额外级别的重新索引的最终用途是什么?是因为你要连接几个数据框吗? @Ben.T 是的。我需要跟踪当前处理的子集以便稍后将它们连接起来。 如果您使用pd.concat
进行连接,您可以使用字典或keys
参数来跟踪您放入连接的Frame or Series
对象。
【参考方案1】:
因为想要简单地使用reindex
,而不是MultiIndex
索引是必要的设置level=1
以匹配新MultiIndex
的第二级:
df = df.reindex(pd.MultiIndex.from_product([["A"], np.arange(1, 11)]), level=1)
print (df)
var1 var2 var3 var4
A 1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0
5 NaN NaN NaN NaN
6 0.0 0.0 0.0 0.0
7 0.0 0.0 0.0 0.0
8 0.0 0.0 0.0 0.0
9 NaN NaN NaN NaN
10 0.0 0.0 0.0 0.0
【讨论】:
谢谢!你能详细解释一下吗?我真的不明白这个解决方案是如何工作的。据我了解,我的 MultiIndex 已经和np.arange(1, 11)
的长度一样了
@Xaume - 在数据框中是由数字创建的索引,新传递的 MultiIndex 由第一级的A
创建,第二级的数字。所以需要原始索引和新 MultiIndex 的第二级之间的匹配数字,这意味着需要 reindex 表示通过 level=1
使用第二级进行 reindex。
@Xaume - 也许是为了更好地理解文档中的帮助示例? DataFrame.reindex
?
@Xaume - 如果还有什么不清楚的地方告诉我,我会试着解释更多。
不幸的是,文档没有级别属性的用例,我仍在努力理解它是如何工作的。尤其是现在,当我遇到我的df
有 2 个级别的 MultiIndex 并且我试图用 3 级 MultiIndex 重新索引它时 - level=1
不再起作用(以及类似level=[1,2]
的东西)。请参阅我的 @edit 示例。【参考方案2】:
您可以创建具有额外级别的新索引并执行显式 DataFrame 连接以获得所需的内容。
df.index = pd.MultiIndex.from_arrays([np.repeat([1, 2], [4, 5]), df.index], names=["key1", "key2"])
# If df's index is already created, do df.rename_axis(["key1", "key2"], inplace=True)
new_index = pd.MultiIndex.from_arrays([['A']*11, np.repeat([1, 2], [4, 7]), range(11)],
names=["new_key", *df.index.names])
output = pd.DataFrame([], index=new_index).join(df, on=df.index.names) # Join on overlapped index levels based on names
输出:
var1 var2 var3 var4
new_key key1 key2
A 1 0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
2 4 0.0 0.0 0.0 0.0
5 NaN NaN NaN NaN
6 0.0 0.0 0.0 0.0
7 0.0 0.0 0.0 0.0
8 0.0 0.0 0.0 0.0
9 NaN NaN NaN NaN
10 0.0 0.0 0.0 0.0
【讨论】:
以上是关于如何使用 MultiIndex 重新索引?的主要内容,如果未能解决你的问题,请参考以下文章
pandas - 如何使用 MultiIndex 在 DataFrame 的深层检索最小值索引
如何使用基于整数位置的索引访问 MultiIndex 数据帧中的行