我有一个带有调查数据的数据框,像这样,每一行都是不同的受访者。
weight race Question_1 Question_2 Question_3
0.9 white 1 5 4
1.1 asian 5 4 3
0.95 white 2 1 5
1.25 black 5 4 3
0.80 other 4 5 2
每个问题的范围是1到5(实际数据中还有几个问题)。对于每个问题,我都在尝试计算回答为5(按种族分组并按权重列加权)的受访者百分比。
我相信以下代码可用于按种族将每个问题的回答百分比设为5。但是我不知道如何通过“重量”列对其进行加权。
df.groupby('race').apply(lambda x: ((x == 5).sum()) / x.count())
我是熊猫新手。有人可以解释一下该怎么做吗?谢谢你的帮助。
编辑:以上数据框的所需输出将类似于以下内容。显然,真实数据具有更多的受访者(行)和更多的问题。
Question_1 Question_2 Question_3
white 0.00 0.49 0.51
black 1.00 0.00 0.00
asian 1.00 0.00 0.00
other 0.00 1.00 0.00
谢谢。
答案 0 :(得分:1)
这里是解决问题1的方法。您可以轻松地将其概括为其他问题。
# Define a dummy indicating a '5 response'
df['Q1'] = np.where(df['Question_1']==5 ,1, 0)
# Create a weighted version of the above dummy
df['Q1_w'] = df['Q1'] * df['weight']
# Compute the sum by race
ds = df.groupby(['race'])[['Q1_w', 'weight']].sum()
# Compute the weighted average
ds['avg'] = ds['Q1_w'] / ds['weight']
基本上,您首先要按种族计算权重和加权5 dummy
的总和,然后除以权重之和。
这将为您提供加权平均值。
答案 1 :(得分:1)
这是通过定义自定义函数并将该函数应用于每列的解决方案。然后,您可以将每一列连接到一个数据框中:
def wavg(x, col):
return (x['weight']*(x[col]==5)).sum()/x['weight'].sum()
grouped = df.groupby('race')
pd.concat([grouped.apply(wavg,col) for col in df.columns if col.startswith('Question')],axis=1)\
.rename(columns = {num:f'Question_{num+1}' for num in range(3)})
输出:
Question_1 Question_2 Question_3
race
asian 1.0 0.000000 0.000000
black 1.0 0.000000 0.000000
other 0.0 1.000000 0.000000
white 0.0 0.486486 0.513514