Функция против столбца pandas не генерирует ожидаемый результат - PullRequest
1 голос
/ 22 февраля 2020

Я пытаюсь мин-макс масштабировать один столбец в кадре данных.

Я слежу за этим: Пишу функцию масштабирования Мин-Макс

Мой код:

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.

Не уверен, что мне не хватает , но мой результат неверен.

Ответы [ 3 ]

1 голос
/ 22 февраля 2020

Также учтите, что использование 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. Например, с DataFrame размером 1000 x 26 я получаю 37,2 мс ± 269 мкс для версии с векторизованными инструкциями, по сравнению с 19,5 с ± 1,82 с для версии, использующей команду apply, примерно в 500 раз быстрее!

1 голос
/ 22 февраля 2020

IIU C, вы пытаетесь сделать что-то подобное?

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 голосов
/ 22 февраля 2020

Не уверен, что вы после. Ваш максимальный и минимальный значения близки к известному из-за диапазона номеров.

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

Пожалуйста, не отмечайте меня, просто пытаясь получить некоторую ясность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...