我正在尝试实现一些机器学习算法,但在将数据组合在一起时遇到一些困难。
在下面的示例中,我从 UCI 加载示例数据集,删除丢失数据的行(感谢上一个问题的帮助),现在我想尝试标准化数据。
对于许多数据集,我只是使用:
valores = (valores - valores.mean()) / (valores.std())
但是对于这个特定的数据集,上述方法不起作用。问题是平均函数返回
inf
,可能是由于精度问题。请参阅下面的示例:
bcw = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data', header=None)
for col in bcw.columns:
if bcw[col].dtype != 'int64':
print "Removendo possivel '?' na coluna %s..." % col
bcw = bcw[bcw[col] != '?']
valores = bcw.iloc[:,1:10]
#mean return inf
print valores.iloc[:,5].mean()
我的问题是如何处理这个问题。看来我需要改变这个列的类型,但我不知道该怎么做。
对 pandas 不太熟悉,但如果你转换为 numpy 数组,它可以工作,请尝试
np.asarray(valores.iloc[:,5], dtype=np.float).mean()
如果 pandas 系列的元素是字符串,您将得到
inf
和平均结果。在这种特定情况下,您可以简单地将 pandas 系列元素转换为 float
,然后计算平均值。无需使用 numpy。
示例:
valores.iloc[:,5].astype(float).mean()
NaN
的平均值时,
pandas.Series
值应该无关紧要。精度也无关紧要。我能想到的唯一解释是 valores
中的一个值等于无穷大。
在计算平均值时,您可以排除任何无限值:
import numpy as np
is_inf = valores.iloc[:, 5] == np.inf
valores.ix[~is_inf, 5].mean()
我对数据类型为“o”的列也有同样的问题,其最大值为 9999。您是否尝试过使用带有
convert_objects
参数的 convert_numeric=True
方法?这解决了我的问题。
对我来说,原因是溢出:我的原始数据位于
float16
中,调用 .mean()
将返回 inf
。将我的数据转换为 float32
(例如通过 .astype("float32")
)后,.mean
按预期工作。
您获得 inf 值的原因可能有多种来源。
溢出:正如其他人提到的,这可能是由于溢出造成的。如果您不熟悉这个概念,您可以在维基百科上阅读更多相关信息:整数溢出。从本质上讲,计算平均值或标准差等统计数据通常涉及对数据集中的所有值求和,这可能会导致非常大的数字和潜在的溢出。
NaN 或 inf 值:另一个常见问题是 DataFrame 中存在 NaN 或 inf 值。这些值可能会扰乱您的计算。为了解决这个问题,您可以使用一个简单而快速的技巧将所有无穷大值替换为NaN:
def is_only_nan_or_inf(df):
return df.isna().all(axis=0).any() or np.isposinf(df).all(axis=0).any()
这是有效的,因为 NaN 在 pandas 中计算统计数据时自然会被忽略,而 inf 值则不会。
您的数据集也可能包含充满 NaN 的行。在这种情况下,您应该在执行任何计算之前删除这些行:
df.dropna(subset=["col1", "col2"], how="all", inplace=True)