0

我正在尝试将节点批量导入 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是一个奇数。)这个float 然后抛出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()的代码来规避代码(可能的加速?)虽然我没有对此进行单元测试,但似乎我们可以安全地将 index 转换为 int ...

使用的 pendulate 函数:

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]
4

2 回答 2

1

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

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

于 2014-01-10T07:21:56.680 回答
1

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

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

print index

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

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

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

于 2014-01-09T22:49:24.460 回答