2017-02-22 5 views
1

В таблице IP-области видимости есть имя местоположения и начальный IP-адрес этого местоположения. Правило: если следующая строка находится в том же диапазоне адресов, конечный IP-адрес местоположения - это значение следующей строки - 1, в противном случае - последний адрес его диапазона. Вот образец данных:использовать сдвиг для нового значения столбца в pandas

Name StartRange 
loc1 172.28.10.15 
loc2 172.28.10.128 
loc3 172.28.12.0 
loc4 172.28.12.58 

Ожидаемый результат:

Name StartRange  EndIP 
loc1 172.28.10.15 172.28.10.127 
loc2 172.28.10.128 172.28.10.255 
loc3 172.28.12.0  172.28.12.57 
loc4 172.28.12.58 172.28.12.255 

Вот код, который я пробовал:

from socket import inet_aton 
from struct import unpack 

import pandas as pd 

mask = unpack(">L", inet_aton('255.255.255.0'))[0] 

def getEndIP(startIP, endIP): 
    hi = (startIP['StartIP'] & mask) + 255 
    return hi if hi < endIP['StartIP'] else endIP['StartIP'] - 1 

xls = pd.read_excel("E:\\TEMP\\AllScope.xlsx") 
xls['StartIP'] = xls['StartRange'].map(lambda a: unpack(">L", inet_aton(a))[0]) 
xls = xls.sort_values('StartIP') 
xls['EndIP'] = getEndIP(xls['StartIP'], xls['StartIP'].shift(-1)) 

print xls[['Name', 'StartRange', 'StartIP', 'EndIP']] 

Но у меня есть ключ сообщение об ошибке:

KeyError: 'StartIP' 

Что я делаю Неправильно? (Я не слишком хорошо знакомы еще с пандами)

Update: Вот след:

runfile('E:/Documents/Projects/Python/Egyéb progik/Network/network.py', wdir='E:/Documents/Projects/Python/Egyéb progik/Network') 
Traceback (most recent call last): 

    File "<ipython-input-67-6caaa536457c>", line 1, in <module> 
    runfile('E:/Documents/Projects/Python/Egyéb progik/Network/network.py', wdir='E:/Documents/Projects/Python/Egyéb progik/Network') 

    File "C:\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile 
    execfile(filename, namespace) 

    File "C:\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile 
    exec(compile(scripttext, filename, 'exec'), glob, loc) 

    File "E:/Documents/Projects/Python/Egyéb progik/Network/network.py", line 15, in <module> 

    File "E:/Documents/Projects/Python/Egyéb progik/Network/network.py", line 9, in getEndIP 

    File "C:\Anaconda2\lib\site-packages\pandas\core\series.py", line 603, in __getitem__ 
    result = self.index.get_value(self, key) 

    File "C:\Anaconda2\lib\site-packages\pandas\indexes\base.py", line 2169, in get_value 
    tz=getattr(series.dtype, 'tz', None)) 

    File "pandas\index.pyx", line 98, in pandas.index.IndexEngine.get_value (pandas\index.c:3557) 

    File "pandas\index.pyx", line 106, in pandas.index.IndexEngine.get_value (pandas\index.c:3240) 

    File "pandas\index.pyx", line 156, in pandas.index.IndexEngine.get_loc (pandas\index.c:4363) 

KeyError: 'StartIP' 
+0

Какая линия поднимает ошибку? –

+0

Либо этот: xls ['EndIP'] = getEndIP (xls ['StartIP'], xls ['StartIP']. Shift (-1)) или сама функция getEndIP – Gabor

+1

Вы передаете 'xls ['StartIP']' на 'getEndIP()', но затем снова войдите в столбец '' StartIP'' в этой функции. I.e., вы ищете 'xls ['StartIP'] ['StartIP']'. – chrisaycock

ответ

0

Здесь панды решение: Предположим, что dfl является

  StartRange 
Name    
loc1 172.28.10.15 
loc2 172.28.10.128 
loc3 172.28.12.0 
loc4 172.28.12.58 

Мы переводим первые строки в int для арифметических операций:

dfl['StartRange']= dfl.StartRange.apply(lambda s : [int(x) for x in s.split('.')]) 
dfl['EndIP']=dfl.StartRange.shift(-1) 
dfl.ix[-1,'EndIP']=[255,255,255,255] 

def adjust(row): 
    start,end=row 
    return min(start[:3]+[255],end[:3]+[end[3]-1]) 

dfl['EndIP']=dfl.apply(adjust,axis=1) 
dfend=dfl.applymap(lambda l : '.'.join([str(x) for x in l])) 

Then dfend является

  StartRange   EndIP 
Name        
loc1 172.28.10.15 172.28.10.127 
loc2 172.28.10.128 172.28.10.255 
loc3 172.28.12.0 172.28.12.57 
loc4 172.28.12.58 172.28.12.255 
+0

Ну, в первой строке есть ошибка: ValueError: («неверный литерал для int() с базой 10:« loc1 »», u'occurred at index Имя ') – Gabor

+0

Имя должно быть индексом. попробуйте dfl.set_index ('Name') раньше. –

Смежные вопросы