python - Pandas:交换一个数据框中的特定列值并计算其加权平均值
问题描述
存在以下数据框:
年 | 弹出0 | 流行音乐1 | 城市0 | 城市1 |
---|---|---|---|---|
2019 | 20 | 40 | 马里布 | 纽约市 |
2018 | 8 | 60 | 悉尼 | 都柏林 |
2018 | 36 | 23 | 纽约市 | 马里布 |
2020 | 17 | 44 | 马里布 | 纽约市 |
2019 | 5 | 55 | 悉尼 | 都柏林 |
我想将每个城市对的人口加权平均值计算为一个新列。例如,w_mean
Malibu / NYC = (23+20+17)/(36+40+44) = 0.5。
以下是所需的输出:
年 | 弹出0 | 流行音乐1 | 城市0 | 城市1 | w_mean |
---|---|---|---|---|---|
2018 | 23 | 36 | 马里布 | 纽约市 | 0.5 |
2019 | 20 | 40 | 马里布 | 纽约市 | 0.5 |
2020 | 17 | 44 | 马里布 | 纽约市 | 0.5 |
2018 | 8 | 60 | 悉尼 | 都柏林 | 0.113 |
2019 | 5 | 55 | 悉尼 | 都柏林 | 0.113 |
我已经按列对数据框进行了排序,但是我在将第三行从 NYC/Malibu 交换到 Malibu/NYC 时遇到了问题。除此之外,我只能计算w_mean
每一行,但不能计算每一组。我试过groupby().mean()
但没有得到任何有用的输出。
当前代码:
import pandas as pd
data = pd.DataFrame({'year': ["2019", "2018", "2018", "2020", "2019"], 'pop0': [20,8,36,17,5], 'pop1': [40,60,23,44,55], 'city0': ['Malibu','Sydney','NYC','Malibu','Sydney'], 'city1': ['NYC','Dublin','Malibu','NYC','Dublin']})
new = data.sort_values(by=['city0', 'city1'])
new['w_mean'] = new.apply(lambda row: row.pop0 / row.pop1, axis=1)
print(new)
解决方案
您可以做的是创建一个创建元组(city, population)
,将两个元组连续放入一个列表中,然后对其进行排序。通过对所有行执行此操作,您可以提取新的城市和人口(按城市字母顺序排序)。这可以按如下方式完成:
cities = [sorted([(e[0], e[1]), (e[2], e[3])]) for e in data[['city0','pop0','city1','pop1']].values]
data[['city0', 'pop0']] = [e[0] for e in cities]
data[['city1', 'pop1']] = [e[1] for e in cities]
结果数据框:
year pop0 pop1 city0 city1
0 2019 20 40 Malibu NYC
1 2018 60 8 Dublin Sydney
2 2018 23 36 Malibu NYC
3 2020 17 44 Malibu NYC
4 2019 55 5 Dublin Sydney
现在,mean_w
可以使用groupby
和transform
创建两个总和然后除以如下方式创建列:
data[['pop0_sum', 'pop1_sum']] = data.groupby(['city0', 'city1'])[['pop0', 'pop1']].transform('sum')
data['w_mean'] = data['pop0_sum'] / data['pop1_sum']
结果:
year pop0 pop1 city0 city1 pop0_sum pop1_sum w_mean
0 2019 20 40 Malibu NYC 60 120 0.500000
1 2018 60 8 Dublin Sydney 115 13 8.846154
2 2018 23 36 Malibu NYC 60 120 0.500000
3 2020 17 44 Malibu NYC 60 120 0.500000
4 2019 55 5 Dublin Sydney 115 13 8.846154
现在可以删除任何额外的列。
如果结果w_mean
列应始终小于零,则可以按如下方式进行最后一次除法:
data['w_mean'] = np.where(data['pop0_sum'] > data['pop1_sum'], data['pop1_sum'] / data['pop0_sum'], data['pop0_sum'] / data['pop1_sum'])
这将为0.5
马里布和纽约市对以及0.113043
都柏林和悉尼提供。
推荐阅读
- c# - 来自按钮的适配器内的 StartActivityForResult 不会触发 OnActivityResult
- elixir - 在 Phoenix 中使用原始文本 SQL 查询是不好的做法吗?
- .net - 显示为空数据网格的数据网格。即使标题不显示
- javascript - 当我在 index.js 上导入类时,“元素类型无效:需要一个字符串”
- openjfx - 如何将 openJFX11 画布保存为 png/位图?
- r - 根据分组数据评估的条件替换缺失值
- c# - C# Process.Start 无法连接到服务器
- java - MouseListener 没有给出准确的鼠标位置
- ios - UIview 顶部限制在安全区域,但在 viewDidLoad 中,视图的 Y 位置错误
- asp.net - 通过 SendGrid 向 Outlook 发送邮件总是失败