规范化pandas数据帧的列

时间:2014-10-16 22:24:42

标签: python pandas normalize

我在pandas中有一个数据框,其中每列具有不同的值范围。例如:

DF:

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)

21 个答案:

答案 0 :(得分:230)

使用 Pandas 的一种简单方法:(这里我想使用均值标准化)

normalized_df=(df-df.mean())/df.std()

使用min-max规范化:

normalized_df=(df-df.min())/(df.max()-df.min())

答案 1 :(得分:123)

您可以使用sklearn包及其关联的预处理实用程序来规范化数据。

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 = pandas.DataFrame(x_scaled)

有关更多信息,请查看关于预处理数据的scikit-learn documentation:将功能扩展到范围。

答案 2 :(得分:37)

根据这篇文章: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之间。

答案 3 :(得分:23)

如果您喜欢使用sklearn软件包,可以使用pandas loc来保留列名和索引名称,如下所示:

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler() 
scaled_values = scaler.fit_transform(df) 
df.loc[:,:] = scaled_values

答案 4 :(得分:18)

您的问题实际上是对列进行简单的转换:

def f(s):
    return s/s.max()

frame.apply(f, axis=0)

甚至更简洁:

   frame.apply(lambda x: x/x.max(), axis=0)

答案 5 :(得分:16)

简单就是美丽:

df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()

答案 6 :(得分:12)

您可以创建要标准化的列的列表

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数据框现在仅在您想要的列上被标准化


但是,如果要相反,请选择要标准化的列列表,只需创建所有列的列表,然后删除不需要的列

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 ]

答案 7 :(得分:8)

我认为在熊猫中更好的方法就是

df = df/df.max().astype(np.float64)

修改如果您的数据框中存在负数,则应使用

df = df/df.loc[df.abs().idxmax()].astype(np.float64)

答案 8 :(得分:6)

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])

答案 9 :(得分:4)

这只是简单的数学。答案应如下所示。

normed_df = (df - df.min()) / (df.max() - df.min())

答案 10 :(得分:3)

df_normalized = df / df.max(axis=0)

答案 11 :(得分:2)

您可能希望对某些列进行规范化,而对其他列保持不变,例如某些回归任务,其中数据标签或分类列不变,因此,我建议您使用这种pythonic方式(这是@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()))

答案 12 :(得分:1)

以下函数计算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 :(得分:1)

您可以通过以下方式简单地使用pandas.DataFrame.transform 1函数:

Sheet1Button1

答案 14 :(得分:1)

这是您使用列表理解来按列进行操作的方式:

[df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]

答案 15 :(得分:1)

请注意,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的官方文档,使用偏倚估计量会影响机器学习算法的性能,因此我们可以放心使用它们。

答案 16 :(得分:1)

def normalize(x):
    try:
        x = x/np.linalg.norm(x,ord=1)
        return x
    except :
        raise
data = pd.DataFrame.apply(data,normalize)

从pandas文档中,DataFrame结构可以将操作(函数)应用于自身。

DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
  

沿DataFrame的输入轴应用功能。   传递给函数的对象是具有索引的系列对象,索引是DataFrame的索引(轴= 0)或列(轴= 1)。返回类型取决于是否传递函数聚合,如果DataFrame为空,则取决于reduce参数。

您可以应用自定义函数来操作DataFrame。

答案 17 :(得分:0)

您可以一行完成

DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)

对每一列取均值,然后从每一行中减去(均值)(特定列的均值仅从其行中减去)并仅除以均值。最后,我们得到的是归一化的数据集。

答案 18 :(得分:0)

Pandas默认情况下按列进行归一化。尝试下面的代码。

X= pd.read_csv('.\\data.csv')
X = (X-X.min())/(X.max()-X.min())

输出值将在0到1的范围内。

答案 19 :(得分:0)

嘿,使用带有 lambda 的 apply 函数可以加快进程:

def normalize(df_col):

  # Condition to exclude 'ID' and 'Class' feature
  if (str(df_col.name) != str('ID') and str(df_col.name)!=str('Class')):
        max_value = df_col.max()
        min_value = df_col.min()

        #It avoids NaN and return 0 instead
        if max_value == min_value:
          return 0

        sub_value = max_value - min_value
        return np.divide(np.subtract(df_col,min_value),sub_value)
  else:
        return df_col

 df_normalize = df.apply(lambda x :normalize(x))

答案 20 :(得分:-2)

如果您的数据存在正偏,则标准化的最佳方法是使用对数转换:

df = np.log10(df)