【问题标题】:Function against pandas column not generating expected output针对 pandas 列的函数未生成预期输出
【发布时间】:2020-02-22 13:36:35
【问题描述】:

我正在尝试对数据框中的单个列进行最小-最大缩放。

我正在关注这个:Writing Min-Max scaler function

我的代码:

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0, 100, size=(100, 4)), columns=list('ABCD'))

print(df, '\n')

y = df['A'].values


def func(x):
    return [round((i - min(x)) / (max(x) - min(x)), 2) for i in x]


df['E'] = func(y)
print(df)

df['E'] 只是 df['A'] / 100。

不确定我遗漏了什么,但我的结果不正确。

【问题讨论】:

    标签: python-3.x pandas numpy


    【解决方案1】:

    IIUC,你想这样做吗?

    import numpy as np
    import pandas as pd
    df = pd.DataFrame(np.random.randint(0, 100, size=(100, 4)), columns=list('ABCD'))
    print(df, '\n')
    
    
    def func(x):
        return [round((i - min(x)) / (max(x) - min(x)), 2) for i in x]
    
    
    df_out = df.apply(func).add_prefix('Norm_')
    print(df_out)
    
    print(df.join(df_out))
    

    输出:

         A   B   C   D
    0   91  59  44   5
    1   85  44  57  17
    2    6  65  37  46
    3   40  50   3  40
    4   73  58  47  53
    ..  ..  ..  ..  ..
    95  94  76  22  66
    96  70  99  40  59
    97  96  84  85  24
    98  43  51  59  60
    99  31   5  55  89
    
    [100 rows x 4 columns] 
    
        Norm_A  Norm_B  Norm_C  Norm_D
    0     0.93    0.60    0.44    0.05
    1     0.87    0.44    0.58    0.17
    2     0.06    0.66    0.37    0.47
    3     0.41    0.51    0.03    0.41
    4     0.74    0.59    0.47    0.54
    ..     ...     ...     ...     ...
    95    0.96    0.77    0.22    0.67
    96    0.71    1.00    0.40    0.60
    97    0.98    0.85    0.86    0.24
    98    0.44    0.52    0.60    0.61
    99    0.32    0.05    0.56    0.91
    
    [100 rows x 4 columns]
         A   B   C   D  Norm_A  Norm_B  Norm_C  Norm_D
    0   91  59  44   5    0.93    0.60    0.44    0.05
    1   85  44  57  17    0.87    0.44    0.58    0.17
    2    6  65  37  46    0.06    0.66    0.37    0.47
    3   40  50   3  40    0.41    0.51    0.03    0.41
    4   73  58  47  53    0.74    0.59    0.47    0.54
    ..  ..  ..  ..  ..     ...     ...     ...     ...
    95  94  76  22  66    0.96    0.77    0.22    0.67
    96  70  99  40  59    0.71    1.00    0.40    0.60
    97  96  84  85  24    0.98    0.85    0.86    0.24
    98  43  51  59  60    0.44    0.52    0.60    0.61
    99  31   5  55  89    0.32    0.05    0.56    0.91
    
    [100 rows x 8 columns]
    

    【讨论】:

    • 由于您生成 0 到 100 之间的随机整数,最大值很可能接近 100,最小值可能接近 0,因此您将值除以 ~100。
    • 哦...所以我的函数可能工作正常,但由于每列的最大值为 100 或 99,因此最终结果是 df['A'] / 100 或 df[' A'] / 99. 我只是在处理它,然后我掀起了玩具数据框,从来没有意识到这些值本身就是我看到我看到的输出的原因。
    【解决方案2】:

    还要考虑将apply() 与函数一起使用通常效率很低。尽可能使用矢量化操作...

    这是一个更有效的表达式,可以根据该列的最小值和最大值对每一列进行归一化:

    min = df.min()  # per column
    max = df.max()  # per column
    df.join(np.round((df - min) / (max - min), 2).add_prefix('Norm_'))
    

    这比在函数上使用apply() 快得多。对于您的示例 DataFrame:

    %timeit df.join(np.round((df - df.min()) / (df.max() - df.min()), 2).add_prefix('Norm_'))
    9.89 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    虽然带有 apply 的版本需要大约 4 倍的时间:

    %timeit df.join(df.apply(func).add_prefix('Norm_'))
    45.8 ms ± 1.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    但是这种差异会随着 DataFrame 的大小而迅速增长。例如,对于大小为 1,000 x 26 的 DataFrame,我得到 使用矢量化指令的版本为 37.2 ms ± 269 µs,而使用 apply 的版本为 19.5 s ± 1.82 s,快了大约 500 倍!

    【讨论】:

      【解决方案3】:

      不知道你在追求什么。由于数字范围,您的最大值和最小值几乎是已知的。

      df.loc[:,'A':'D'].apply(lambda x : x.agg({'min','max'}))
      

      如果您只需要 df['E'] 只是 df['A'] / 100。 为什么不;

      df['E']=df['A']/100
      y=df['E'].values
      y
      

      请不要仅仅为了弄清楚而标记我

      【讨论】:

      • 我得到 df['E'] = df['A'] / 100,但这不是我想要的。不知道为什么我的函数会生成该输出。
      猜你喜欢
      • 2022-07-06
      • 1970-01-01
      • 2017-09-15
      • 1970-01-01
      • 2022-07-18
      • 2021-04-07
      • 1970-01-01
      • 2021-08-27
      • 2021-03-06
      相关资源
      最近更新 更多