py2neo rel()列表索引必须是整数而不是浮点数

时间:2014-01-09 22:23:31

标签: python neo4j batch-processing py2neo

我正在尝试批量导入节点到Neo4j。但是当我尝试执行它时,它会抛出一个错误:List indices must be integers, not float。我真的不明白哪些列表项,我确实有浮点数,但这些都被转换为字符串......

部分代码:

graph_db = neo4j.GraphDatabaseService("http://127.0.0.1:7474/db/data/")
batch = neo4j.WriteBatch(graph_db)

for ngram, one_grams in data.items():
    ngram_rank = int(one_grams['_rank'])
    ngram_prob = '%.16f' % float(one_grams['_prob'])
    ngram_id = 'a'+str(n)
    ngram_node = batch.create(node({"word": ngram, "rank": str(ngram_rank), "prob": str(ngram_prob)}))

    for one_gram, two_grams in one_grams.items():
        one_rank = int(two_grams['_rank'])
        one_prob = '%.16f' % float(two_grams['_prob'])
        one_node = batch.create(node({"word": one_gram, "rank": str(one_rank), "prob": one_prob}))
        batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))) #line 81 throwing error
        results = batch.submit()

完整追溯

Traceback (most recent call last):
File "Ngram_neo4j.py", line 81, in probability_items 
    batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2692, in create
    uri = self._uri_for(entity.start_node, "relationships"),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2537, in _uri_for
    uri = "{{{0}}}".format(self.find(resource)),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2525, in find
    for i, req in pendulate(self._requests):,
File "virtenv\\lib\\site-packages\\py2neo\\util.py", line 161, in pendulate
    yield index, collection[index],
TypeError: list indices must be integers, not float

运行neo4j 2.0,py2neo 1.6.1,Windows 7 / 64bit,python 3.3 / 64bit

- 编辑 -

进行了一些测试,但错误位于引用节点的位置。 过于简化的示例代码:

for key, dict in data.items():                         #string, dictionary
    batch = neo4j.WriteBatch(graph_db)
    three_gram_node = batch.create(node({"word": key}))
    pprint(three_gram_node)
    batch.add_labels(three_gram_node, "3gram")         # must be int, not float

    for k,v in dict.items():                           #string, string
        four_gram_node = batch.create(node({"word": k}))
        batch.create_path(three_gram_node, "FOLLOWED_BY", four_gram_node)
                                            # cannot cast node from BatchRequest obj
    batch.submit()

创建节点batch.create(node({props}))时,pprint会返回P2Neo.neo4j. batchrequest object。 在第add_labels()行,它会产生与尝试创建关系时相同的错误:List indices must be integers, not float。 在batch.create_path()行,它会抛出一条错误消息,指出它无法从P2Neo.neo4j. batchrequest object转换节点。

我正在尝试使用脏调试来理解索引。

- 脏调试编辑 -

我一直在干扰pendulate(collection)功能。 虽然我真的不明白它是如何适应的,以及它是如何使用的,但是会发生以下情况: 每当它遇到一个不均匀的数字时,就会被转换为浮点数(这很奇怪,因为count - ((i + 1) / 2),其中i是一个不均匀的数字。)然后这个浮点数会抛出list indices错误。一些印刷品:

count:  3
i= 0
index: 0
(int)index: 0
i= 1             # i = uneven
index: 2.0       # a float appears
(int)index: 2    # this is a safe cast

这会导致list indices错误。这也发生在i=0时。由于这是一个常见的情况,我做了一个额外的if()来规避代码(可能的加速?)虽然我没有对它进行单元测试,但似乎我们可以安全地将索引转换为int ...

使用的摆动函数:

def pendulate(collection):
    count = len(collection)
    print("count: ", count)
    for i in range(count):
        print("i=", i)
        if i == 0:
            index = 0
        elif i % 2 == 0:
            index = i / 2
        else:
            index = count - ((i + 1) / 2)
        print("index:", index)
        index = int(index)
        print("(int)index:", index)
        yield index, collection[index]

2 个答案:

答案 0 :(得分:1)

软调试:打印ngram_node和one_node以查看它们包含的内容

脏调试:修改文件“virtenv \ lib \ site-packages \ py2neo \ util.py”,第161行,之前添加一行:

print index

您正在访问一个集合(给定回溯的Python列表),因此,索引必须是一个整数:)

打印它可能会帮助您理解为什么会引发异常

(不要忘记之后删除脏调试;))

答案 1 :(得分:1)

虽然目前WriteBatch个对象可以多次执行并且中间有编辑,但不建议以这种方式使用它们,这将在下一版本的py2neo中受到限制。这是因为在一次执行期间创建的对象在后续执行期间将不可用,并且在请求时不容易检测到。

不回头查看底层代码,我不确定为什么你会看到这个确切的错误,但我建议重构你的代码,以便每个WriteBatch创建与一个且只有一个执行调用配对({{ 1}})。您可以通过将批量创建放在外部循环中并将提交调用从内部循环移动到外部循环中来实现此目的。