2017-03-02 108 views
1

我有一个熊猫数据框。在这个DataFrame中,我想修改一些行的几列。这些是我尝试的方法。在熊猫中的行子集中修改多个列DataFrame

df[['finalA', 'finalB']] = df[['A', 'B']] 
exceptions = df.loc[df.normal == False] 

其中用得好好的,但现在我想设置的例外情况:

df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']] 

不工作。所以我尝试使用this answer.ix

df.ix[exceptions.index, ['finalA', 'finalB']] = \ 
    df.ix[exceptions.index, ['A_except', 'B_except']] 

哪一个也不行。两种方法在finalAfinalB中给出了NaN的例外行。

,似乎工作在同一时间做它一列的唯一方法:

df.ix[exceptions.index, 'finalA'] = \ 
    df.ix[exceptions.index, 'A_except'] 
df.ix[exceptions.index, 'finalB'] = \ 
    df.ix[exceptions.index, 'B_except'] 

这是怎么回事的熊猫吗?如何避免将值设置为显然通过选择多列来复制的副本?有没有办法避免这种代码重复?

一些更多的思考:它实际上没有将值设置为数据帧的副本,它将值设置为NaN。它实际上将它们覆盖为一个新的值。


样品数据框:

import pandas as pd 
df = pd.DataFrame({'A': [1,2,3,4], 
        'B': [5,6,7,8], 
        'normal': [True, True, False, False], 
        'A_except': [0,0,9,9], 
        'B_except': [0,0,10,10]}) 

结果:

A A_except B B_except normal finalA finalB 
0 1 0   5 0   True 1.0  5.0 
1 2 0   6 0   True 2.0  6.0 
2 3 9   7 10   False NaN  NaN 
3 4 9   8 10   False NaN  NaN 

预期结果:

A A_except B B_except normal finalA finalB 
0 1 0   5 0   True 1  5 
1 2 0   6 0   True 2  6 
2 3 9   7 10   False 9  10 
3 4 9   8 10   False 9  10 

回答

2

您可以对齐重命名列名:

d = {'A_except':'finalA', 'B_except':'finalB'} 
df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']].rename(columns=d) 

print (df) 
    A A_except B B_except normal finalA finalB 
0 1   0 5   0 True  1  5 
1 2   0 6   0 True  2  6 
2 3   9 7  10 False  9  10 
3 4   9 8  10 False  9  10 

另一种解决方案是输出转换为numpy array,但列不对齐:

df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']].values 

print (df) 
    A A_except B B_except normal finalA finalB 
0 1   0 5   0 True  1  5 
1 2   0 6   0 True  2  6 
2 3   9 7  10 False  9  10 
3 4   9 8  10 False  9  10 
1

如果您查看公式的两边,你会发现,列不同。熊猫考虑到列的标签,并且因为它们不匹配,所以不会插入该值。

它适用于单个列,因为这样您将提取一个Series,然后列标签不再适用。

一个快速的解决办法是简单地剥离数据帧,以裸阵列,那么无论是locix方法工作:

df.loc[exceptions.index, ['finalA', 'finalB']] = 
    df.loc[exceptions.index, ['A_except', 'B_except']].values 

但请记住,这样做将消除熊猫尝试匹配列,索引标签,它基本上是一个'硬'插入。因此,这使得您作为用户负责正确对齐。在这种情况下哪个不是问题,但是一般情况下需要注意的事情。