DataFrame设置LoginDate为索引时Series真值模糊报错如何解决
问题原因与解决方案
错误原因
你将LoginDate设为索引后,该列存在重复值(示例中所有行的LoginDate均为2021-03-23),此时用df.loc[index, "Timing"]取数时,返回的不是单个字符串,而是所有匹配该索引的行组成的Series对象。if判断无法直接对Series的布尔值做判定,因此触发了歧义错误。当你使用无重复的整数索引时,loc每次仅返回单个值,所以代码可以正常运行。
另外你现有的转换逻辑存在疏漏:符合规范的24小时制规则中,12am对应0点,12pm仍为12点,直接给所有pm时间加12会导致12pm被错误转为24点。
最优解决方案(推荐)
优先使用Pandas向量化操作代替for循环遍历,既可以规避索引重复带来的报错,执行效率也远高于循环遍历,同时还能修正逻辑问题:
import pandas as pd from io import StringIO # 初始化与设置索引的代码 data = """ LoginDate LoginTime Timing StudentId 2021-03-23 12 am 3574 2021-03-23 12 am 3574 2021-03-23 9 am 2512 2021-03-23 12 pm 2692 2021-03-23 3 pm 3064 """ df = pd.read_csv(StringIO(data.strip()), sep='\s+') df = df.set_index('LoginDate') # 保留LoginDate为索引 # 向量化转换逻辑 mask_pm = df['Timing'] == 'pm' mask_am_12 = (df['Timing'] == 'am') & (df['LoginTime'] == 12) mask_pm_not12 = mask_pm & (df['LoginTime'] != 12) df.loc[mask_pm_not12, 'LoginTime'] += 12 df.loc[mask_am_12, 'LoginTime'] = 0
若必须使用for循环实现
可以用按位置取值的iloc代替按索引取值的loc,规避重复索引的影响:
for row_idx in range(len(df)): timing_col_pos = df.columns.get_loc('Timing') time_col_pos = df.columns.get_loc('LoginTime') timing = df.iloc[row_idx, timing_col_pos] login_time = df.iloc[row_idx, time_col_pos] if timing == 'pm': if login_time != 12: df.iloc[row_idx, time_col_pos] = login_time + 12 else: if login_time == 12: df.iloc[row_idx, time_col_pos] = 0
内容的提问来源于stack exchange,提问作者mukunda
相关产品推荐
相关产品推荐

