Нормализовать столбцы кадра данных pandas
У меня есть датафрейм в пандах, где каждый столбец имеет различный диапазон значений. Например:
ДФ:
A B C
1000 10 0.5
765 5 0.35
800 7 0.09
Любая идея, как я могу нормализовать столбцы этого кадра данных, где каждое значение находится между 0 и 1?
Мой желаемый результат:
A B C
1 1 1
0.765 0.5 0.7
0.8 0.7 0.18(which is 0.09/0.5)
Ответы
Ответ 1
Вы можете использовать пакет sklearn и связанные с ним утилиты предварительной обработки для нормализации данных.
import pandas as pd
from sklearn import preprocessing
x = df.values #returns a numpy array
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
df = pd.DataFrame(x_scaled)
Для получения дополнительной информации см. документацию по scikit-learn о предварительной обработке данных: масштабирование функций до диапазона.
Ответ 2
один простой способ с помощью Pandas: (здесь я хочу использовать среднюю нормировку)
normalized_df=(df-df.mean())/df.std()
использовать min-max нормализацию:
normalized_df=(df-df.min())/(df.max()-df.min())
Ответ 3
Основываясь на этом сообщении: https://stats.stackexchange.com/questions/70801/how-to-normalize-data-to-0-1-range
Вы можете сделать следующее:
def normalize(df):
result = df.copy()
for feature_name in df.columns:
max_value = df[feature_name].max()
min_value = df[feature_name].min()
result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
return result
Вам не нужно беспокоиться о том, являются ли ваши значения отрицательными или положительными. И значения должны быть хорошо распределены между 0 и 1.
Ответ 4
Если вам нравится использовать пакет sklearn, вы можете сохранить имена столбцов и индексов с помощью pandas loc
следующим образом:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaled_values = scaler.fit_transform(df)
df.loc[:,:] = scaled_values
Ответ 5
Ваша проблема - фактически простое преобразование, действующее на столбцы:
def f(s):
return s/s.max()
frame.apply(f, axis=0)
Или еще более кратким:
frame.apply(lambda x: x/x.max(), axis=0)
Ответ 6
Простое это красиво:
df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()
Ответ 7
Вы можете создать список столбцов, которые вы хотите нормализовать
column_names_to_normalize = ['A', 'E', 'G', 'sadasdsd', 'lol']
x = df[column_names_to_normalize].values
x_scaled = min_max_scaler.fit_transform(x)
df_temp = pd.DataFrame(x_scaled, columns=column_names_to_normalize, index = df.index)
df[column_names_to_normalize] = df_temp
Ваш Pandas Dataframe теперь нормализуется только в тех столбцах, которые вы хотите
Однако, если вы хотите обратное, выберите список столбцов, которые вы не хотите нормализовать, вы можете просто создать список всех столбцов и удалить ненужные.
column_names_to_not_normalize = ['B', 'J', 'K']
column_names_to_normalize = [x for x in list(df) if x not in column_names_to_not_normalize ]
Ответ 8
Я думаю, что лучший способ сделать это в pandas - это просто
df = df/df.max().astype(np.float64)
Изменить Если в вашем фрейме данных присутствуют отрицательные числа, вы должны использовать вместо этого
df = df/df.loc[df.abs().idxmax()].astype(np.float64)
Ответ 9
Решение, данное Sandman и Praveen, очень хорошо. Единственная проблема с этим, если у вас есть категориальные переменные в других столбцах вашего фрейма данных, этот метод будет нуждаться в некоторых настройках.
Мое решение для этого типа проблемы следующее:
from sklearn import preprocesing
x = pd.concat([df.Numerical1, df.Numerical2,df.Numerical3])
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
x_new = pd.DataFrame(x_scaled)
df = pd.concat([df.Categoricals,x_new])
Ответ 10
Возможно, вы захотите, чтобы некоторые столбцы были нормализованы, а другие не изменились, как некоторые из задач регрессии, в которых метки данных или категориальные столбцы не изменились. Поэтому я предлагаю вам этот питонический способ (это комбинация ответов @shg и @Cina):
features_to_normalize = ['A', 'B', 'C']
# could be ['A','B']
df[features_to_normalize] = df[features_to_normalize].apply(lambda x:(x-x.min()) / (x.max()-x.min()))
Ответ 11
def normalize(x):
try:
x = x/np.linalg.norm(x,ord=1)
return x
except :
raise
data = pd.DataFrame.apply(data,normalize)
Из документа панд структура DataFrame может применить операцию (функцию) к себе.
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
Применяет функцию вдоль входной оси DataFrame. Объекты, передаваемые в функции, являются объектами Series, имеющими индекс либо индекса DataFrames (axis = 0), либо столбцов (axis = 1). Тип возвращаемого значения зависит от того, передана ли агрегатная функция, или от аргумента Reduce, если DataFrame пуст.
Вы можете применить пользовательскую функцию для работы с DataFrame.
Ответ 12
Следующая функция вычисляет Z балл:
def standardization(dataset):
""" Standardization of numeric fields, where all values will have mean of zero
and standard deviation of one. (z-score)
Args:
dataset: A 'Pandas.Dataframe'
"""
dtypes = list(zip(dataset.dtypes.index, map(str, dataset.dtypes)))
# Normalize numeric columns.
for column, dtype in dtypes:
if dtype == 'float32':
dataset[column] -= dataset[column].mean()
dataset[column] /= dataset[column].std()
return dataset
Ответ 13
Обратите внимание, что sklearn использует смещенную оценку для стандартного отклонения. Рассмотрим следующий пример нормализации:
import pandas as pd
df = pd.DataFrame({
'A':[1,2,3],
'B':[100,300,500],
'C':list('abc')
})
print(df)
A B C
0 1 100 a
1 2 300 b
2 3 500 c
При нормализации мы просто вычитаем среднее и делим на стандартное отклонение.
df.iloc[:,0:-1] = df.iloc[:,0:-1].apply(lambda x: (x-x.mean())/ x.std(), axis=0)
print(df)
A B C
0 -1.0 -1.0 a
1 0.0 0.0 b
2 1.0 1.0 c
Если вы сделаете то же самое со sklearn
вы получите РАЗНЫЕ выходные данные!
import pandas as pd
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df = pd.DataFrame({
'A':[1,2,3],
'B':[100,300,500],
'C':list('abc')
})
df.iloc[:,0:-1] = scaler.fit_transform(df.iloc[:,0:-1].to_numpy())
print(df)
A B C
0 -1.224745 -1.224745 a
1 0.000000 0.000000 b
2 1.224745 1.224745 c
Результаты разные. Однако, согласно официальной документации sklearn.preprocessing.scale, использование смещенной оценки НЕПРАВИЛЬНО влияет на производительность алгоритмов машинного обучения, и мы можем безопасно их использовать.
Ответ 14
Это всего лишь простая математика. Ответ должен быть таким простым, как показано ниже.
normed_df = (df - df.min()) / (df.max() - df.min())
Ответ 15
Вы можете сделать это в одну строку
DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)
он принимает среднее значение для каждого столбца, а затем вычитает его (среднее значение) из каждой строки (среднее значение для конкретного столбца вычитает только из его строки) и делит только среднее значение. Наконец, мы получаем нормализованный набор данных.
Ответ 16
Вот как вы делаете это по столбцам, используя понимание списка:
[df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]
Ответ 17
Вы можете просто использовать функцию pandas.DataFrame.transform1 следующим образом:
df.transform(lambda x: x/x.max())