Compare two Series containing a list of objects

Viewed 50

I have two parking pandas.Series that are the same size. I also have a class Car (see implementation below). In each row of my parking serie, I have a list of Car object.

for each car in parking1 n-th row, we need to check if the car is present in parking2 n-th row as well.

import pandas as pd

class Car:
    def __init__(self, brand, color, mileage):
        self.brand = brand
        self.color = color
        self.mileage = mileage

car1 = Car('toyota', 'black', 1000)
car2 = Car('mercedes', 'white', 3222)
car3 = Car('honda', 'yellow', 2500)
car4 = Car('Wolswagen', 'red', 6000)

carA = Car('mercedes', 'white', 8000)
carB = Car('toyota', 'black', 1000)
carC = Car('ferrari', 'red', 3000)
carD = Car('Wolswagen', 'red', 6000)

parking1 = pd.Series(data=[[car1, car2], [car3, car4]])
parking2 = pd.Series(data=[[carA, carB], [carC, carB]])

def compare_parkings(park1, park2):
    diff = list()
    """ iterate through cars in parking1, for example, for car1 on row1, 
    it needs to check whether its in the first row of parking2 as well """
    for level1, level2 in zip(parking1, parking2):
        level_diff = list()
        for car in level1:
            if car in level2: #This probably doesn't work
                level_diff.append(True)
            else:
                level_diff.append(False)
        diff.append(level_diff)
    return diff

diff = compare_parkings(parking1, parking2)

expected_diff = [True, False, False, True]
pass

When I run this script, I get all False for diff

how can I achieve that ?

Thanks

1 Answers

If you create two different instances of the same class, they will have different values, even if all their attributes have the same values.

To achieve the comparison you want, you could explicitly define the __eq__() method of your Car class. This is the method that will be used by the == operator when comparing two Car instances, and it will also be used by the in operator when applied between a Car instance and a list of Car instances. So you can then use the in operator within your compare_parkings function with the intended result.

By the way, the result of the in operation is a Boolean value, so you can simplify the code at that point by appending this value to the list directly:

import pandas as pd


class Car:

    def __init__(self, brand, color, mileage):
        self.brand = brand
        self.color = color
        self.mileage = mileage
        
    def __eq__(self, other):
        if self.brand != other.brand:
            return False
        if self.color != other.color:
            return False
        if self.mileage != other.mileage:
            return False
        return True

    
car1 = Car('toyota', 'black', 1000)
car2 = Car('mercedes', 'white', 3222)
car3 = Car('honda', 'yellow', 2500)
car4 = Car('Wolswagen', 'red', 6000)

carA = Car('mercedes', 'white', 8000)
carB = Car('toyota', 'black', 1000)
carC = Car('ferrari', 'red', 3000)
carD = Car('Wolswagen', 'red', 6000)

parking1 = pd.Series(data=[[car1, car2], [car3, car4]])
parking2 = pd.Series(data=[[carA, carB], [carC, carB]])


def compare_parkings(park1, park2):
    diff = list()
    """ iterate through cars in parking1, for example, for car1 on row1, 
    it needs to check whether its in the first row of parking2 as well """
    for level1, level2 in zip(parking1, parking2):
        level_diff = list()
        for car in level1:
            level_diff.append(car in level2)
        diff.append(level_diff)
    return diff

This should work now:

compare_parkings(parking1, parking2)

Returns [[True, False], [False, False]].

Related