代码之家  ›  专栏  ›  技术社区  ›  lmocsi

如何基于列值比较过滤python中的熊猫数据帧?

  •  1
  • lmocsi  · 技术社区  · 7 年前

    如果您有这样一个熊猫数据帧,那么按以下方式过滤:

    df = pd.DataFrame({'name1': ['apple','pear','applepie','APPLE'],
                    'name2': ['APPLE','PEAR','apple','APPLE']
                })
    df[df['name1'] != df['name2']] # works
    

    但是,当您想比较列的上限值时,如何筛选行呢?

    df[df['name1'].upper() != df['name2'].upper()]  # does not work
    
    3 回复  |  直到 7 年前
        1
  •  4
  •   rafaelc    7 年前

    你需要使用 pandas.Series.str.upper() 作为 df['name1'] 是一系列字符串,因此我们使用 .str 用于矢量化字符串操作的字符串访问器。

    df[df['name1'].str.upper() != df['name2'].str.upper()]
    

    输出:

           name1    name2
    2   applepie    apple
    
        2
  •  1
  •   rafaelc    7 年前

    仅限ASCII,请检查以上内容:)

    就像观察一样,跟随 this very good answer 在@veedrac中,如果要比较多语言中许多行的不区分大小写,可能需要 normalize casefold 价值观优先

    df.col.str.normalize('NFKD').transform(str.casefold)
    

    例子

    df=pd.DataFrame({'t':['a','b','A', 'ê', 'ê', 'Ê', 'ß', 'ss']})
    
    df.t.duplicated()
    0    False
    1    False
    2    False
    3    False
    4    False
    5    False
    6    False
    7    False
    

    df.t.str.lower().duplicated()
    0    False
    1    False
    2     True
    3    False
    4    False
    5     True
    6    False
    7    False
    

    但是

    df.t.str.normalize('NFKD').transform(str.casefold).duplicated(keep=False)
    
    0     True
    1    False
    2     True
    3     True
    4     True
    5     True
    6     True
    7     True
    
        3
  •  1
  •   user3483203    7 年前

    在处理大熊猫的弦时,通常可以更快地使用列表理解。

    pd.DataFrame(
        [[i, j] for i, j in zip(df.name1, df.name2) if i.upper() != j.upper()],
        columns=df.columns
    )
    
          name1  name2
    0  applepie  apple
    

    一些时间:

    In [159]: df = pd.concat([df]*10000)
    
    In [160]: %%timeit
         ...:     pd.DataFrame(
         ...:         [[i, j] for i, j in zip(df.name1, df.name2) if i.upper() != j.upper()]
         ...: ,
         ...:         columns=df.columns
         ...:     )
         ...:
    14.2 ms ± 68.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [161]: %timeit df[df['name1'].str.upper() != df['name2'].str.upper()]
    35.6 ms ± 160 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)