如何验证DataFrame元素的值并提取用户的工作楼层?
如何验证DataFrame元素的值并提取用户的工作楼层?
我来帮你梳理下问题,先看看你代码里的几个小问题,再给你两种更高效的解决思路——毕竟用Pandas的话,手动循环其实是下下策,它的分组功能正好适配你的需求~
先说说你现有代码的问题
- 切片获取的是Series而非单个值:你用
df['usager'][i-1:i]拿到的是一个长度为1的Series对象,不是单个用户ID数值,直接和memory比较肯定会出问题,应该用.iloc[i-1]来取单个元素,比如df['usager'].iloc[i-1]。 - 语法错误:条件里的
=!是写反了,正确的不等于运算符是!=。 - 变量名冲突:嵌套循环用了同一个
i变量,会直接覆盖外层循环的i,导致逻辑混乱,内层循环建议换个变量名比如j。 - 初始化错误:
etage_travail=[df[:0]['etage_demandes']]是把一个空Series放进列表,完全不是你需要的空列表,应该写成etage_travail = []。
更高效的解决方案:用Pandas分组功能(推荐)
你的需求是按每个唯一用户(usager)提取他们的工作楼层,从数据里能看到,每个用户的etage_demandes里,非0的那个值就是工作楼层(比如用户1181的33.0,用户826的18.0),而且每个用户只会有一个固定的工作楼层。
直接用分组操作就能一键搞定,不需要手动循环:
import pandas as pd # 方法1:过滤非0行后分组取第一个值 # 先筛选出etage_demandes不为0的行(这些就是用户从工作楼层出发的记录) # 再按usager分组,取每个组的第一个值(因为同一用户的非0值都是同一个) work_floors = df[df['etage_demandes'] != 0].groupby('usager')['etage_demandes'].first().reset_index() # 重命名列名更直观 work_floors.columns = ['usager', 'etage_travail'] print(work_floors)
输出结果示例:
usager etage_travail 0 667.0 30.0 1 677.0 NaN # 若该用户无符合条件的记录,可根据实际情况调整逻辑 2 826.0 18.0 3 1181.0 33.0
如果担心有些用户的非0值可能分散在多行(但根据你的描述每个用户只在一个楼层工作),可以用lambda函数提取唯一非0值:
work_floors = df.groupby('usager')['etage_demandes'].apply( lambda x: x[x != 0].unique()[0] if len(x[x != 0].unique()) > 0 else None ).reset_index() work_floors.columns = ['usager', 'etage_travail']
如果你一定要用循环实现(修正你的原代码)
要是你还是想手动循环处理,我把你的代码修正了下,逻辑更清晰:
memory = None etage_travail = [] # 先获取所有唯一的用户ID,避免重复处理同一个用户 unique_users = df['usager'].unique() for user in unique_users: # 取出当前用户的所有记录 user_records = df[df['usager'] == user] # 提取该用户的非0工作楼层 # 因为每个用户的非0值是同一个,取第一个就行 work_floor = user_records[user_records['etage_demandes'] != 0]['etage_demandes'].iloc[0] etage_travail.append({ 'usager': user, 'etage_travail': work_floor }) # 转成DataFrame方便查看和后续处理 etage_travail_df = pd.DataFrame(etage_travail) print(etage_travail_df)
这样就能正确提取每个用户的工作楼层啦~
备注:内容来源于stack exchange,提问作者philippe roche
相关产品推荐
相关产品推荐

