Pandas 多索引根据其他列中的值从值中减去
Pandas multi-index subtract from value based on value in other column
给定以下数据框:
df = pd.DataFrame({
('A', 'a'): [23, 'n/a',54,7,32,76],
('B', 'b'): [23, 'n/a',54,7,32,76],
('possible','possible'):[100,100,100,100,100,100]
})
df
A B possible
a b
0 23 23 100
1 n/a n/a 100
2 54 54 100
3 7 n/a 100
4 32 32 100
5 76 76 100
我想针对 'n/a' 的每个实例每行调整 'possible',这样每个实例将从 'possible' 中减去 4。
想要的结果如下:
A B possible
a b possible
0 23 23 100
1 n/a n/a 92
2 54 54 100
3 7 n/a 96
4 32 32 100
5 76 76 100
然后完成后,我希望将 'n/a' 的每个实例都转换为 0,以便列类型为整数(但 float 可以)。
提前致谢!
后续问题:
如果我的多索引是这样的怎么办:
df = pd.DataFrame({
('A', 'a'): [23, 'n/a',54,7,32,76],
('A', 'b'): [23, 'n/a',54,7,32,76],
('B', 'b'): [23, 'n/a',54,7,32,76],
('possible','possible'):[100,100,100,100,100,100]
})
我有 5 个上层索引和 25 个下层索引。我想知道是否可以只引用
中的顶部
no4 = (df.loc[:, (top level indices),(bottom level indices)] == 'n/a').sum(axis=1)
我认为您可以通过掩码检查值 boolean indexing
. Last replace
所有值 n/a
到 0
:
使用 n/a
和 sum
检查值:
idx = pd.IndexSlice
no4 = (df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1)
print no4
0 0
1 2
2 0
3 1
4 0
5 0
dtype: int64
检查总和是否相等 0
(这意味着有 n/a
个值):
mask = no4 != 0
print mask
0 False
1 True
2 False
3 True
4 False
5 False
dtype: bool
减去 4
次 no4
:
df.loc[mask, idx['possible', 'possible']] -= no4 * 4
df.replace({'n/a':0}, inplace=True)
print df
A B possible
a b possible
0 23 23 100.0
1 0 0 92.0
2 54 54 100.0
3 7 0 96.0
4 32 32 100.0
5 76 76 100.0
编辑:
我找到了更简单的解决方案 - 掩码不是必需的,因为如果 n/a
:
你减去 0
idx = pd.IndexSlice
print (df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1) * 4
0 0
1 8
2 0
3 4
4 0
5 0
dtype: int64
df.loc[:, idx['possible', 'possible']] -=
(df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1) * 4
df.replace({'n/a':0}, inplace=True)
print df
A B possible
a b possible
0 23 23 100
1 0 0 92
2 54 54 100
3 7 0 96
4 32 32 100
5 76 76 100
EDIT1:如果您只需要 select tom indices - 请参阅 using slicers:
(df.loc[:, idx[(top level indices),:]] == 'n/a').sum(axis=1)
给定以下数据框:
df = pd.DataFrame({
('A', 'a'): [23, 'n/a',54,7,32,76],
('B', 'b'): [23, 'n/a',54,7,32,76],
('possible','possible'):[100,100,100,100,100,100]
})
df
A B possible
a b
0 23 23 100
1 n/a n/a 100
2 54 54 100
3 7 n/a 100
4 32 32 100
5 76 76 100
我想针对 'n/a' 的每个实例每行调整 'possible',这样每个实例将从 'possible' 中减去 4。 想要的结果如下:
A B possible
a b possible
0 23 23 100
1 n/a n/a 92
2 54 54 100
3 7 n/a 96
4 32 32 100
5 76 76 100
然后完成后,我希望将 'n/a' 的每个实例都转换为 0,以便列类型为整数(但 float 可以)。
提前致谢!
后续问题:
如果我的多索引是这样的怎么办:
df = pd.DataFrame({
('A', 'a'): [23, 'n/a',54,7,32,76],
('A', 'b'): [23, 'n/a',54,7,32,76],
('B', 'b'): [23, 'n/a',54,7,32,76],
('possible','possible'):[100,100,100,100,100,100]
})
我有 5 个上层索引和 25 个下层索引。我想知道是否可以只引用
中的顶部no4 = (df.loc[:, (top level indices),(bottom level indices)] == 'n/a').sum(axis=1)
我认为您可以通过掩码检查值 boolean indexing
. Last replace
所有值 n/a
到 0
:
使用 n/a
和 sum
检查值:
idx = pd.IndexSlice
no4 = (df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1)
print no4
0 0
1 2
2 0
3 1
4 0
5 0
dtype: int64
检查总和是否相等 0
(这意味着有 n/a
个值):
mask = no4 != 0
print mask
0 False
1 True
2 False
3 True
4 False
5 False
dtype: bool
减去 4
次 no4
:
df.loc[mask, idx['possible', 'possible']] -= no4 * 4
df.replace({'n/a':0}, inplace=True)
print df
A B possible
a b possible
0 23 23 100.0
1 0 0 92.0
2 54 54 100.0
3 7 0 96.0
4 32 32 100.0
5 76 76 100.0
编辑:
我找到了更简单的解决方案 - 掩码不是必需的,因为如果 n/a
:
0
idx = pd.IndexSlice
print (df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1) * 4
0 0
1 8
2 0
3 4
4 0
5 0
dtype: int64
df.loc[:, idx['possible', 'possible']] -=
(df.loc[:, idx[('A', 'B'), ('a', 'b')]] == 'n/a').sum(axis=1) * 4
df.replace({'n/a':0}, inplace=True)
print df
A B possible
a b possible
0 23 23 100
1 0 0 92
2 54 54 100
3 7 0 96
4 32 32 100
5 76 76 100
EDIT1:如果您只需要 select tom indices - 请参阅 using slicers:
(df.loc[:, idx[(top level indices),:]] == 'n/a').sum(axis=1)