我有以下列表:
data=['ip: 1.2.3.9',
'port: 80',
'protocol: tcp',
'state:open',
'banner: HTTP/1.1 200 OK\\x0d\\x0a',
'service: http',
'ip: 2.3.19.7',
'port: 23',
'protocol: tcp',
'state:open',
'banner: xff\\xfb\\x03',
'service: unknown',
'ip: 21.17.28.15',
'port: 8080',
'protocol: tcp',
'state:open',
'service: title',
'ip: 3.17.8.15',
'port: 8080',
'protocol: tcp',
'state:open',
'service: title']
该列表具有顺序,因此每个IP,端口,协议,状态,标语和服务都是一行。这应该是第一行:'ip:1.2.3.9','port:80','protocol:tcp','state:open','banner:HTTP / 1.1 200 OK \ x0d \ x0a',服务:http '。但是,有时候,我只有ip,端口,协议,状态,服务,没有横幅,或者任何其他缺失值都是可能的。我想将其转换为数据框,并且已经尝试过:
import pandas as pd
col= ['ip', 'port', 'protocol','state','banner','service']
df = pd.DataFrame([data[i:i+6] for i in range(0, len(data), 6)], columns=col)
但是,输出看起来像这样:
Out[75]:
ip port protocol state \
0 ip: 1.2.3.9 port: 80 protocol: tcp state:open
1 ip: 2.3.19.7 port: 23 protocol: tcp state:open
2 ip: 21.17.28.15 port: 8080 protocol: tcp state:open
3 port: 8080 protocol: tcp state:open service: title
banner service
0 banner: HTTP/1.1 200 OK\x0d\x0a service: http
1 banner: xff\xfb\x03 service: unknown
2 service: title ip: 3.17.8.15
3 None None
正如您在第二行中看到的,横幅应该为空,服务不在右列中,而下一行中的IP应该是服务值所在的位置。这些值是连续存储的,那么如何检查并确保每个值都在各自的列中?我不是熊猫专家,所以我们将不胜感激。
一种应该很好用的方法是使用字典,冒号之前和之后的数据看起来已经很格式化了,文本已经很明确了,所以我们可以使用它并使用zip_longest来配对字典。
from collections import defaultdict
from itertools import zip_longest
#initialize defaultdict
d = defaultdict(list)
for entry in data:
#get data before and after the colon
key = entry.split(':')[0]
value = entry.split(':')[-1]
#create dictionary
d[key].append(value)
#what happens here is we zip the pairs
#from each key, and where there is no corresponding value,
#it returns none
combo = zip_longest(*d.values(),)
#pass it to the dataframe
pd.DataFrame(combo,columns=d.keys())
ip port protocol state banner service
0 1.2.3.9 80 tcp open HTTP/1.1 200 OK\x0d\x0a http
1 2.3.19.7 23 tcp open xff\xfb\x03 unknown
2 21.17.28.15 8080 tcp open None title
3 3.17.8.15 8080 tcp open None title