Вот мой подход:
# separate relevant parts
s = df['ip'].str.extract('(\d+\.\d+\.\d+.)(\d+)-?(\d+)?').ffill(1)
# convert last parts to int for easy manipulation
s[1] = s[1].astype(int)
s[2] = s[2].astype(int)
# masking the IP range
lowers = s[1].values[:,None] <= np.arange(256)
uppers = np.arange(256)<= s[2].values[:,None]
# create new dataframe for the new IPs
u = pd.DataFrame(lowers & uppers,
index=pd.MultiIndex.from_arrays([df['last_active'],s[0]])
)
# final data
(u.where(u).stack().reset_index(name='dummy')
.assign(ip=lambda x: x[0]+x['level_2'].astype(str))
.drop([0,'level_2','dummy'], axis=1)
)
Вывод:
last_active ip
0 01/02/2012 192.167.0.9
1 05/06/2013 226.90.2.12
2 05/06/2014 10.90.2.9
3 NaN 12.60.2.80
4 05/06/2016 192.168.2.11
5 05/06/2016 192.168.2.12
6 05/06/2016 192.168.2.13
7 05/06/2016 192.168.2.14
8 05/06/2016 192.168.2.15
9 05/06/2016 192.168.2.16
10 05/06/2016 192.168.2.17