Найти дубликаты в кадре данных, где один столбец может находиться в пределах диапазона - PullRequest
0 голосов
/ 06 сентября 2018

Я разобрался со всем, что касается поиска дубликатов. У меня есть столбец, помечающий их как True или False, а затем я удаляю один с определенным значением. На данный момент мне просто нужно включить все, что один столбец находится в диапазоне строк.

Для примера:

       Status Height Object  Store
0        Here   100'    ABC  EFG
1  Maybe here    99'    ABC  EFG
2  Maybe here   102'    ABC  JKL
3  Maybe here    99'    ABC  QRS
4        Here    80'    XYZ  QRS
5  Maybe here    78'    XYZ  JKL

Желаемый вывод:

       Status Height Object  Store
0        Here   100'    ABC  EFG
2  Maybe here   102'    ABC  JKL
3  Maybe here    99'    ABC  QRS
4        Here    80'    XYZ  QRS
5  Maybe here    78'    XYZ  JKL

Строки «Возможно здесь» должны быть удалены, потому что их высота находится в пределах +/- 4 фута. Кто-нибудь может указать мне правильное направление?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Чтобы решить, следует ли удалять строку на основе height, проверьте, присутствует ли хотя бы один элемент в [height-threshold, height+threshold] в dictionary. Если есть, удалите height

Например, если height=80 & threshold=4, проверьте, присутствует ли хотя бы один номер из 76, 77, 78, 79, 80, 81, 82, 83, 84 в dictionary. Если есть, удалите строку.

global dictionary

def can_i_remove(item, threshold):
    global dictionary
    key = item-threshold
    while(key <= (item+threshold)):
        if(dictionary.get(key) != None):
            return True
        key = key+1
    dictionary[item] = False
    return False

def main():
    global dictionary
    dictionary = dict()
    threshold = 4
    ret = can_i_remove(100, threshold)
    print(str(dictionary) + " -> 100 - " + str(ret))
    ret = can_i_remove(96, threshold)
    print(str(dictionary) + " -> 96 - " + str(ret))
    ret = can_i_remove(95, threshold)
    print(str(dictionary) + " -> 95 - " + str(ret))
    ret = can_i_remove(104, threshold)
    print(str(dictionary) + " -> 104 - " + str(ret))
    ret = can_i_remove(105, threshold)
    print(str(dictionary) + " -> 105 - " + str(ret))

main()

Выход:

{100: False} -> 100 - False
{100: False} -> 96 - True
{100: False, 95: False} -> 95 - False
{100: False, 95: False} -> 104 - True
{100: False, 95: False, 105: False} -> 105 - False
0 голосов
/ 06 сентября 2018

Вы можете использовать решение numpy с указанными значениями для диапазона get + -4 и фильтровать по boolean indexing:

print (df)
       Status Height Object
0        Here   100'    ABC
1  Maybe here    99'    ABC
2  Maybe here   102'    ABC
3  Maybe here    99'    ABC
4        Here    80'    XYZ
5  Maybe here    78'    XYZ


#specify values for check ranges
vals = [100, 80]
#remove traling 'and convert to integer
a = df['Height'].str.strip("'").astype(int)

#convert to numpy array and compare, get abs values
arr =  np.abs(np.array(vals) - a.values[:, None])
print (arr)
[[ 0 20]
 [ 1 19]
 [ 2 22]
 [ 1 19]
 [20  0]
 [22  2]]

#xreate boolean mask for match at least one True
mask = np.any((arr > 0) & (arr < 4), axis=1)
print (mask)
[False  True  True  True False  True]

#inverting condition by ~
print (df[~mask])
  Status Height Object
0   Here   100'    ABC
4   Here    80'    XYZ

Аналогично:

#invert conditions and check if all values Trues per row
mask = np.all((arr <= 0) | (arr >= 4), axis=1)
print (mask)
[ True False False False  True False]

print (df[mask])
  Status Height Object
0   Here   100'    ABC
4   Here    80'    XYZ

EDIT:

Решение аналогично только новой логической цепочке, созданной DataFrame.duplicated:

#specify values for check ranges
vals = [100, 80]
#remove traling 'and convert to integer
a = df['Height'].str.strip("'").astype(int)

#convert to numpy array and compare, get abs values
arr =  np.abs(np.array(vals) - a.values[:, None])
print (arr)
[[ 0 20]
 [ 1 19]
 [ 2 22]
 [ 1 19]
 [20  0]
 [22  2]]

#create boolean mask for match at least one True
mask1 = np.any((arr > 0) & (arr < 4), axis=1)
print (mask1)
[False  True  True  True False  True]

mask2 = df.duplicated(subset=['Object','Store'], keep=False)
print (mask2)
0     True
1     True
2    False
3    False
4    False
5    False
dtype: bool


mask = mask1 & mask2

#inverting condition by ~
print (df[~mask])
       Status Height Object Store
0        Here   100'    ABC   EFG
2  Maybe here   102'    ABC   JKL
3  Maybe here    99'    ABC   QRS
4        Here    80'    XYZ   QRS
5  Maybe here    78'    XYZ   JKL

#invert conditions and check if all values Trues per row
mask3 = np.all((arr <= 0) | (arr >= 4), axis=1)
print (mask3)
[ True False False False  True False]

mask = mask3 | ~mask2

print (df[mask])
       Status Height Object Store
0        Here   100'    ABC   EFG
2  Maybe here   102'    ABC   JKL
3  Maybe here    99'    ABC   QRS
4        Here    80'    XYZ   QRS
5  Maybe here    78'    XYZ   JKL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...