Pandas df.equals() 在相​​同的数据帧上返回 False?

Mah*_*hdi 6 python equals dataframe pandas dtype

df_1df_2成为:

In [1]: import pandas as pd
   ...: df_1 = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
   ...: df_2 = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})

In [2]: df_1
Out[2]:
   a  b
0  1  4
1  2  5
2  3  6
Run Code Online (Sandbox Code Playgroud)

r我们添加一行df_1

In [3]: r = pd.DataFrame({'a': ['x'], 'b': ['y']})
   ...: df_1 = df_1.append(r, ignore_index=True)

In [4]: df_1
Out[4]:
   a  b
0  1  4
1  2  5
2  3  6
3  x  y
Run Code Online (Sandbox Code Playgroud)

现在,我们删除添加的行并再次df_1获取原始行:df_1

In [5]: df_1 = pd.concat([df_1, r]).drop_duplicates(keep=False)

In [6]: df_1
Out[6]:
   a  b
0  1  4
1  2  5
2  3  6

In [7]: df_2
Out[7]:
   a  b
0  1  4
1  2  5
2  3  6
Run Code Online (Sandbox Code Playgroud)

df_1df_2相同时,equals()返回False

In [8]: df_1.equals(df_2)
Out[8]: False
Run Code Online (Sandbox Code Playgroud)

做过研究,但找不到相关问题。我做错了什么吗?在这种情况下如何得到正确的结果呢? (df_1==df_2).all().all()返回但不适合和具有不同长度True的情况。df_1df_2

Pau*_*nan 10

这又是一个微妙的问题,很好地发现了它。

import pandas as pd
df_1 = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
df_2 = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
r = pd.DataFrame({'a': ['x'], 'b': ['y']})
df_1 = df_1.append(r, ignore_index=True)
df_1 = pd.concat([df_1, r]).drop_duplicates(keep=False)
df_1.equals(df_2)

from pandas.util.testing import assert_frame_equal
assert_frame_equal(df_1,df_2)
Run Code Online (Sandbox Code Playgroud)

现在我们可以看到断言失败的问题。

AssertionError: Attributes of DataFrame.iloc[:, 0] (column name="a") are different

Attribute "dtype" are different
[left]:  object
[right]: int64
Run Code Online (Sandbox Code Playgroud)

当您将字符串添加到整数时,整数就变成了对象。所以这就是 equals 也失败的原因..


smc*_*mci 7

使用pandas.testing.assert_frame_equal(df_1, df_2, check_dtype=True),它还将检查数据类型是否相同。

(在这种情况下,当您附加然后删除字符串行时,它会发现您的数据类型从 int 更改为“object”(字符串);pandas 不会自动将数据类型强制回为扩展性较小的数据类型。)

AssertionError: Attributes of DataFrame.iloc[:, 0] (column name="a") are different

Attribute "dtype" are different
[left]:  object
[right]: int64
Run Code Online (Sandbox Code Playgroud)