我正在尝试从HTML输入文件中读取行并准备Series / DataFrames,以便最终创建图形。我正在使用lxml的objectify来获取HTML数据并将它们转换为列表。每当我尝试获取列表数据并创建一个Series或DataFrame时,我得到一个Series(或DataFrame),其中包含的元素数量等于列表中的项目数,但元素的数据本身就是我的列表。 / p>
我能说明问题的最简单方法是:
from lxml import etree
from lxml import objectify
from pandas import Series
line='<tr class="alt"><td>192.168.1.0</td><td>XXDHCP</td><td>Y</td><td>255</td><td>0</td><td>YYDHCP</td><td>Y</td><td>250</td><td>0</td><td>0%</td><td>505</td><td>505</td><td>0</td><td></td></tr>'
htmldata=(objectify.fromstring(line)).getchildren()
htmlseries=Series(htmldata)
htmlseries最终看起来像:
0 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
1 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
2 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
3 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
4 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
5 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
6 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
7 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
8 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
9 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
10 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
11 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
12 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
13 [[[192.168.1.0, XXDHCP, Y, 255, 0, YYDHCP, Y, ...
type(htmldata[0])
是:lxml.objectify.StringElement
type(htmldata[3])
是:lxml.objectify.IntElement
我正在寻找类似的东西:
0 192.168.1.0
1 XXDHCP
2 Y
3 255
4 0
5 YYDHCP
6 Y
7 250
8 0
9 0%
10 505
11 505
12 0
13
我做错了什么?对于发生的事情,我有点神秘。当我尝试将每列读入列表时:
data=objectify.fromstring(line).getchildren()
labdata[ip]['Scope'].append(data[0])
labdata[ip]['Cluster1'].append(data[1])
labdata[ip]['Active1'].append(data[2])
...etc...
我的列表最终看起来像:
labdata['192.168.1.0']['Utilization']
['100%',
'96%',
'96%',
'90%',
'81%',
'96%',
'90%',
'97%',
'98%',
'92%',
'99%',
...etc...
]
但出于某种原因:
Series(labdata['192.168.1.0']['Utilization'])
0 [[[192.168.1.0, XXDHCP, Y, 0, 383, YYDHCP, Y...
1 [[[192.168.1.0, XXDHCP, Y, 28, 355, YYDHCP, ...
2 [[[192.168.1.0, XXDHCP, Y, 28, 355, YYDHCP, ...
3 [[[192.168.1.0, XXDHCP, Y, 76, 307, YYDHCP, ...
4 [[[192.168.1.0, XXDHCP, Y, 104, 279, YYDHCP,...
5 [[[192.168.1.0, XXDHCP, Y, 27, 356, YYDHCP, ...
6 [[[192.168.1.0, XXDHCP, Y, 66, 317, YYDHCP, ...
7 [[[192.168.1.0, XXDHCP, Y, 15, 368, YYDHCP, ...
8 [[[192.168.1.0, XXDHCP, Y, 15, 368, YYDHCP, ...
9 [[[192.168.1.0, XXDHCP, Y, 54, 329, YYDHCP, ...
...etc...
type(labdata['192.168.1.0']['Utilization'][0])
是lxml.objectify.StringElement
我是否需要将这些元素转换为普通字符串和整数?
答案 0 :(得分:7)
问题是htmldata中的元素不是简单类型,而np.isscalar在这里被欺骗了 (因为这是确定我们是否有列表列表或标量列表的方式 只是字符串化元素是否可行
In [23]: print [ type(x) for x in htmldata ]
[<type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.StringElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.IntElement'>, <type 'lxml.objectify.StringElement'>]
In [24]: Series([ str(x) for x in htmldata ])
Out[24]:
0 192.168.1.0
1 XXDHCP
2 Y
3 255
4 0
5 YYDHCP
6 Y
7 250
8 0
9 0%
10 505
11 505
12 0
13
答案 1 :(得分:2)
好问题!这是奇怪的行为。
出现问题是因为您正在传递系列列表lxml.objectify.StringElement
。 pandas
由np.array
支持,因此更喜欢将其数据存储在统一数组中。因此,它将所有内容抽象为np.object
,以便它可以将它们推入数组中。实际上,如果你查看数据的基础数组(Series.values
),你会看到它被创建得很好,虽然它是lxml.objectify.StringElements
的一个numpy数组,可能不是你想要的。< / p>
简单的解决方案当然是将所有内容都转换为字符串,这可能就是你想要做的事情。
但是为什么打印有趣,你问?好吧,如果您在pandas中钻取代码,最终会得到pandas.core.common
中的以下函数:
def _is_sequence(x):
try:
iter(x)
len(x) # it has a length
return not isinstance(x, basestring) and True
except Exception:
return False
换句话说,pandas看到lxml对象不是basetrings,因此假定它们是序列。熊猫应该检查isinstance(x, collections.Sequence)
...