说我有以下DataFrame:
arrays = [['foo', 'foo', 'bar', 'bar'],
['A', 'B', 'C', 'D']]
tuples = list(zip(*arrays))
columnValues = pd.MultiIndex.from_tuples(tuples)
df = pd.DataFrame(np.random.rand(4,4), columns = columnValues)
print(df)
foo bar
A B C D
0 0.037362 0.470010 0.315396 0.333798
1 0.339038 0.396307 0.487242 0.064883
2 0.691654 0.793609 0.044490 0.384154
3 0.605801 0.967021 0.156839 0.123816
我想生成以下输出:
foo bar
A B C D
0 0 0 0.315396 0.333798
1 0 0 0.487242 0.064883
2 0 0 0.044490 0.384154
3 0 0 0.156839 0.123816
我认为我可以使用pd.DataFrame.where()
,但我不知道如何将列名称bar
作为条件传递。
编辑:我正在寻找一种专门使用bar
代替foo
来产生所需结果的方法,因为foo
实际上会有很多列
EDIT2:遗憾的是,如果列表包含所有列标签,则列表理解会中断。明确地写出for循环确实有效。 所以不要这样:
df.loc[:, [col for col in df.columns.levels[0] if col != 'bar']] = 0
我用这个:
for col in df.columns.levels[0]:
if not(col in nameList):
df.loc[:,col]=0
答案 0 :(得分:2)
使用slicing设置您的数据。在这里,您可以访问foo
下的子列(A,B)。
In [12]: df
Out[12]:
foo bar
A B C D
0 0.040251 0.119267 0.170111 0.582362
1 0.978192 0.592043 0.515702 0.630627
2 0.762532 0.667234 0.450505 0.103858
3 0.871375 0.397503 0.966837 0.870184
In [13]: df.loc[:, 'foo'] = 0
In [14]: df
Out[14]:
foo bar
A B C D
0 0 0 0.170111 0.582362
1 0 0 0.515702 0.630627
2 0 0 0.450505 0.103858
3 0 0 0.966837 0.870184
如果您想设置除bar
以外的所有列,您可以这样做。
In [15]: df.loc[:, [col for col in df.columns.levels[0] if col != 'bar']] = 0
答案 1 :(得分:1)
我猜你可以使用get_level_values
:
>>> df
foo bar
A B C D
0 0.039728 0.065875 0.825380 0.240403
1 0.617857 0.895751 0.484237 0.506315
2 0.332381 0.047287 0.011291 0.346073
3 0.216224 0.024978 0.834353 0.500970
>>> df.loc[:, df.columns.get_level_values(0) != "bar"] = 0
>>> df
foo bar
A B C D
0 0 0 0.825380 0.240403
1 0 0 0.484237 0.506315
2 0 0 0.011291 0.346073
3 0 0 0.834353 0.500970
df.columns.droplevel(1) != "bar"
也应该有用,虽然我不喜欢它,尽管它更短,因为它反转了选择逻辑。
答案 2 :(得分:0)
更容易,没有loc
df [' foo'] = 0
答案 3 :(得分:0)
如果您没有这个多索引,可以使用:
df.ix[:,['A','B']] = 0
这会自动替换列中的值' A'和' B'由0。