Python 使用列名作为数据帧上的位置的条件

Python 使用列名作为数据帧上的位置的条件,python,pandas,Python,Pandas,假设我有以下数据帧: 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)

假设我有以下数据帧:

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
用于设置您的数据。在这里,您可以访问
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
如果要设置除
之外的所有列,可以这样做

In [15]: df.loc[:,  [col for col in df.columns.levels[0] if col != 'bar']] = 0
用于设置您的数据。在这里,您可以访问
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
如果要设置除
之外的所有列,可以这样做

In [15]: df.loc[:,  [col for col in df.columns.levels[0] if col != 'bar']] = 0
更容易,没有loc

df['foo']=0

更容易,没有loc

df['foo']=0


如果您碰巧没有此多索引,则可以使用:

df.ix[:,['A','B']] = 0

这会自动将列“A”和“B”中的值替换为0。

如果碰巧没有此多索引,则可以使用:

df.ix[:,['A','B']] = 0

这会自动将列“A”和“B”中的值替换为0。

您可以使用
获取级别值,我想:

>>> 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”
也应该可以工作,尽管我不太喜欢它,尽管它更短,因为它会反转选择逻辑。

您可以使用
获取级别值,我想:

>>> 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”
也应该可以,尽管我不太喜欢它,尽管它比较短,因为它颠倒了选择逻辑。

感谢您的快速回复。虽然这会为上面的示例产生所需的结果,但实际上我宁愿使用
bar
作为条件,而不是
foo
,因为
foo
实际上会有很多列。类似
df.loc[:,[col for col in df.columns.levels[0]的情况下,如果col!='bar']=0
,最终使用了这种方法,因为它也允许我传递一个列表,例如
['a','B']
而不是
'bar'
,谢谢您的快速回复。虽然这会为上面的示例产生所需的结果,但实际上我宁愿使用
bar
作为条件,而不是
foo
,因为
foo
实际上会有很多列。类似
df.loc[:,[col for col in df.columns.levels[0]的情况下,如果col!='bar']=0
,最终使用了这种方法,由于它也允许我传递一个列表,例如
['a','B']
而不是
'bar'
,因此建议在pandas对象中设置值时,必须小心避免所谓的“链在哪里?”:)建议在pandas对象中设置值时,必须小心避免所谓的“链在哪里?”:)你能说得更具体些吗?因为我用过很多次这种方法,效果很好。但是千万不要使用多索引,至少我记得不是这样。只要从问题中创建一个DF,并针对它运行代码——你会看到的。如果你从未亲自尝试过,你为什么要回答这个问题?你至少读过我的答案吗?第一行:“如果你碰巧没有这个多索引,你可以使用”如果你自己从来没有读过,为什么要评论这个答案?啊,好吧,我想你的答案帮了大忙…:)你能说得更具体些吗?因为我用过很多次这种方法,效果很好。但是千万不要使用多索引,至少我记得不是这样。只要从问题中创建一个DF,并针对它运行代码——你会看到的。如果你从未亲自尝试过,你为什么要回答这个问题?你至少读过我的答案吗?第一行:“如果你碰巧没有这个多索引,你可以使用”如果你自己从来没有读过,为什么要评论这个答案?啊,好吧,我想你的答案帮了大忙…:)