Python 在相同的数据帧上,df.equals()是否返回False?

Python 在相同的数据帧上,df.equals()是否返回False?,python,pandas,dataframe,equals,dtype,Python,Pandas,Dataframe,Equals,Dtype,让df_1和df_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 我们将一行r添加到df_1: In [3]: r = pd.

df_1
df_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
我们将一行
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
现在,我们从
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
虽然
df_1
df_2
是相同的,
equals()
返回
False

In [8]: df_1.equals(df_2)
Out[8]: False
对此进行了研究,但未能找到相关问题。 我做错什么了吗?在这种情况下,如何获得正确的结果?
(df_1==df_2).all().all()
返回
True
,但不适用于
df_1
df_2
长度不同的情况。

这也是一个微妙的问题,很好地识别了它

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)
现在我们可以看到断言失败时的问题

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

Attribute "dtype" are different
[left]:  object
[right]: int64

当您向整数添加字符串时,整数变成了对象。这就是为什么equals也失败的原因。

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

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)
现在我们可以看到断言失败时的问题

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

Attribute "dtype" are different
[left]:  object
[right]: int64
当您向整数添加字符串时,整数变成了对象。这就是equals也失败的原因。

根据文档:

此函数允许对两个系列或数据帧进行相互比较,以查看它们是否具有相同的形状和元素。同一位置的NAN被认为是相等的。列标题不需要具有相同的类型,但列中的元素必须具有相同的数据类型

因此,
df.equals
仅当元素具有相同的值且
d类型也相同时才会返回
True

df_1
添加和删除行时,
dtypes
int
更改为
object
,因此返回
False

In [8]: df_1.equals(df_2)
Out[8]: False
请举例说明:

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

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

 In [1031]: df_1.dtypes
Out[1031]: 
a    int64
b    int64
dtype: object

In [1032]: df_2.dtypes
Out[1032]: 
a    int64
b    int64
dtype: object
因此,如果您在上面看到,两个dfs的
dtypes
是相同的,因此下面的条件返回
True

In [1030]: df_1.equals(df_2)
Out[1030]: True
现在,在添加和删除行之后:

In [1033]: r = pd.DataFrame({'a': ['x'], 'b': ['y']})

In [1034]: df_1 = df_1.append(r, ignore_index=True)

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

In [1038]: df_1.dtypes
Out[1038]: 
a    object
b    object
dtype: object
dtype
已更改为
object
,因此下面的条件返回
False

In [1039]: df_1.equals(df_2)
Out[1039]: False
如果仍希望返回
True
,则需要将
dtypes
更改回
int
: 根据文件:

此函数允许对两个系列或数据帧进行相互比较,以查看它们是否具有相同的形状和元素。同一位置的NAN被认为是相等的。列标题不需要具有相同的类型,但列中的元素必须具有相同的数据类型

因此,
df.equals
仅当元素具有相同的值且
d类型也相同时才会返回
True

df_1
添加和删除行时,
dtypes
int
更改为
object
,因此返回
False

In [8]: df_1.equals(df_2)
Out[8]: False
请举例说明:

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

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

 In [1031]: df_1.dtypes
Out[1031]: 
a    int64
b    int64
dtype: object

In [1032]: df_2.dtypes
Out[1032]: 
a    int64
b    int64
dtype: object
因此,如果您在上面看到,两个dfs的
dtypes
是相同的,因此下面的条件返回
True

In [1030]: df_1.equals(df_2)
Out[1030]: True
现在,在添加和删除行之后:

In [1033]: r = pd.DataFrame({'a': ['x'], 'b': ['y']})

In [1034]: df_1 = df_1.append(r, ignore_index=True)

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

In [1038]: df_1.dtypes
Out[1038]: 
a    object
b    object
dtype: object
dtype
已更改为
object
,因此下面的条件返回
False

In [1039]: df_1.equals(df_2)
Out[1039]: False
如果仍希望返回
True
,则需要将
dtypes
更改回
int
: 使用,它还将检查数据类型是否相同

(在这种情况下,当您追加然后删除一个字符串行时,您的数据类型将从int更改为“object”(字符串)

使用,它还将检查数据类型是否相同

(在这种情况下,当您追加然后删除一个字符串行时,您的数据类型将从int更改为“object”(字符串)


根据其他人的意见,在这种情况下,可以:

from pandas.util.testing import assert_frame_equal

identical_df = True
try:
    assert_frame_equal(df_1, df_2, check_dtype=False)
except AssertionError:
    identical_df = False

根据其他人的意见,在这种情况下,可以:

from pandas.util.testing import assert_frame_equal

identical_df = True
try:
    assert_frame_equal(df_1, df_2, check_dtype=False)
except AssertionError:
    identical_df = False

谢谢背后的原因是什么?它怎么能被忽视
(df_1==df_2).all().all()
返回
True
,但不适用于
df_1
df_2
长度不同的情况。将它们转换为相同的类型,然后查看它们是否相等。通常,我尝试只保存一次数据,但是如果您正在获取另一组数据,检查它们是否是相同的数据类型是一件好事,并且使它们相同会更好。
df_1['a']=df_1['a'].astype(int)
df_1['b']=df_1['b'].astype(int)
print(df_1.equals(df_2))
会给出您想要的答案。谢谢!背后的原因是什么?它怎么能被忽视
(df_1==df_2).all().all()
返回
True
,但不适用于
df_1
df_2
长度不同的情况。将它们转换为相同的类型,然后查看它们是否相等。通常,我只会尝试保存一次数据,但是如果您正在获取另一组数据,检查它们是否是相同的数据类型是一件好事,并且使它们相同会更好。
df_1['a']=df_1['a'].astype(int)
df_1['b']=df_1['b'].astype(int)
print(df_1.equals(df_2))
会给出您想要的答案。