Python-Pandas之Dataframe的比较记录

25 篇文章 0 订阅
18 篇文章 3 订阅

最近需要做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,也不会影响最终的结果。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏小败在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值