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))
会给出您想要的答案。