np.allclose throws抛出TypeError:当dataframe在一行中有字符串时,没有为此类型实现

时间:2015-04-10 12:23:14

标签: python pandas dataframe

我试图将数据框中的值与给定容差内的相等性进行比较。 np.allclose是完美的候选者,但是当我的数据框具有字符串值时,它会抛出TypeError:未针对此类型实现。我无法知道他们的内容是否会串成一排。

示例

old = pd.DataFrame({'a': [1, np.nan, 3],
                    'b': [4,"OK", 6]},
                    index=['x', 'y', 'z'])

new = pd.DataFrame({'a': [1, np.nan, 3],
                    'b': [4, "OK", 6]},
                    index=['x', 'y', 'z'])

1 个答案:

答案 0 :(得分:2)

列' b'在示例中包含混合类型;字符串和整数。 您不能将字符串与allclose进行比较,因为字符串不同或不同。 如果可能,您应该对数据进行组织,以使列成为单一类型。如果有,可以使用np.allclose比较数字列和标准==运算符来比较包含字符串的列。 在示例中,列' a'是数字,所以np.allclose工作:

In [25]: np.allclose(old.a, new.a)
Out[25]: False

但是,它返回False因为等于null值总是返回False,这是比较DataFrame时需要注意的另一个细微之处。在这种情况下你可以做

In [25]: np.allclose(old.fillna(value=0).a, new.fillna(value=0).a)
Out[25]: True

在你给出的小例子中,DataFrame的转置具有单一类型的列,所以也许你应该使用它。但请注意,简单地进行转置不会改变数据类型。

In [18]: old.T.dtypes

Out[18]:
x    object
y    object
z    object

但是使用convert_objects方法将

In [20]: old.T.convert_objects().dtypes
Out[20]:
x    float64
y     object
z    float64
dtype: object

通常,您可以通过调用DataFrame.dtypes来检查每列的dtypes。你可以用

之类的东西挑出字符串(对象)列
obj_cols = df.columns[df.dtypes == object]
num_cols = df.columns[df.dtypes != object]   #this would also include any time columns

然后做

np.allclose(df1[num_cols].fillna(0), df2[num_cols].fillna(0))

(df1[obj_cols].fillna('') == df2[obj_cols].fillna('')).all().all()

编辑: 在更一般的设置中,您可能希望在处理nans时更加小心。您可以执行上述操作,但也要确保空条目完全匹配,因为将nans替换为0可能会产生不必要的相等性(在一个DataFrame中可能有0,而在另一个DataFrame中可能有n)并且您仍然可以获得相等性,对于字符串也是如此)。你可以这样做:

(old.isnull() == new.isnull()).all().all()