将值从一个数据帧切片复制到另一个:使用 `IndexSlice` 的多索引 pandas 数据帧的切片是否总是一致排序?
Copying values from one dataframe slice to another: are slices from multi-indexed pandas dataframes using `IndexSlice` always ordered consistently?
上下文
假设我有一个多索引数据框,如下所示:
import numpy as np
import pandas as pd
arrays = [
["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
["one", "two", "one", "two", "one", "two", "one", "two"],
]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
data = np.array([
[1, 2],
[3, 4],
[5, 6],
[7, 8],
[9, 10],
[11, 12],
[13, 14],
[15, 16],
])
df = pd.DataFrame(data, index=index, columns=('a', 'b'))
看起来像这样:
a b
first second
bar one 1 2
two 3 4
baz one 5 6
two 7 8
foo one 9 10
two 11 12
qux one 13 14
two 15 16
我想将第一个索引级别 bar
的列 a
的值复制到第一个索引级别 qux
的同一列中,对齐在索引的第二层 (此处称为 second
)。换句话说,我想从上面的数据帧中获取以下数据帧:
a b
first second
bar one 1 2
two 3 4
baz one 5 6
two 7 8
foo one 9 10
two 11 12
qux one 1 14 # <-- column a changed to match first = bar for second = one
two 3 16 # <-- column a changed to match first = bar for second = two
根据对 问题的回答,我了解到我可以通过将 pd.IndexSlice
与 .loc
和 .values
结合使用来完成此操作,如下所示:
df.loc[pd.IndexSlice['qux', :], 'a'] = df.loc[pd.IndexSlice['bar', :], 'a'].values
我直觉上不喜欢这样(perhaps/probably 不合理),因为如果这些值 总是 在第二个索引级别上对齐,或者不是:
问题:
我可以保证上面的赋值(使用.values
访问)将总是在第二层对齐多指标?
如果没有,是否有办法实现我想要实现的目标?
不,它不会对齐,因为通过使用 .value
(顺便说一句,不赞成使用 .to_numpy()
),returns 底层 numpy 数组,您删除了所有 index/column 信息,因此无法对齐。
这是保持对齐的一种解决方案:
df.loc['qux', 'a'] = df.loc['qux', 'a'].index.map(df.loc['bar', 'a'].to_dict())
输出:
>>> df
a b
first second
bar two 1.0 2
one 3.0 4
baz one 5.0 6
two 7.0 8
foo one 9.0 10
two 11.0 12
qux one 3.0 14
two 1.0 16
上下文
假设我有一个多索引数据框,如下所示:
import numpy as np
import pandas as pd
arrays = [
["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
["one", "two", "one", "two", "one", "two", "one", "two"],
]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
data = np.array([
[1, 2],
[3, 4],
[5, 6],
[7, 8],
[9, 10],
[11, 12],
[13, 14],
[15, 16],
])
df = pd.DataFrame(data, index=index, columns=('a', 'b'))
看起来像这样:
a b
first second
bar one 1 2
two 3 4
baz one 5 6
two 7 8
foo one 9 10
two 11 12
qux one 13 14
two 15 16
我想将第一个索引级别 bar
的列 a
的值复制到第一个索引级别 qux
的同一列中,对齐在索引的第二层 (此处称为 second
)。换句话说,我想从上面的数据帧中获取以下数据帧:
a b
first second
bar one 1 2
two 3 4
baz one 5 6
two 7 8
foo one 9 10
two 11 12
qux one 1 14 # <-- column a changed to match first = bar for second = one
two 3 16 # <-- column a changed to match first = bar for second = two
根据对 pd.IndexSlice
与 .loc
和 .values
结合使用来完成此操作,如下所示:
df.loc[pd.IndexSlice['qux', :], 'a'] = df.loc[pd.IndexSlice['bar', :], 'a'].values
我直觉上不喜欢这样(perhaps/probably 不合理),因为如果这些值 总是 在第二个索引级别上对齐,或者不是:
问题:
我可以保证上面的赋值(使用.values
访问)将总是在第二层对齐多指标?
如果没有,是否有办法实现我想要实现的目标?
不,它不会对齐,因为通过使用 .value
(顺便说一句,不赞成使用 .to_numpy()
),returns 底层 numpy 数组,您删除了所有 index/column 信息,因此无法对齐。
这是保持对齐的一种解决方案:
df.loc['qux', 'a'] = df.loc['qux', 'a'].index.map(df.loc['bar', 'a'].to_dict())
输出:
>>> df
a b
first second
bar two 1.0 2
one 3.0 4
baz one 5.0 6
two 7.0 8
foo one 9.0 10
two 11.0 12
qux one 3.0 14
two 1.0 16