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

熊猫:如何将数据帧中的所有数值列转换为对数

  •  2
  • maurobio  · 技术社区  · 7 年前

    在R中,我可以使用以下方法将对数(或平方根等)转换应用于数据帧的所有数值列:

    logdf <- log10(df)
    

    在python/pandas中是否有类似的东西?我看到有一个“transform”和一个(R-like)“apply”函数,但是在这种情况下无法理解如何使用它们。

    感谢您提供任何提示或建议。

    4 回复  |  直到 7 年前
        1
  •  2
  •   Rex Low    7 年前

    假设你有一个名为 df

    您可以先列出可能的数字类型,然后进行循环

    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    for c in [c for c in df.columns if df[c].dtype in numerics]:
        df[c] = np.log10(df[c])
    

    或者,使用lambda运算符和 np.dtype.kind

    numeric_df = df.apply(lambda x: np.log10(x) if np.issubdtype(x.dtype, np.number) else x)
    
        2
  •  3
  •   Graipher    7 年前

    如果大多数列都是数字,那么 try 如果不起作用,则跳过该列:

    for column in df.columns:
        try:
            df[column] = np.log10(df[column])
        except (ValueError, AttributeError):
            pass
    

    当然,如果你愿意的话,你可以用一个函数来包装它。

        3
  •  2
  •   Mohit Motwani    7 年前

    你可以使用 select_dtypes numpy.log10 :

    import numpy as np
    for c in df.select_dtype(include = [np.number]).columns:
        df[c] = np.log10(df[c])
    

    select类型选择传递给它的数据类型的列 include 参数。 np.number 包括所有数字数据类型。

    numpy.log10 返回以10为底的输入对数,按元素计算

        4
  •  1
  •   astro123    7 年前

    如果你关心速度:

    df = pd.DataFrame({'A': list('abc')*1000000, 'B': [10, 20,200]*1000000,
                      'C': [0.1,0.2,0.3]*1000000})
    df.head()
    
    %timeit df.apply(lambda x: np.log10(x) if np.issubdtype(x.dtype, np.number) else x)
    #1 loop, best of 3: 539 ms per loop
    
    %%timeit
    log10_df = pd.concat([df.select_dtypes(exclude=np.number),
                          df.select_dtypes(include=np.number).apply(np.log10)],
                          axis=1)
    #loop, best of 3: 315 ms per loop
    
    %%timeit
    for c in df.select_dtypes(include = [np.number]).columns:
        df[c] = np.log10(df[c].values)
    #1 loop, best of 3: 113 ms per loop