python - 替换列(字符串)中的值时无法覆盖现有数据框值
问题描述
我有一个带有客户 ID 和性别的熊猫数据框。然而,在清理数据集时,我注意到一些 ID 分配了两种性别,在大多数情况下是女性或男性和未知。
df 看起来像这样:
index ID gender
0 23 M
1 23 U
2 55 F
3 55 U
我的目标是找到分配了两种性别的 ID,并将 U 性别替换为非 U 性别。
为此,我在列表上使用了 for 循环,其中包含所有性别不一致的客户 ID。例如,对于 ID = 23,循环内的代码如下所示:
if all((customers.loc[customers['ID'] == 23]['gender'].str.contains('M')) | (customers.loc[customers['ID'] == 23]['gender'].str.contains('U'))):
customers.loc[customers['ID'] == 23]['gender'] = customers.loc[customers['ID'] == 23]['gender'].replace('U', 'M')
我的问题:
- 不确定 for 循环和 if 语句是否最适合执行我的任务
在使用我的方法时,我无法覆盖现有的数据框。我尝试使用 replace(inplace = True),我尝试使用 .loc() 分配新的性别,但也使用链式索引。在所有情况下,我都会收到警告(使用 .loc 或链式索引时):
A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas- docs/stable/indexing.html#indexing-view-versus-copy
(当使用替换(就地=真)
C:\Users\***: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
并且原始数据框完好无损。
我广泛地查看了 StackOverflow,但我仍然无法解决我的问题。
解决方案
对于此任务,循环将是低效的。相反,您可以使用groupby
. 这是一种依赖于排序的解决方案。
请注意,升序排序NaN
出现在M
和下方F
。
res = df.copy()
res['gender'] = res.replace('U', np.nan\
.sort_values('gender')\
.groupby('ID')['gender'].transform('first')\
.fillna('U')\
.sort_values('index')
print(res)
index ID gender
0 0 23 M
1 1 23 M
2 2 55 F
3 3 55 F
在这种特定情况下,正如@pshep123 所提到的,因为U
按字母顺序出现在之后M
,F
您可以采用分组最小值:
res['gender'] = res.groupby('ID')['gender'].transform('min')
推荐阅读
- javascript - 如何通过nodejs发送画布信息以在另一个浏览器中执行?
- apache-spark - 火花提交:403 错误,客户端系统:匿名错误
- c# - 重新抛出后异常丢失
- python - Scrapy 刮苹果网站
- html - 当我没有指定固定宽度时,如何使 div 居中?
- java - 安装后无法执行pyspark
- java - Java 编译错误 "error: class, interface, or enum expected" 在这种情况下有帮助吗?
- import - Robot Framework:有条件地导入资源
- angular - TS2304:找不到名称
- javascript - JavaScript 上下文翻译在电子中不起作用