python - 在另一列上使用 groupBy 为 nan 添加模式值
问题描述
我在年份列中有一些 nan 单元格。我认为最好设置按行业类型分组的年度模式。
df
ID Name Industry Year Employees Expenses Profit
1 E-Zim Health 2019 320 1,130,700 8553827
2 Daltfase Software NaN 78 804,035 13212508
3 Hotlane Government 2012 87 1,044,375 8701897
4 Latho Health NaN 103 4,631,808 10727561
5 Lambam IT Services 2015 210 4,374,841 4193069
6 Quozap Health 2008 21 4,626,275 8179177
7 Tampware Health 2008 13 2,127,984 3259485
对于模式值,我做了:
df_mode_year = df.groupby('Industry')['Year'].apply(lambda x: x.mode().iloc[0])
df_mode_year
Industry
Government 2012
Health 2008
IT Services 2015
Software
然后修改我的df,我试过了
- df['年份'].fillna(df_mode_year)
- df['Year'] = df['Year'].fillna(df_mode_year[df['Industry']=='Health'])
但是这两个都没有影响最终的 df 。
预期输出:
df
ID Name Industry Year Employees Expenses Profit
1 E-Zim Health 2019 320 1,130,700 8553827
2 Daltfase Software NaN 78 804,035 13212508
3 Hotlane Government 2012 87 1,044,375 8701897
4 Latho Health 2008 103 4,631,808 10727561
5 Lambam IT Services 2012 210 4,374,841 4193069
6 Quozap Health 2008 21 4,626,275 8179177
7 Tampware Health 2008 13 2,127,984 3259485
我究竟做错了什么?非常感谢。
解决方案
您可以使用.transform()
而不是.apply()
,它将返回与df相同长度的一系列,每个组的模式
mode = df.groupby('Industry').Year
mode = mode.transform(lambda x: x.mode().squeeze())
df.update(mode, overwrite=False)
.update()
操作总是在原地完成并返回None
编辑
如果所有行业至少有一年,则第一部分中的代码可以正常工作,但是.transform(lambda x: x.mode().squeeze())
当它遇到仅NaN
作为值的组时似乎会引发错误。如果这是数据中的一种可能性,那么最简单的方法是采用您的方法来按行业汇总模式:
mode = df.groupby('Industry').Year.apply(lambda x: x.mode().squeeze())
现在的问题是.squeeze()
返回一个空的 Series 并且.iloc[0]
(如在您的原始代码中)引发异常。
>>> print(mode.apply(type))
Industry
Government <class 'numpy.float64'>
Health <class 'numpy.float64'>
IT Services <class 'numpy.float64'>
Software <class 'pandas.core.series.Series'>
Name: Year, dtype: object
>>> mode = df.groupby('Industry').Year.apply(lambda x: x.mode().iloc[0])
Traceback ...
IndexError: single positional indexer is out-of-bounds
所以现在我们需要修复那个软件价值。由于它是一个可迭代的,它不能被替换,但它可以被迭代:
mode = mode.explode()
现在模式就像我们需要它一样
>>> print(mode)
Industry
Government 2012
Health 2008
IT Services 2015
Software NaN
Name: Year, dtype: object
对于晚上的最后一招:
df = df.merge(mode, on='Industry') # default suffixes: ['_x', '_y']
mode = df.pop('Year_y').rename('Year')
df.rename({'Year_x': 'Year'}, axis=1, inplace=True)
df.update(mode, overwrite=False)
最终输出
ID Name Industry Year Employees Expenses Profit
0 1 E-Zim Health 2019 320 1,130,700 8553827
1 4 Latho Health 2008 103 4,631,808 10727561
2 6 Quozap Health 2008 21 4,626,275 8179177
3 7 Tampware Health 2008 13 2,127,984 3259485
4 2 Daltfase Software NaN 78 804,035 13212508
5 3 Hotlane Government 2012 87 1,044,375 8701897
6 5 Lambam IT Services 2015 210 4,374,841 4193069
请注意软件如何保持不变NaN
并且健康状况仅NaN
更新
推荐阅读
- amazon-web-services - 使用 Amazon Documentdb 设置 Pritunl
- python - python-pptx 中的图片插入失败并出现错误:LayoutPlaceholder 没有属性 insert_picture
- github - 如何将私有 github 存储库部署到 GCE 集群
- reactjs - 尝试将每个 li 元素路由到显示项目详细页面的组件
- ruby - 运行自动化测试时 Selenium Webdriver 连接超时
- c# - 有没有办法防止 VSBuild Jobs 清除 bin 目录?
- php - 如何从 Laravel 嵌套关系中获取数据?
- python-3.x - 是否有可以返回传入日期(2010 年 5 月 14 日)的格式(%d %m %y)的 python 库?
- powershell - Powershell在gpedit脚本中获取用户名
- javascript - 在 Chrome 和 OpenLayers 2 中防止“无法在被动事件侦听器中阻止默认值”错误