【问题标题】:TypeError: float() argument must be a string or a number, not 'function' – Python/SklearnTypeError: float() 参数必须是字符串或数字,而不是“函数”——Python/Sklearn
【发布时间】:2018-02-26 10:19:22
【问题描述】:

我有一个名为 Flights.py 的程序的以下代码 sn-p

...
#Load the Dataset
df = dataset
df.isnull().any()
df = df.fillna(lambda x: x.median())

# Define X and Y
X = df.iloc[:, 2:124].values
y = df.iloc[:, 136].values
X_tolist = X.tolist()

# Splitting the dataset into the Training set and Test set
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

倒数第二行抛出以下错误:

Traceback (most recent call last):

  File "<ipython-input-14-d4add2ccf5ab>", line 3, in <module>
    X_train = sc.fit_transform(X_train)

  File "/Users/<username>/anaconda/lib/python3.6/site-packages/sklearn/base.py", line 494, in fit_transform
    return self.fit(X, **fit_params).transform(X)

  File "/Users/<username>/anaconda/lib/python3.6/site-packages/sklearn/preprocessing/data.py", line 560, in fit
    return self.partial_fit(X, y)

  File "/Users/<username>/anaconda/lib/python3.6/site-packages/sklearn/preprocessing/data.py", line 583, in partial_fit
    estimator=self, dtype=FLOAT_DTYPES)

  File "/Users/<username>/anaconda/lib/python3.6/site-packages/sklearn/utils/validation.py", line 382, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)

TypeError: float() argument must be a string or a number, not 'function'

我的数据框 df 的大小为 (22587, 138)

我正在查看以下问题以获得灵感:

TypeError: float() argument must be a string or a number, not 'method' in Geocoder

我尝试了以下调整:

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train.as_matrix)
X_test = sc.transform(X_test.as_matrix)

导致以下错误:

AttributeError: 'numpy.ndarray' object has no attribute 'as_matrix'

我目前不知道如何扫描数据框并查找/转换有问题的条目。

【问题讨论】:

    标签: python pandas dataframe scikit-learn


    【解决方案1】:

    正如this answer 解释的那样,fillna 并非设计用于回调。如果你传递一个,它将被视为文字填充值,这意味着你的 NaNs 将被替换为 lambdas:

    df
    
          col1  col2  col3  col4
    row1  65.0    24  47.0   NaN
    row2  33.0    48   NaN  89.0
    row3   NaN    34  67.0   NaN
    row4  24.0    12  52.0  17.0
    
    df4.fillna(lambda x: x.median())
    
                                        col1  col2  \
    row1                                  65    24   
    row2                                  33    48   
    row3  <function <lambda> at 0x10bc47730>    34   
    row4                                  24    12   
    
                                        col3                                col4  
    row1                                  47  <function <lambda> at 0x10bc47730>  
    row2  <function <lambda> at 0x10bc47730>                                  89  
    row3                                  67  <function <lambda> at 0x10bc47730>  
    row4                                  52                                  17 
    

    如果您尝试按中位数填充,解决方案是根据列创建中位数数据框,并将其传递给fillna

    df
          col1  col2  col3  col4
    row1  65.0    24  47.0   NaN
    row2  33.0    48   NaN  89.0
    row3   NaN    34  67.0   NaN
    row4  24.0    12  52.0  17.0
    
    df.fillna(df.median())
    df 
          col1  col2  col3  col4
    row1  65.0    24  47.0  53.0
    row2  33.0    48  52.0  89.0
    row3  33.0    34  67.0  53.0
    row4  24.0    12  52.0  17.0
    

    【讨论】:

    • 如果你传递一个系列,熊猫可以对齐它们,所以你实际上不需要转换或广播。 df.fillna(df.median()).
    • @ayhan 我不知道!谢谢。
    • 我使用 df.fillna(df.median()) 现在我得到了与当天早些时候相同的错误,在我输入 lambda ValueError: Input contains NaN, infinity or a value too large for dtype('float64').之前
    • @HMLDude 这可能是您的数据有问题...您应该考虑使用df.clip:pandas.pydata.org/pandas-docs/stable/generated/…
    【解决方案2】:
    df = df.fillna(lambda x: x.median())
    

    这不是使用fillna 的真正有效方式。它在这里需要文字值,或者从列到文字值的映射。它不会应用您提供的功能;相反,NA 单元格的值将简单地设置为函数本身。这是您的估算器试图将其转换为浮点数的函数。

    https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html

    【讨论】:

      【解决方案3】:

      我在使用 df = df.fillna(lambda x: x.median()) 时遇到了同样的问题 这是我在数据框中获取真实值而不是“函数”的解决方案:

      # -*- coding: utf-8 -*-
      import pandas as pd
      import numpy as np
      

      我用 nan 创建了 10 行 3 列的数据框

      df = pd.DataFrame(np.random.randint(100,size=(10,3)))
      df.iloc[3:5,0] = np.nan
      df.iloc[4:6,1] = np.nan
      df.iloc[5:8,2] = np.nan
      

      为以后的方便添加愚蠢的列标签

      df.columns=['Number_of_Holy_Hand_Grenades_of_Antioch', 'Number_of_knight_fleeings', 'Number_of_rabbits_of_Caerbannog']
      
      print df.isnull().any()  # tell if nan per column
      

      对于每个列通过它们的标签,我们用列本身计算的中值填充所有 nan 值。可与mean()等配合使用。

      for i in df.columns:     #df.columns[w:] if you have w column of line description 
          df[i] = df[i].fillna(df[i].median() )
      print df.isnull().any()
      

      现在 df 包含由中值替换的 nan

      print df
      

      你可以这样做

      X = df.ix[:,:].values
      from sklearn.preprocessing import StandardScaler
      scaler = StandardScaler()
      X_std = scaler.fit_transform(X)
      

      这不适用于df = df.fillna(lambda x: x.median()) 我们现在可以将 df 用于 forward 方法,因为所有值都是真值,而不是函数;与在 dataframe.fillna() 中使用 lambda 的方法相反,例如 all proposals using fillna combined to lambda

      【讨论】:

        猜你喜欢
        • 2023-02-18
        • 2020-04-24
        • 1970-01-01
        • 2021-03-30
        • 2022-08-13
        • 2020-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多