Python: масштабирование чисел столбец за столбцом с пандами
У меня есть фрейм данных Pandas 'df', в котором я хотел бы выполнять масштабирование столбец за столбцом.
- В столбце "а" мне нужно, чтобы максимальное число было равно 1, минимальное число было равно 0, а все остальные должны быть соответственно распределены.
- Однако в столбце "b" мне нужно, чтобы минимальное число равнялось 1, максимальное число равнялось 0, а все остальные соответственно распределялись.
Есть ли функция Pandas для выполнения этих двух операций? Если нет, то numpy наверняка подойдет.
a b
A 14 103
B 90 107
C 90 110
D 96 114
E 91 114
Ответы
Ответ 1
Вы можете вычесть на минимум, а затем разделить на максимум (остерегайтесь 0/0). Обратите внимание, что после вычитания минимума, новый максимум будет исходным максимумом - мин.
In [11]: df
Out[11]:
a b
A 14 103
B 90 107
C 90 110
D 96 114
E 91 114
In [12]: df -= df.min() # equivalent to df = df - df.min()
In [13]: df /= df.max() # equivalent to df = df / df.max()
In [14]: df
Out[14]:
a b
A 0.000000 0.000000
B 0.926829 0.363636
C 0.926829 0.636364
D 1.000000 1.000000
E 0.939024 1.000000
Чтобы изменить порядок столбцов (от 1 до 0, а не от 0 до 1):
In [15]: df['b'] = 1 - df['b']
Альтернативный метод - сначала df['b'] = -df['b']
столбцы b (df['b'] = -df['b']
).
Ответ 2
Вот как вы можете это сделать, используя sklearn
и preprocessing
. У Sci-Kit Learn есть много функций предварительной обработки для масштабирования и центрирования данных.
In [0]: from sklearn.preprocessing import MinMaxScaler
In [1]: df = pd.DataFrame({'A':[14,90,90,96,91],
'B':[103,107,110,114,114]}).astype(float)
In [2]: df
Out[2]:
A B
0 14 103
1 90 107
2 90 110
3 96 114
4 91 114
In [3]: scaler = MinMaxScaler()
In [4]: df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)
In [5]: df_scaled
Out[5]:
A B
0 0.000000 0.000000
1 0.926829 0.363636
2 0.926829 0.636364
3 1.000000 1.000000
4 0.939024 1.000000
Ответ 3
Это не очень элегантно, но для этого случая с двумя столбцами работает следующее:
#Create dataframe
df = pd.DataFrame({'A':[14,90,90,96,91], 'B':[103,107,110,114,114]})
#Apply operates on each row or column with the lambda function
#axis = 0 -> act on columns, axis = 1 act on rows
#x is a variable for the whole row or column
#This line will scale minimum = 0 and maximum = 1 for each column
df2 = df.apply(lambda x:(x.astype(float) - min(x))/(max(x)-min(x)), axis = 0)
#Want to now invert the order on column 'B'
#Use apply function again, reverse numbers in column, select column 'B' only and
#reassign to column 'B' of original dataframe
df2['B'] = df2.apply(lambda x: 1-x, axis = 1)['B']
Если я нахожу более элегантный способ (например, используя индекс столбца: (0 или 1) mod 2 - 1, чтобы выбрать знак в операции приложения, чтобы его можно было выполнить только с одной командой приложения, я буду дайте знать.
Ответ 4
Если вы хотите масштабировать только один столбец в кадре данных, вы можете сделать следующее:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df['Col1_scaled'] = scaler.fit_transform(df['Col1'].values.reshape(-1,1))
Ответ 5
заданный фрейм данных
df = pd.DataFrame({'A':[14,90,90,96,91], 'B':[103,107,110,114,114]})
шкала со средним 0 и вар 1
df.apply(lambda x: (x - np.mean(x)) / np.std(x), axis=0)
шкала с диапазоном от 0 до 1
df.apply(lambda x: x / np.max(x), axis=0)