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,并针对它运行代码——你会看到的。如果你从未亲自尝试过,你为什么要回答这个问题?你至少读过我的答案吗?第一行:“如果你碰巧没有这个多索引,你可以使用”如果你自己从来没有读过,为什么要评论这个答案?啊,好吧,我想你的答案帮了大忙…:)