создать фрейм данных из строки Python Python - PullRequest
2 голосов
/ 21 мая 2019

Я создаю программу для перечисления IP-адреса и пользователей, подключенных к локальной сети. Я сделал, получая данные с помощью Nmap. Далее я хочу изменить данные результата на определенный фрейм данных, используя панд или любым другим способом. Как это сделать.

Вот код:

import pandas as pd
import subprocess
from subprocess import Popen, PIPE
import re

def ipget():
    i = 'nmap -sP 192.168.1.*'
    output = subprocess.getoutput(i)
    a = str(output).replace("Nmap","").replace("Starting  7.01 ( https://nmap.org ) at","").replace("scan report for","").replace("Host is up","").replace("latency","").replace("done: 256 IP addresses ","")
    data = re.sub(r"(\(.*?\)\.)", "", a)
    print(data)
#df = pd.DataFrame(data, columns = ['User', 'IP_Address']) 

#print (df) 
ipget()

вывод хранится в данных и представляет собой строку:

2019-05-21 18:19 IST 
android-eb20919729f10e96 (192.168.1.8)

smackcoders (192.168.1.9)

princes-mbp (192.168.1.10)

shiv-mbp (192.168.1.15)

(4 hosts up) scanned in 18.35 seconds

Требуемый вывод для создания в кадре данных:

User                            IP_Address
android-eb20919729f10e96        192.168.1.8
smackcoders                     192.168.1.9
princes-mbp                     192.168.1.10
shiv-mbp                        192.168.1.15

Ответы [ 3 ]

4 голосов
/ 21 мая 2019

Скажем, у вас есть текст:

2019-05-21 18:19 IST 
android-eb20919729f10e96 (192.168.1.8)

smackcoders (192.168.1.9)

princes-mbp (192.168.1.10)

shiv-mbp (192.168.1.15)

(4 hosts up) scanned in 18.35 seconds

Используйте регулярные выражения, чтобы найти нужные данные:

>>> ms = re.findall(r'\n([^\s]*)\s+\((\d+\.\d+\.\d+\.\d+)\)', text)
>>> ms

[('android-eb20919729f10e96', '192.168.1.8'),
 ('smackcoders', '192.168.1.9'),
 ('princes-mbp', '192.168.1.10'),
 ('shiv-mbp', '192.168.1.15')]

>>> df = pd.DataFrame(ms, columns=['User', 'IP_Address'])

Сравнение с другими ответами:

  1. регулярное выражение короткое.
  2. Regex работает только через ваш текст один раз .

str.replace запускается один раз за вызов, поэтому решение регулярных выражений может получить огромную эффективность для длинных журналов.

3 голосов
/ 21 мая 2019

Использовать StringIO

import sys
if sys.version_info[0] < 3: 
    from StringIO import StringIO
else:
    from io import StringIO

import pandas as pd
a="""
android-eb20919729f10e96 (192.168.1.8)

smackcoders (192.168.1.9)

princes-mbp (192.168.1.10)

shiv-mbp (192.168.1.15)"""

TESTDATA = StringIO(a)

df = pd.read_csv(TESTDATA, sep=" ",names=['User','IP_Address'])

Добавьте строку ниже для удаления ( и )

import re
df.IP_Address = df.IP_Address.map(lambda x:re.sub('\(|\)',"",x))
2 голосов
/ 21 мая 2019

Если ваша строка называется s, следующий код делает то, что вы хотите:

line_list = []

# iterate over each line
for line in s.split("\n"):
    #remove empty lines
    if line == '':
        continue

    #replace ( and ) with empty strings 
    line = line.replace("(", "").replace(")", "")

    line_list.append(line)

# remove first and last line
line_list = line_list[1:-1]

array = []
# split lines by " "
for line in line_list:
    array.append(line.split(" "))

# create dataframe
pd.DataFrame(array, columns = ["User", "IP_Adress"])

Используя listcomprehension, вы можете сделать то же самое, что и oneliner:

pd.DataFrame([line.replace("(", "").replace(")", "").split(" ") for line in s.split("\n") if line != ""][1:-1], columns = ["User", "IP_Adress"])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...