熊猫数据框具有多个值和缺失值的单个列表

问题描述 投票:0回答:1

我有以下列表:

 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应该是服务值所在的位置。这些值是连续存储的,那么如何检查并确保每个值都在各自的列中?我不是熊猫专家,所以我们将不胜感激。

python pandas
1个回答
0
投票

一种应该很好用的方法是使用字典,冒号之前和之后的数据看起来已经很格式化了,文本已经很明确了,所以我们可以使用它并使用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
© www.soinside.com 2019 - 2024. All rights reserved.