如何用Pythonic方式为Pandas DataFrame标记非零值恒定行
问题描述
现有如下结构的Pandas DataFrame:
Car 2020-01-01 2020-01-02 2020-01-03 Car1 10 10 10 Car2 0 10 10 Car3 5 15 7
需要新增一个IS_CONSTANT列:若某行的非零值保持恒定,则该列值设为1,否则为0。处理后的目标DataFrame如下:
Car 2020-01-01 2020-01-02 2020-01-03 IS_CONSTANT Car1 10 10 10 1 Car2 0 10 10 1 Car3 5 15 7 0
要求采用Pythonic方式实现,避免循环(循环处理大数据集效率较低)。
实现方案
可以利用Pandas的矢量化操作完成,无需循环,以下是两种实现方式:
方案一:基于apply的简洁实现
import pandas as pd # 构造示例数据 data = { '2020-01-01': [10, 0, 5], '2020-01-02': [10, 10, 15], '2020-01-03': [10, 10, 7] } df = pd.DataFrame(data, index=['Car1', 'Car2', 'Car3']) df.index.name = 'Car' # 核心逻辑:提取每行非零值,判断唯一值数量是否≤1 df['IS_CONSTANT'] = ( df.apply(lambda row: row[row != 0].nunique() <= 1, axis=1) .astype(int) ) print(df)
逻辑说明:
row[row != 0]筛选出每行的非零元素nunique()统计非零值的唯一值数量,若数量≤1(所有非零值相同,或无任何非零值)则返回Trueastype(int)将布尔值转换为1/0
方案二:纯矢量化高效实现(适合大数据集)
如果数据规模极大,apply的行级遍历效率有限,可以改用更底层的矢量化操作:
import pandas as pd # 构造示例数据 data = { '2020-01-01': [10, 0, 5], '2020-01-02': [10, 10, 15], '2020-01-03': [10, 10, 7] } df = pd.DataFrame(data, index=['Car1', 'Car2', 'Car3']) df.index.name = 'Car' # 替换0为NaN,统计每行非NaN值的唯一数量 non_zero_vals = df.where(df.ne(0)) df['IS_CONSTANT'] = (non_zero_vals.nunique(axis=1) <= 1).astype(int) print(df)
逻辑说明:
df.where(df.ne(0))将所有0替换为NaN,保留非零值nunique(axis=1)直接按行统计非NaN值的唯一数量,全程无行级遍历,效率更高
内容的提问来源于stack exchange,提问作者FlyingPickle
相关产品推荐
相关产品推荐

