Python 将dict中的列表转换为序列

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

我试图从HTML输入文件中读取行,并准备系列/数据帧,以便最终创建图形。我使用lxml的objectify获取HTML数据行并将它们转换为列表。每当我尝试获取列表数据并创建一个系列或数据帧时,我都会得到一个系列(或数据帧),其中包含的元素数量等于列表中的项目数量,但元素的数据就是列表本身

我能证明我的问题的最简单方法是:

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])
is
lxml.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']
的类型实际上是一个
列表,例如put
list()
在其周围,它可能类似于列表,但实际上不是列表,还显示系列中第一个元素的类型,例如
类型(s[0])
为什么会被否决?这个问题是可以理解的,并且提供了一个有效的SSCCE,它已经对它进行了相当高的排名。唯一缺少的是对所需输出的描述,但在上下文中,我认为它非常清楚。@dooz:作为一种解决方法,您可以使用
系列(在htmldata中obj的obj.pyval)
。我无法立即了解原因,但关于
lxml.objectify.*元素的某些内容
对象与序列构造的关系不太好。对,我的(现在已删除)答案基本上是DSM的评论。啊,+1。我记得
isscalar
也导致了Sage的问题--
numpy
不将Sage整数识别为标量,因此数组的索引工作不太正常。我想我更喜欢
pyval
方法,尽管它保留了更多的类型信息。同意……我想没有太多其他方法k最终可以做到这一点,因为确定用户是否真的将列表作为一个系列元素传递并表示它是非常困难的