基于条件生成last_created_date列的Python函数问题排查
Python函数问题排查:生成
last_created_date列异常 需求说明
数据背景
现有DataFrame包含rounded_geo_lat、rounded_geo_lng、created_date、distance_1_lat_lng至distance_5_lat_lng等列。每组rounded_geo_lat, rounded_geo_lng对应一列distance_N_lat_lng(第N组对应第N个距离列)。处理时需排除当前行自身值,仅遍历同一rake_device下当前行之后的行。
填充规则
- 若遍历后未找到任何小于5的值,
last_created_date设为null,终止循环; - 若存在小于0.1的值,取最后出现的对应
created_date填充,终止循环; - 若不存在小于0.1但存在大于0.1且小于5的值,取第一个出现的对应
created_date填充。
现有问题代码
import pandas as pd def find_and_append_created_dates(df_0): df_0["last_created_dates"] = None # Add the new column with initial values of None # Iterate over unique rake devices for rake_device in df_0['rake_device'].unique(): rake_device_df = df_0[df_0['rake_device'] == rake_device] # Iterate over distance columns for the current rake device for i in range(len(rake_device_df)): distance_column = f"distance_{i+1}_lat_lng" # Iterate over rows below the current row for j in range(i + 1, len(rake_device_df)): distance = rake_device_df[distance_column].iloc[j] # Iterate over distance columns for distance_column in rake_device_df.filter(like='distance_').columns: # Iterate downward from the row after the current row has_value_less_than_5 = False found_date = None for j in range(i + 1, len(rake_device_df)): distance = rake_device_df[distance_column].iloc[j] if pd.isna(distance): continue # Condition 1: No value less than 5 in the entire column if distance < 5: has_value_less_than_5 = True # Mark that a value less than 5 exists # Condition 2: First occurrence of value less than 0.1 if distance < 0.1 and not found_date: found_date = rake_device_df.loc[rake_device_df.index[j], "created_date"] break # Stop iterating if you find a value less than 0.1 # If no value less than 5 was found, assign NULL and break the loop if not has_value_less_than_5: found_date = None break # Assign the found_date (or None if not found) to the last_created_dates column df_0.at[rake_device_df.index[i], "last_created_dates"] = found_date return df_0 # 调用示例(假设df是你的数据) # find_and_append_created_dates(df) # print(df)
问题排查与修正
核心错误点
- 冗余无效循环:代码开头有一段无意义的循环,仅读取距离值但未做处理,还会覆盖后续的
distance_column变量,导致逻辑混乱; - 小于0.1取值逻辑错误:原代码找到第一个小于0.1的值就终止遍历,不符合需求中"取最后出现的小于0.1对应日期"的要求;
- 距离列遍历逻辑冲突:原代码在遍历行的循环中又遍历所有距离列,不符合"每行对应唯一
distance_N_lat_lng列"的需求; - 条件优先级处理错误:未按需求顺序判断"无小于5值→有小于0.1值→有大于0.1且小于5值"的优先级。
修正后的代码
import pandas as pd def find_and_append_created_dates(df_0): df_0["last_created_date"] = pd.NaT # 用pd.NaT表示日期类型空值更规范 # 按rake_device分组处理 for rake_device, group_df in df_0.groupby('rake_device'): group_indices = group_df.index num_rows = len(group_df) # 遍历组内每一行 for i in range(num_rows): current_idx = group_indices[i] # 获取当前行对应的距离列:第i+1组对应distance_{i+1}_lat_lng distance_col = f"distance_{i+1}_lat_lng" # 收集后续行的有效距离与对应日期 valid_entries = [] for j in range(i + 1, num_rows): dist = group_df[distance_col].iloc[j] if pd.isna(dist): continue valid_entries.append( (dist, group_df['created_date'].iloc[j]) ) # 按规则处理 if not valid_entries: df_0.at[current_idx, "last_created_date"] = pd.NaT continue # 筛选所有小于5的条目 less_5_entries = [entry for entry in valid_entries if entry[0] < 5] if not less_5_entries: df_0.at[current_idx, "last_created_date"] = pd.NaT continue # 筛选小于0.1的条目 less_01_entries = [entry for entry in less_5_entries if entry[0] < 0.1] if less_01_entries: # 取最后一个出现的日期 df_0.at[current_idx, "last_created_date"] = less_01_entries[-1][1] else: # 取第一个大于0.1且小于5的日期 df_0.at[current_idx, "last_created_date"] = less_5_entries[0][1] return df_0
修正说明
- 移除冗余循环,明确每行对应唯一的
distance_N_lat_lng列; - 先收集所有有效后续行数据,再按需求优先级筛选:先判断是否存在小于5的值,再从中筛选小于0.1的值,优先取最后一个符合条件的日期;若无则取第一个大于0.1且小于5的日期;
- 使用
pd.NaT处理日期类型空值,符合pandas数据规范; - 用
groupby替代手动筛选rake_device,代码更简洁高效。
内容的提问来源于stack exchange,提问作者vish
相关产品推荐
相关产品推荐

