Заменяем \n
на ;
для единообразия, затем режем сплитом по ;
, далее по очереди "взрываем" полученные списки, размножая строки. Затем удаляем дубликаты.
df = pd.DataFrame(
{'num': {0: '1.0.1', 1: '1.0.2'}, 'grl': {0: 'vpn\nWiFi_SSID', 1: 'vpn\nWiFi_SSID'}, 'seg': {0: None, 1: None},
'gr2': {0: 'ip_l', 1: 'ip_2'}, 'protocol': {0: 'HTTPS', 1: 'XMPP;XMPP;XMPP;XMPP\nHTTPS'},
'port': {0: '443', 1: '5235\n5228\n5229\n5230\n443'}, 'status': {0: 'Изменено', 1: 'Изменено'}})
print('\nИсходный\n',df)
cols = ['grl', 'protocol', 'port']
df[cols] = df[cols].apply(lambda x: x.astype(str).str.replace('\n', ';').str.split(';'))
df = df.explode('grl').explode('protocol').explode('port').drop_duplicates(cols)
print('\nИтог\n',df)
Исходный
num grl seg gr2 protocol port status
0 1.0.1 vpn\nWiFi_SSID None ip_l HTTPS 443 Изменено
1 1.0.2 vpn\nWiFi_SSID None ip_2 XMPP;XMPP;XMPP;XMPP\nHTTPS 5235\n5228\n5229\n5230\n443 Изменено
Итог
num grl seg gr2 protocol port status
0 1.0.1 vpn None ip_l HTTPS 443 Изменено
0 1.0.1 WiFi_SSID None ip_l HTTPS 443 Изменено
1 1.0.2 vpn None ip_2 XMPP 5235 Изменено
1 1.0.2 vpn None ip_2 XMPP 5228 Изменено
1 1.0.2 vpn None ip_2 XMPP 5229 Изменено
1 1.0.2 vpn None ip_2 XMPP 5230 Изменено
1 1.0.2 vpn None ip_2 XMPP 443 Изменено
1 1.0.2 vpn None ip_2 HTTPS 5235 Изменено
1 1.0.2 vpn None ip_2 HTTPS 5228 Изменено
1 1.0.2 vpn None ip_2 HTTPS 5229 Изменено
1 1.0.2 vpn None ip_2 HTTPS 5230 Изменено
1 1.0.2 WiFi_SSID None ip_2 XMPP 5235 Изменено
1 1.0.2 WiFi_SSID None ip_2 XMPP 5228 Изменено
1 1.0.2 WiFi_SSID None ip_2 XMPP 5229 Изменено
1 1.0.2 WiFi_SSID None ip_2 XMPP 5230 Изменено
1 1.0.2 WiFi_SSID None ip_2 XMPP 443 Изменено
1 1.0.2 WiFi_SSID None ip_2 HTTPS 5235 Изменено
1 1.0.2 WiFi_SSID None ip_2 HTTPS 5228 Изменено
1 1.0.2 WiFi_SSID None ip_2 HTTPS 5229 Изменено
1 1.0.2 WiFi_SSID None ip_2 HTTPS 5230 Изменено