Python 具有多索引列的数据框架中的布尔索引
我有一个带有多索引列的数据帧:Python 具有多索引列的数据框架中的布尔索引,python,pandas,Python,Pandas,我有一个带有多索引列的数据帧: import numpy as np import pandas as pd columns = pd.MultiIndex.from_arrays([['n1', 'n1', 'n2', 'n2'], ['p', 'm', 'p', 'm']]) values = [ [1, 2, 3, 4], [np.nan, 6, 7, 8], [np.nan, 10, np.nan, 12], ] df = pd
import numpy as np
import pandas as pd
columns = pd.MultiIndex.from_arrays([['n1', 'n1', 'n2', 'n2'], ['p', 'm', 'p', 'm']])
values = [
[1, 2, 3, 4],
[np.nan, 6, 7, 8],
[np.nan, 10, np.nan, 12],
]
df = pd.DataFrame(values, columns=columns)
现在,每当p
为NaN
时,我想将m
设置为NaN
。以下是我想要的结果:
n1 n2
p m p m
0 1.0 2.0 3.0 4.0
1 NaN NaN 7.0 8.0
2 NaN NaN NaN NaN
我知道如何找出p
在哪里NaN
,例如使用
mask = df.xs('p', level=1, axis=1).isnull()
但是,我不知道如何使用此掩码将df
中相应的m
值设置为NaN
,您可以使用该掩码获取一个布尔数据数组,指示p
列中的n
值是否在级别1
上,然后将False
替换为NaN
,并通过乘以结果替换m
中的值:
x = df.loc[:, pd.IndexSlice[:,'p']].notna().replace({False:float('nan')}).values
df.loc[:, pd.IndexSlice[:,'m']] *= x
n1 n2
p m p m
0 1.0 2 3.0 4
1 NaN NaN 7.0 8
2 NaN NaN NaN NaN
您可以使用获取一个布尔数据数组,该数组指示1级1
上的p
列中的值是否为NaN
,然后将False
替换为NaN
,还可以通过乘以结果替换m
中的值:
x = df.loc[:, pd.IndexSlice[:,'p']].notna().replace({False:float('nan')}).values
df.loc[:, pd.IndexSlice[:,'m']] *= x
n1 n2
p m p m
0 1.0 2 3.0 4
1 NaN NaN 7.0 8
2 NaN NaN NaN NaN
您可以堆叠和取消堆叠转置的数据帧,以便能够轻松选择和更改值,然后再次堆叠、取消堆叠和转置以将其取回:
df = df.T.stack(dropna=False).unstack(level=1)
df.loc[df['p'].isna(), 'm'] = np.nan
df = df.stack(dropna=False).unstack(1).T
在第一行之后,df
是:
m p
n1 0 2.0 1.0
1 6.0 NaN
2 10.0 NaN
n2 0 4.0 3.0
1 8.0 7.0
2 12.0 NaN
最后:
n1 n2
m p m p
0 2.0 1.0 4.0 3.0
1 NaN NaN 8.0 7.0
2 NaN NaN NaN NaN
您可以堆叠和取消堆叠转置的数据帧,以便能够轻松选择和更改值,然后再次堆叠、取消堆叠和转置以将其取回:
df = df.T.stack(dropna=False).unstack(level=1)
df.loc[df['p'].isna(), 'm'] = np.nan
df = df.stack(dropna=False).unstack(1).T
在第一行之后,df
是:
m p
n1 0 2.0 1.0
1 6.0 NaN
2 10.0 NaN
n2 0 4.0 3.0
1 8.0 7.0
2 12.0 NaN
最后:
n1 n2
m p m p
0 2.0 1.0 4.0 3.0
1 NaN NaN 8.0 7.0
2 NaN NaN NaN NaN
这是可行的,但请注意,堆栈
/取消堆栈
组合对可能不需要的列进行排序。这是可行的,但请注意,堆栈
/取消堆栈
组合对可能不需要的列进行排序。