概述
最近需要做dataframe之间的比较,看看两个df之间是否相同,百度之后,有一个好的方式,就是将df的值先转化成行向量,然后用向量比较,得到一个ndarray的数组,里面只有True和False,其中False,表示两个向量不同,我们只需要判断里面是否有False就可以知道是否完全相等。
下面是代码:
def compare_values(df1, df2):
df1_r, df1_c = df1.shape
df2_r, df2_c = df2.shape
if ((df1_r != df2_r) or (df1_c != df2_c)) :
raise Exception('Dimension Mismatch!')
df1_t = df1.fillna(value='')
df2_t = df2.fillna(value='')
res = list(df1_t.values.ravel() == df2_t.values.ravel())
return res.count(False) <= 0
这里我们看到,在里面还做了一个处理,那就是处理空值。
这是因为这个在比较的时候,如果有空值,即使两个df的同一个位置都是空值,那得到的结果也是不相同的,所以我们需要在比较之前,先把空值设定为一个特定的值,或者空字符串,这样再做比较就比较真实了。
如果,我们想要知道到底是哪些位置没有匹配对,或者说我们要验证这个比较是不是正确的,那我们只需要一个循环,然后把False项的位置都取出来,然后计算下行和列,就能知道哪里没有匹配:
def compare_values(df1, df2):
df1_r, df1_c = df1.shape
df2_r, df2_c = df2.shape
if ((df1_r != df2_r) or (df1_c != df2_c)) :
raise Exception('Dimension Mismatch!')
df1_t = df1.fillna(value='')
df2_t = df2.fillna(value='')
res = list(df1_t.values.ravel() == df2_t.values.ravel())
for i,v in enumerate(res): # 这里其实需要做循环判断了,只是为了展示哪行哪列不好
if not v:
r = i // df1_c
c = i % df1_c
print('====================')
print(r, c)
print(df1.iloc[r,c])
print(df2.iloc[r,c])
print('====================')
return res.count(False) <= 0
然后弄个例子来验证下:
import numpy as np
df1 = pd.DataFrame(data=[[1, 2, 3], [pd.NaT, np.nan, 6], [7, 8, 9]], index=['0', '1', '2'], columns=['a', 'b', 'c'])
df2 = pd.DataFrame(data=[[1, 2, 3], [pd.NaT, 5, 6], [7, 8, 9]], index=['0', '1', '2'], columns=['a', 'b', 'c'])
print(compare_values(df1, df2))
最后的结果是:
====================
1 1
nan
5
====================
False
也就是第二行第二列匹配不上,而第二行第一列,两边都是空值的情况,他们是匹配的。
另外,如果不想做填充空值,那我们只好用循环去做判断了,判断两边是否是同时为空值:
def compare_values(df1, df2):
df1_r, df1_c = df1.shape
df2_r, df2_c = df2.shape
if ((df1_r != df2_r) or (df1_c != df2_c)) :
raise Exception('Dimension Mismatch!')
identical = True
res = list(df1.values.ravel() == df2.values.ravel())
for i,v in enumerate(res):
if not v:
r = i // df1_c
c = i % df1_c
if ((df1.iloc[r,c] != df2.iloc[r,c]) and (pd.notna(df1.iloc[r,c]) or pd.notna(df2.iloc[r,c]))):
print('====================')
print(r, c)
print(df1.iloc[r,c])
print(df2.iloc[r,c])
print('====================')
identical = False
return identical
用上面的实例跑一下,得到的结果是一样的,所以在我们具体的比较中,看看自己需求是什么,然后再稍加改动即可。
另外,由于在比较时,我们可以需要填充空值,比如把空值填充为空字符串,然后参与接下来的数据分析,需要注意,这里面如果你是替换成了空字符串,那么在做统计时,就会报错,因为不是numeric的,所以在做比较时,一定是用临时的填充空值的df去做,免得影响后面的计算。
所以,需要用到统计的int和float类型的空值,我们一般用0去填充,这样即使有两个df,一个是空值,一个是0,也不会影响最终的结果。
最后
以上就是糊涂未来为你收集整理的Python-Pandas之Dataframe的比较记录的全部内容,希望文章能够帮你解决Python-Pandas之Dataframe的比较记录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复