如何根据Python中的条件用2级列替换数据框中的值?

时间:2017-11-14 15:23:14

标签: python pandas numpy compare

我使用Python 3.6.1。这是我的数据框myDF我想操纵值:

    a     b          c      
    a    X1    X2   X1    X2
 0  10    .     o    o     o
 1  20    .     o    o     o
 2  30    .     o    o     o

正如您所看到的那样,列有' a',''' c'在0级,有列' a',' X1'' X2'在第1级。

我需要比较X1中的值是否等于b / c下X2中的对应值,如果是,则删除这些值。因此,对上述数据框的操作应该返回:

    a     b          c      
    a    X1    X2   X1    X2
 0  10    .     o         
 1  20    .     o         
 2  30    .     o         

这是获取源数据框的方法:

import numpy
import pandas

X1 = pandas.DataFrame(data=[[10,'.','o'],[20,'.','o'],[30,'.','o']],
                      columns=['a','b','c'])
X2 = pandas.DataFrame(data=[[10,'o','o'],[20,'o','o'],[30,'o','o']],
                      columns=['a','b','c'])

myDF = pandas.concat([X1.set_index('a'), X2.set_index('a')],
                     axis='columns', keys=['X1','X2'])
myDF = myDF.swaplevel(axis='columns')[X1.columns[1:]]
myDF = myDF.reset_index(col_level=1, col_fill='a')

到目前为止我尝试的是:

other = myDF.xs('X1', axis=1, level=-1)
main = numpy.where(myDF.eq(other, level=0), 'x', 'y')
pandas.DataFrame(main, index=myDF.index, columns=myDF.columns)

给出了:

   a    b          c      
   a   X1    X2   X1    X2
0  F    T     F    T     T
1  F    T     F    T     T
2  F    T     F    T     T

并且不知道如何前进......

1 个答案:

答案 0 :(得分:2)

我的目标是创建一个包含两列['X1', 'X2']的临时数据框,这样我就可以屏蔽它们相等的行。这让我得到两列:

myDF.set_index(('a', 'a')).stack(0)

         X1 X2
(a, a)        
10     b  .  o
       c  o  o
20     b  .  o
       c  o  o
30     b  .  o
       c  o  o

我可以将其保存为临时名称,然后在其他几行中进行操作。或者我可以按照pipe

执行任务
myDF.set_index(('a', 'a')).stack(0).pipe(
    lambda d: d.mask(d.X1 == d.X2, '')
)

         X1 X2
(a, a)        
10     b  .  o
       c      
20     b  .  o
       c      
30     b  .  o
       c      

其余的只是会计工作,让事情回到原位。

myDF.set_index(('a', 'a')).stack(0).pipe(
    lambda d: d.mask(d.X1 == d.X2, '')
).unstack().swaplevel(0, 1, 1).sort_index(1).reset_index()

    a  b     c   
    a X1 X2 X1 X2
0  10  .  o      
1  20  .  o      
2  30  .  o