根据条件向DF列分配新值

时间:2020-08-31 23:30:42

标签: python pandas

我需要为列('A')中分配为0(零)的所有寄存器分配一个值。这个新值将是共享在另一列('B')上共享相同值的每个寄存器的平均值,即:所有将'A'分配为0的行都将其值替换为'A'在“ B”值相同的人中发现。显然,以下代码无法正常工作,因为当我在其后调用print(df.A)时,我返回了一些行,其中'A'为0:

df = df[df.A == 0].groupby('B')['A'].mean().reset_index()

我尝试了很多行代码,但是有些甚至没有被接受...

我期望的是这样一种情况,即A的所有0值都替换为B列分组的A列的平均值。像这样:

之前:

Output:
     A    B
1    0    7    
2    0    7
3    9    7
4   10    6
5    8    6
6    0    6
7    0    2

之后:

Output:

         A    B
    1    3    7    
    2    3    7
    3    9    7
    4   10    6
    5    8    6
    6    3    6
    7    0    2
 

感谢您的支持。

1 个答案:

答案 0 :(得分:0)

我想我现在已经理解了您的问题,但是我看不到您如何获得第6行A列的“ 3”。我遵循的逻辑是如何匹配第1行和第2行中的3在col A中,我将尝试在下面的代码中进行解释。如果这不是正确的解释,希望仍然可以使您指向正确的方向。

您的初始df

df = pd.DataFrame({
    'A': [0, 0, 9, 10, 8, 0, 0], 
    'B': [7, 7, 7, 6, 6, 6, 2]
    })

    A   B
1   0   7
2   0   7
3   9   7
4   10  6
5   8   6
6   0   6
7   0   2

确定目标

对于col A为0的col B中的每个唯一值,找到col A中B具有该值的行,并取这些col A值的平均值。然后将该平均值覆盖到A中的那些值为0并与B中选择的值对齐的行。因此,例如,前3行在col B中有7,而在col A中有0、0、9。前3个A行的平均值为3,因此该值将在col A的第1行和第2行的0上覆盖。

步骤

从col A也是0的col B获取唯一值

bvals_when_a_zero = df[df['A'] == 0]['B'].unique()
array([7, 6, 2])

对于每个唯一值,请计算col A中相应值的平均值

means = [df[df['B'] == i]['A'].mean() for i in bvals_when_a_zero]
[3.0, 6.0, 0.0]

遍历bval,表示配对,并用bval的相应均值覆盖0。 pandas where方法的逻辑是将满足条件的值(在本例中为df ['A']值)保留在左方括号中第一个参数中,否则选择第二个参数作为保持价值。我们的条件(df['A'] == 0) & (df['B'] == bval)说,获取col A为0且col B为唯一bval之一的行。但是在这里,我们实际上要保留不等于条件的df ['A']值,因此括号中的条件参数用前面的~符号取反。

for bval, mean in zip(bvals_when_a_zero, means):
    df['A'] = df['A'].where( ~((df['A'] == 0) & (df['B'] == bval)), mean )

这给出了最终的df

    A   B
1   3   7
2   3   7
3   9   7
4   10  6
5   8   6
6   6   6
7   0   2