繁体   English   中英

Pandas - 根据其他列中的值计算具有条件的列的平均值

[英]Pandas - Calculate average of columns with condition based on values in other columns

我努力在我的数据框中创建一个新列,这将是遍历数据框的每一行并根据某些条件计算平均值的结果。 这就是数据框的样子

ID, 1_a, 1_b, 1_c, 2_a, 2_b, 2_c, 3_a, 3_b, 3_c 
0, 0, 145, 0.8, 0, 555, 0.7, 1, 335, 0.7
1, 1, 222, 0.9, 1, 224, 0.4, 1, 555, 0.6
3, 1, 111, 0.3, 0, 222, 0.5, 1, 999, 0.7 

我希望有以下结果:

ID, 1_a, 1_b, 1_c, 2_a, 2_b, 2_c, 3_a, 3_b, 3_c, NEW
0, 0, 145, 0.8, 0, 555, 0.7, 1, 335, 0.7, 0.7
1, 1, 222, 0.8, 1, 224, 0.4, 1, 555, 0.6, 0.6
3, 1, 111, 0.3, 0, 222, 0.5, 1, 999, 0.7, 0.5

逻辑如下。

If 1_a is 1, keep value in 1_c, if not ignore
If 2_a is 1, keep value in 2_c, if not ignore
If 3_a is 1, keep value in 3_c, if not ignore

计算每行保留值的平均值并存储在“新”列中

我尝试了几种方法,但只有在数据框中只有 1 行时才有效。 如果我有超过 1 行,它似乎计算整个数据框的平均值。 此外,我尝试优化函数,因为我有更多 10 个这些 IF 条件。 这就是我尝试过的,但它没有给我结果,我正在寻找:

 def test(x):
    a = x[x['1_a']==1]['1_c'].values
    b = x[x['2_a']==1]['2_c'].values
    c = x[x['3_a']==1]['3_c'].values
    xx =np.concatenate((a,b,c), axis=0)
    z = sum(xx)/len(xx)
    x['New_Prob'] = z
    return x
print(test(df))

结果是这样的:

ID, 1_a, 1_b, 1_c, 2_a, 2_b, 2_c, 3_a, 3_b, 3_c, NEW
0, 0, 145, 0.8, 0, 555, 0.7, 1, 335, 0.7, 0.6
1, 1, 222, 0.8, 1, 224, 0.4, 1, 555, 0.6, 0.6
3, 1, 111, 0.3, 0, 222, 0.5, 1, 999, 0.7, 0.6

您可以通过编写一个for loop来简化这一点,该for loop遍历带有后缀_c_a每一列,并使用np.where有条件地用NaN替换值。

最后,您使用pandas.DataFrame.mean创建NEW

# First we remove the spaces from your column names
df.columns = df.columns.str.strip()

amt_cols_check = 3

for x in range(amt_cols_check):
    df[f'{x+1}_c'] = np.where(df[f'{x+1}_a'] == 1, df[f'{x+1}_c'], np.NaN)

cols_mean = [col for col in df.columns if col.endswith('_c')]
df['NEW'] =  round(df[cols_mean].mean(axis=1), 1)

print(df)
   ID  1_a  1_b  1_c  2_a  2_b  2_c  3_a  3_b  3_c  NEW
0   0    0  145  NaN    0  555  NaN    1  335  0.7  0.7
1   1    1  222  0.9    1  224  0.4    1  555  0.6  0.6
2   3    1  111  0.3    0  222  NaN    1  999  0.7  0.5

请注意,正如 AlexK 在评论中指出的那样。 我在答案中使用了f-strings ,它仅在 Python 3.6 及更高版本中受支持。

如果您的列在 '_a' 和 '_c' 的范围内相似,您可以简单地遍历它们;

r = range(1,4)
for i in r:
    df.loc[df["{}_a".format(i)] != 1, "{}_c".format(i)] = np.NaN

df['NEW'] = df[['{}_c'.format(i) for i in r]].mean(axis=1)

这是一个不需要用任何东西替换数据框中现有值的解决方案,但假设“_a”列中只有 1 和 0。

这个问题本质上变成了“_c”列的加权平均值,由“_a”列加权。

df.columns = df.columns.str.strip()

a_cols = [col for col in df.columns if col.endswith('_a')]
c_cols = [col for col in df.columns if col.endswith('_c')]
#create a list of tuples of column names, i.e., [('1_a', '1_c'), ('2_a', '2_c'), ('3_a', '3_c')]
a_c = list(zip(a_cols,c_cols)) #if using Python 2.x, use zip(a_cols,c_cols)

df['NEW'] = sum([df[x] * df[y] for x,y in a_c]) / sum([df[z] for z in a_cols])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM