如何在Pandas中从多列筛选非空、非'aaa'、非日期时间值生成新列?
解决方案
要实现跳过空值、aaa和日期时间格式的值,优先取第一个符合条件的列值,你可以通过以下两种方式实现:
方法1:逐行判断(直观易懂)
先定义一个函数判断字符串是否为日期时间格式,再用apply逐行检查每一列:
import pandas as pd import numpy as np # 判断字符串是否可解析为日期时间 def is_datetime_str(s): return not pd.isna(pd.to_datetime(s, errors='coerce')) # 生成Col4的逻辑函数 def get_target_value(row): # 检查col1:非空、非'aaa'、非日期 if pd.notna(row['col1']) and row['col1'] != 'aaa' and not is_datetime_str(row['col1']): return row['col1'] # 检查col2 elif pd.notna(row['col2']) and row['col2'] != 'aaa' and not is_datetime_str(row['col2']): return row['col2'] # 检查col3 elif pd.notna(row['col3']) and row['col3'] != 'aaa' and not is_datetime_str(row['col3']): return row['col3'] # 所有列都不符合时返回默认值 else: return 'No Value' # 应用函数生成Col4 df['col4'] = df.apply(get_target_value, axis=1)
方法2:向量化操作(高效适合大数据量)
通过生成掩码数组,用嵌套的np.where实现向量化判断,避免逐行循环:
import pandas as pd import numpy as np # 生成各列的符合条件掩码:非空、非'aaa'、非日期 mask_col1 = df['col1'].notna() & (df['col1'] != 'aaa') & ~df['col1'].apply(lambda x: not pd.isna(pd.to_datetime(x, errors='coerce'))) mask_col2 = df['col2'].notna() & (df['col2'] != 'aaa') & ~df['col2'].apply(lambda x: not pd.isna(pd.to_datetime(x, errors='coerce'))) mask_col3 = df['col3'].notna() & (df['col3'] != 'aaa') & ~df['col3'].apply(lambda x: not pd.isna(pd.to_datetime(x, errors='coerce'))) # 嵌套np.where实现优先级判断 df['col4'] = np.where( mask_col1, df['col1'], np.where( mask_col2, df['col2'], np.where( mask_col3, df['col3'], 'No Value' ) ) )
验证示例数据
用你提供的示例数据测试,两种方法都会得到预期结果:
| col1 | col2 | col3 | col4 |
|---|---|---|---|
| aaa | 2011-02-01 10:04:03 | abc | abc |
| 2011-02-01 10:04:03 | xyz | abc | xyz |
| ijk | xyz | ijk |
内容的提问来源于stack exchange,提问作者Ambreen
相关产品推荐
相关产品推荐

