Python 将dict中的列表转换为序列
我试图从HTML输入文件中读取行,并准备系列/数据帧,以便最终创建图形。我使用lxml的objectify获取HTML数据行并将它们转换为列表。每当我尝试获取列表数据并创建一个系列或数据帧时,我都会得到一个系列(或数据帧),其中包含的元素数量等于列表中的项目数量,但元素的数据就是列表本身 我能证明我的问题的最简单方法是:Python 将dict中的列表转换为序列,python,python-3.x,pandas,Python,Python 3.x,Pandas,我试图从HTML输入文件中读取行,并准备系列/数据帧,以便最终创建图形。我使用lxml的objectify获取HTML数据行并将它们转换为列表。每当我尝试获取列表数据并创建一个系列或数据帧时,我都会得到一个系列(或数据帧),其中包含的元素数量等于列表中的项目数量,但元素的数据就是列表本身 我能证明我的问题的最简单方法是: from lxml import etree from lxml import objectify from pandas import Series line='<tr
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)
type(htmldata[0])
是:lxml.objectify.StringElement
type(htmldata[3])
is:lxml.objectify.inteElement
当我在寻找类似的东西时:
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...
我的清单最后看起来像:
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, ...
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']['use'][0])
islxml.objectify.StringElement
我需要将这些元素强制转换为普通字符串和int吗?问题是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
[23]中的:打印[在htmldata中为x键入(x)]
[, , , , , , , ]
[24]中:系列([str(x)表示htmldata中的x])
出[24]:
0 192.168.1.0
1 XXDHCP
2岁
3 255
4 0
5 YYDHCP
6岁
7 250
8 0
9 0%
10 505
11 505
12 0
13
问得好!这是一种奇怪的行为
出现此问题的原因是,您正在传递序列a列表lxml.objectify.StringElement
s.pandas
由np.array
s支持,因此更喜欢将其数据存储在统一的数组中。因此,它将所有内容抽象为np.object
,以便将它们推送到数组中。确实,如果您查看数据的底层数组(Series.values
),您会发现它创建得很好,尽管它是一个lxml.objectify.StringElements
的numpy数组,这可能不是您想要的
当然,简单的解决方案是将所有内容都转换为字符串,这可能就是您在本例中想要做的
但你会问,为什么打印会很有趣呢?好吧,如果你在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对象不是基串,因此假设它们是序列。pandas可能应该检查
isinstance(x,collections.Sequence)
…确保labdata['192.168.1.0']['Utilization']
的类型实际上是一个列表,例如putlist()
在其周围,它可能类似于列表,但实际上不是列表,还显示系列中第一个元素的类型,例如类型(s[0])
为什么会被否决?这个问题是可以理解的,并且提供了一个有效的SSCCE,它已经对它进行了相当高的排名。唯一缺少的是对所需输出的描述,但在上下文中,我认为它非常清楚。@dooz:作为一种解决方法,您可以使用系列(在htmldata中obj的obj.pyval)
。我无法立即了解原因,但关于lxml.objectify.*元素的某些内容
对象与序列构造的关系不太好。对,我的(现在已删除)答案基本上是DSM的评论。啊,+1。我记得isscalar
也导致了Sage的问题--numpy
不将Sage整数识别为标量,因此数组的索引工作不太正常。我想我更喜欢pyval
方法,尽管它保留了更多的类型信息。同意……我想没有太多其他方法k最终可以做到这一点,因为确定用户是否真的将列表作为一个系列元素传递并表示它是非常困难的