![](/img/trans.png)
[英]How to average certain values of a column based on other columns condition in 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.