You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于条件生成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)

问题排查与修正

核心错误点

  1. 冗余无效循环:代码开头有一段无意义的循环,仅读取距离值但未做处理,还会覆盖后续的distance_column变量,导致逻辑混乱;
  2. 小于0.1取值逻辑错误:原代码找到第一个小于0.1的值就终止遍历,不符合需求中"取最后出现的小于0.1对应日期"的要求;
  3. 距离列遍历逻辑冲突:原代码在遍历行的循环中又遍历所有距离列,不符合"每行对应唯一distance_N_lat_lng列"的需求;
  4. 条件优先级处理错误:未按需求顺序判断"无小于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:44:55