【问题标题】:Python pandas: how to remove nan and -inf valuesPython pandas:如何删除 nan 和 -inf 值
【发布时间】:2018-01-26 10:59:01
【问题描述】:

我有以下数据框

           time       X    Y  X_t0     X_tp0  X_t1     X_tp1  X_t2     X_tp2
0         0.002876    0   10     0       NaN   NaN       NaN   NaN       NaN
1         0.002986    0   10     0       NaN     0       NaN   NaN       NaN
2         0.037367    1   10     1  1.000000     0       NaN     0       NaN
3         0.037374    2   10     2  0.500000     1  1.000000     0       NaN
4         0.037389    3   10     3  0.333333     2  0.500000     1  1.000000
5         0.037393    4   10     4  0.250000     3  0.333333     2  0.500000

....
1030308   9.962213  256  268   256  0.000000   256  0.003906   255  0.003922
1030309  10.041799    0  268     0      -inf   256  0.000000   256  0.003906
1030310  10.118960    0  268     0       NaN     0      -inf   256  0.000000

我尝试了以下

df.dropna(inplace=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.40)

X_train = X_train.drop('time', axis=1)
X_train = X_train.drop('X_t1', axis=1)
X_train = X_train.drop('X_t2', axis=1)
X_test = X_test.drop('time', axis=1)
X_test = X_test.drop('X_t1', axis=1)
X_test = X_test.drop('X_t2', axis=1)
X_test.fillna(X_test.mean(), inplace=True)
X_train.fillna(X_train.mean(), inplace=True)
y_train.fillna(y_train.mean(), inplace=True)

但是,每当我尝试拟合回归模型fit(X_train, y_train)时,我仍然会收到此错误ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

我们如何同时删除NaN-inf 值?

【问题讨论】:

  • 您要删除带有NaN-inf 的行还是将它们设置为默认值?
  • 我想删除(或删除)它们
  • -inf 替换为NaN (df.replace(-np.inf, np.nan)) 然后执行dropna()
  • 谢谢,但当我尝试拟合回归模型时,我仍然遇到同样的错误fit(X_train, y_train)

标签: python python-3.x pandas numpy dataframe


【解决方案1】:

使用pd.DataFrame.isin 并检查包含pd.DataFrame.any 的行。最后,使用布尔数组对数据帧进行切片。

df[~df.isin([np.nan, np.inf, -np.inf]).any(1)]

             time    X    Y  X_t0     X_tp0   X_t1     X_tp1   X_t2     X_tp2
4        0.037389    3   10     3  0.333333    2.0  0.500000    1.0  1.000000
5        0.037393    4   10     4  0.250000    3.0  0.333333    2.0  0.500000
1030308  9.962213  256  268   256  0.000000  256.0  0.003906  255.0  0.003922

【讨论】:

  • 谢谢,但当我尝试拟合回归模型时仍然遇到同样的错误fit(X_train, y_train)
  • 你对 dtype float32 有什么大的值吗?
  • 我们如何检查?我有大约 200 万行,似乎很难手动检查
  • df[~df.isin([np.nan, np.inf, -np.inf]).any(1)].astype(np.float64)?
【解决方案2】:

您可以将inf-inf 替换为NaN,然后选择非空行。

df[df.replace([np.inf, -np.inf], np.nan).notnull().all(axis=1)]  # .astype(np.float64) ?

df.replace([np.inf, -np.inf], np.nan).dropna(axis=1)

通过df.info()检查您的列返回的类型以确保它们都符合预期(例如np.float32/64)。

【讨论】:

  • 我仍然收到相同的错误消息。当我做df.info() 这里是输出Data columns (total 9 columns): time 1030291 non-null float64 X 1030291 non-null int64 Y 1030291 non-null int64 X_t0 1030291 non-null int64 X_tp0 1030291 non-null float64 X_t1 1030291 non-null float64 X_tp1 1030291 non-null float64 X_t2 1030291 non-null float64 X_tp2 1030291 non-null float64 dtypes: float64(6), int64(3) memory usage: 78.6 MB
  • 其中一些列是整数。我不确定它是否会有所帮助,但请尝试通过.astype(np.float64) 将所有内容转换为浮点数。如果做不到这一点,请尝试df.describe() 检查看起来不正常的最大值或最小值。
  • 好的,我会亚历山大。当我执行df.replace(-np.inf, np.nan) 时,它会将-inf 值转换为NaN。但是,当我们执行 df.dropna(inplace=True) 时 - 它不会删除所有 NaN 值 - 它会留下一些带有 NaN 值的行,这就是为什么我仍然遇到相同的错误。是否可以强制删除具有NaN 值的所有行?
  • 您需要指定等于1 的轴来删除行,否则它正在删除列:df.dropna(axis=1)。另外,请参阅:stackoverflow.com/questions/17477979/…
【解决方案3】:
df.replace([np.inf, -np.inf], np.nan)

df.dropna(inplace=True)

【讨论】:

  • 我喜欢这个答案,但我认为你需要:df.replace([np.inf, -np.inf], np.nan, inplace=True)
【解决方案4】:

与其删除包含任何空值和无限数的行,不如将其逻辑颠倒过来,而是返回所有单元格都是有限数的行。 numpy isfinite 函数会执行此操作,如果行中的 所有 单元格是有限的,“.all(1)”只会返回 TRUE。

df = df[np.isfinite(df).all(1)]

【讨论】:

    【解决方案5】:

    df.replace 仅替换值上的第一次出现,从而替换错误

    df = list(filter(lambda x: x!= inf, df)) 将删除所有出现的inf,然后可以使用drop 函数

    【讨论】:

      【解决方案6】:

      我更喜欢设置选项,以便将 inf 值计算为 nan;

      s1 = pd.Series([0, 1, 2])
      s2 = pd.Series([2, 1, 0])
      s1/s2
      # Outputs:
      # 0.0
      # 1.0
      # inf
      # dtype: float64
      
      pd.set_option('mode.use_inf_as_na', True)
      s1/s2
      # Outputs:
      # 0.0
      # 1.0
      # NaN
      # dtype: float64
      

      注意你也可以使用上下文;

      with pd.option_context('mode.use_inf_as_na', True):
          print(s1/s2)
      # Outputs:
      # 0.0
      # 1.0
      # NaN
      # dtype: float64
      

      【讨论】:

      • 我在这里尝试了所有提到的解决方案。但是我的数据框中仍然有 nan 和 inf 值。任何人都可以帮忙吗?此外,我在数据框中的值是指数浮点值,我如何将其转换为小的浮点值?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 2020-09-18
      • 2013-03-24
      • 2014-09-28
      • 2015-01-18
      • 2019-03-11
      相关资源
      最近更新 更多