这个问题看起来非常基本,但我找不到任何答案。
我有一个多索引数据框,看起来像这样
A B
a b c a b c
x y z x y z x y z x y z x y z x y z
1 : : :
2 : :
3 :
4
5
6
7
我想要的是创建另一个显示x-z和y-z的数据帧。 我试图减去切片机,但它给了我NaN(尽管尺寸相同)
test.loc[:,idx[:,:,'x']].sub(test.loc[:,idx[:,:,'z']])
你知道执行这项任务的技巧吗?
答案 0 :(得分:0)
Pandas操作(例如减法)始终根据行和列索引对齐NDFrame。由于df.loc[:,idx[:,:,'x']]
和df.loc[:,idx[:,:,'z']]
具有不同的列索引,因此减法会产生NaN:
x = df.loc[:,idx[:,:,'x']]
z = df.loc[:,idx[:,:,'z']]
x.sub(z)
# A B
# a b c a b c
# x z x z x z x z x z x z
# 0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# 6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
要使Pandas按元素执行操作(忽略索引),请通过使z
成为NumPy数组来删除索引:
x = df.loc[:,idx[:,:,'x']]
z = df.loc[:,idx[:,:,'z']].values
x.sub(z)
A B
a b c a b c
x x x x x x
0 1 -1 -1 -1 -5 -1
1 0 1 0 4 -2 1
2 -5 -9 4 7 -5 -2
3 -5 -2 -6 -6 0 0
4 -3 -4 4 -5 -6 8
5 1 4 -7 7 -4 8
6 4 0 -2 1 3 -6
例如,
import pandas as pd
import numpy as np
np.random.seed(2016)
columns = pd.MultiIndex.from_product([['A', 'B'], ['a', 'b', 'c'], ['x', 'y', 'z']])
df = pd.DataFrame(np.random.randint(10, size=(7, 18)), columns=columns)
idx = pd.IndexSlice
x = df.loc[:,idx[:,:,'x']]
y = df.loc[:,idx[:,:,'y']]
z = df.loc[:,idx[:,:,'z']].values
result = pd.concat([x-z, y-z], axis=1)
result = result.rename(columns={'x':'x-z', 'y':'y-z'})
产量
A B A B
a b c a b c a b c a b c
x-z x-z x-z x-z x-z x-z y-z y-z y-z y-z y-z y-z
0 1 -1 -1 -1 -5 -1 5 4 -2 3 -8 0
1 0 1 0 4 -2 1 1 5 1 4 6 0
2 -5 -9 4 7 -5 -2 -9 -5 4 8 4 4
3 -5 -2 -6 -6 0 0 -5 -7 0 -4 3 -2
4 -3 -4 4 -5 -6 8 -2 -1 2 -8 1 1
5 1 4 -7 7 -4 8 0 2 -8 3 2 5
6 4 0 -2 1 3 -6 2 5 5 6 -2 -2