Сравните столбец фрейма данных между двумя другими столбцами другого фрейма данных - PullRequest
1 голос
/ 11 января 2020

Имеют два фрейма данных, как показано ниже.

print(Data)



Band         CGI       CID   
  3G  0-0-1505-37226   1505 
  3G   0-0-111-14769    111 
  3G  0-0-1505-36896   1505 
  3G  0-0-1501-33532   1501 
  3G   0-0-111-14769    111 
 ...             ...    ... 
  3G    0-0-111-4857    111 
  3G  0-0-1505-37458   1505 
  3G   0-0-222-43029    222 
  3G   0-0-222-43029    222 
  3G   0-0-222-43029    222 

print(IDS)

Circle STARTR  ENDR
 KUM    601   622  
 BMF   1401  1406  
 KIL      2  1215  
 LOK    206   226  
 HOE   1101  1108  
 HOP    401   403  
 KOK    501   503  
 KRR    801   817  
 KUJ   1301  1303  
 KJL    101   153  
CPGJ    301   339  
 BNG    701   714  
 JHG   1501  1507  
 EMG    701   911  
 WPR   1001  1014  

Требуется найти круг из данных IDS, где CID присутствует в фрейме данных между STARTR и ENDR.

окончательный результат будет.

Band             CGI  CID   Circle
  3G  0-0-1505-37226   1505 JHG   
  3G   0-0-111-14769    111 KJL   
  3G  0-0-1505-36896   1505 JHG   
  3G  0-0-1501-33532   1501 JHG   
  3G   0-0-111-14769    111 KJL   
 ...             ...    ... ...   
  3G    0-0-111-4857    111 KJL   
  3G  0-0-1505-37458   1505 JHG   
  3G   0-0-222-43029    222 LOK 
  3G   0-0-222-43029    222 LOK   
  3G   0-0-222-43029    222 LOK   




 Data['Circle'] = np.where((Data['CID'] >= IDS['STARTR']) & (Data['CID'] <= IDS['ENDR']),IDS['Circle'],np.nan) 

перепробовал множество вариантов, но не повезло. пример ошибки .. ValueError: может сравнивать только идентичные объекты Series

Ответы [ 2 ]

1 голос
/ 11 января 2020

Вот способ сделать .apply:

# get matching circles
Data['Circle'] = Data['CID'].apply(lambda x: IDS.loc[(IDS['STARTR'] <= x) & (x <= IDS['ENDR']),'Circle'].values)

  Band             CGI   CID      Circle
0   3G  0-0-1505-37226  1505       [JHG]
1   3G   0-0-111-14769   111  [KIL, KJL]
2   3G  0-0-1505-36896  1505       [JHG]
3   3G  0-0-1501-33532  1501       [JHG]
4   3G   0-0-111-14769   111  [KIL, KJL]
5   3G    0-0-111-4857   111  [KIL, KJL]
6   3G  0-0-1505-37458  1505       [JHG]
7   3G   0-0-222-43029   222  [KIL, LOK]
8   3G   0-0-222-43029   222  [KIL, LOK]
9   3G   0-0-222-43029   222  [KIL, LOK]


# get last value
Data['Circle'] = Data['Circle'].str[-1]

  Band             CGI   CID Circle
0   3G  0-0-1505-37226  1505    JHG
1   3G   0-0-111-14769   111    KJL
2   3G  0-0-1505-36896  1505    JHG
3   3G  0-0-1501-33532  1501    JHG
4   3G   0-0-111-14769   111    KJL
5   3G    0-0-111-4857   111    KJL
6   3G  0-0-1505-37458  1505    JHG
7   3G   0-0-222-43029   222    LOK
8   3G   0-0-222-43029   222    LOK
9   3G   0-0-222-43029   222    LOK
0 голосов
/ 11 января 2020

numpy где здесь не тот инструмент, я думаю. Он используется, когда вам нужно сравнивать массивы поэлементно, но это не ваш случай: для каждой строки в Data вам нужно выбрать правильную строку в IDS. Их может быть несколько: если посмотреть на ваш пример, ваши 'STARTR' и 'ENDR' могут перекрываться, а в некоторых случаях согласно вашему описанию вам может потребоваться выбрать два Circle s.

Вот рабочее решение, использующее apply :

def search(x):
    res = IDS.loc[(x >= IDS['STARTR']) & (x <= IDS['ENDR'])]['Circle']
    return list(res)

data['Circle'] = data['CID'].apply(search)

Это возвращает:

  Band             CGI   CID      Circle
0   3G  0-0-1505-37226  1505       [JHG]
1   3G   0-0-111-14769   111  [KIL, KJL]
2   3G  0-0-1505-36896  1505       [JHG]
3   3G  0-0-1501-33532  1501       [JHG]
4   3G   0-0-111-14769   111  [KIL, KJL]
5   3G    0-0-111-4857   111  [KIL, KJL]
6   3G  0-0-1505-37458  1505       [JHG]
7   3G   0-0-222-43029   222  [KIL, LOK]
8   3G   0-0-222-43029   222  [KIL, LOK]
9   3G   0-0-222-43029   222  [KIL, LOK]

Как вы видите, я использовал список для столбца Circle, поскольку их может быть несколько значения.
В вашем ожидаемом выводе вы, кажется, всегда выбираете последнее, поэтому, если это правило, jus замените последнюю строку функции search на:

return list(res)[-1]

, и вы get:

  Band             CGI   CID Circle
0   3G  0-0-1505-37226  1505    JHG
1   3G   0-0-111-14769   111    KJL
2   3G  0-0-1505-36896  1505    JHG
3   3G  0-0-1501-33532  1501    JHG
4   3G   0-0-111-14769   111    KJL
5   3G    0-0-111-4857   111    KJL
6   3G  0-0-1505-37458  1505    JHG
7   3G   0-0-222-43029   222    LOK
8   3G   0-0-222-43029   222    LOK
9   3G   0-0-222-43029   222    LOK

EDIT

Чтобы рассмотреть случаи, когда в данном диапазоне не найдено Circle, вы можете заключить оператор return в блок try except:

try:
    return list(res)[-1]
except IndexError:
    return ""
...