【问题标题】:Complex Data Manipulation in PythonPython中的复杂数据操作
【发布时间】:2014-08-28 11:44:02
【问题描述】:

我有 3 个文件,其中包含真实数据和伪数据以及真实数据的值。

File_one 有两列,一列是真实数据,第二列是平移数据。 IE。对于真实数据,会给出一个伪值。

col[0] col[1]
123     0
234     1
345     2
456     3
567     4
678     5

File_two 具有成对的伪值,即代替 123,使用的值是 0,伪值对的方式与 [0, 1] 相同,这意味着实际的 [123, 234]

col[0]  col[1]
0        2
0        3
0        5
2        4
5        1

所以可以说file_two中的col[0] and col[1]是键,值在file_onecol[0]

现在我必须将file_two 中的伪值对与file_one 中的真实数据col[0] 进行匹配,并将输出保存到新文件中。我们将其命名为file_four。这里对只出现ONE时间。

col[0]  col[1]
123     345
123     456
123     678
345     567
678     234

现在file_three 出现了。 File_three 有 3 列。

col[0]col[1]file_four 中的对相同,但它们还有许多其他对在 file_four 中不存在。

文件_三个

col[0]  col[1]  col[2]
123     345       54
345     262       65
123     456       54
2456    2467      98
123     678       46
7845    2458      631
345     567       153
3456    3673      94
678     234       5

最后,我需要匹配file_four 对,即col[0] col[1] 并从file_three 中的col[2] 中提取值,并生成一个新的output_file,其中file_four 对作为键和值在col[2]file_three 中。

在下面的代码中,我试图只考虑前两个文件

from collections import defaultdict

d1 = dict()
d2 = dict()

with open('input1.txt', 'r') as file1:
    for row in file1:
        c0, c1 = row.split()[:2]
        d1[c1] = c0
with open('input2.txt', 'r') as file2:
    for row in file2:
        c0, c1 = row.split()[:2]
        d2[(c0, c1)] = [d1[c1], d1[c1]]

#for k, v in sorted(d2.items()):
    #print '\t'.join(v)
print d2

Error:

Key Error: 'key' 

即使没有注释 for 循环并且注释了最后一个打印,也会出现相同的错误。

【问题讨论】:

  • 这里发布错误时,最好发布完整的 Traceback。当您尝试从不存在的字典中检索某些内容时,会出现KeyError。当试图弄清楚这样的事情时,打印语句可以提供很大帮助。将语句包装在 Try/Except 块中并打印有问题的值,也许还有字典。在拆分之前,您可能需要从每行中去除空格。你可能想花一些时间在文档中的教程上,也许greenteapress.com/thinkpython

标签: python file dictionary multiple-columns


【解决方案1】:

您没有匹配的键,因为 d1 包含对作为键,而 d2 包含单个值。

这行好像错了:

    key =  col[0], col[1]

【讨论】:

  • 输入 file1 有一对键,这些键在 file2 中只有一列的值,我需要成对的输出为[value_of_K1 value_of_K2]
【解决方案2】:

对于d1,使用 file1 的第 1 列作为键,使用第 0 列作为创建查找表的值:

f1 = [(123,0),(234,1),(345,2),(456,3),(567,4),(678,5)]
f2 = [(0,2),(0,3),(0,5),(2,4),(5,1)]

d1 = {c1:c0 for c0,c1 in f1}

这允许您使用 file2 列值来查找d1中的值

d2 = {(c0, c1):[d1[c0], d1[c1]] for c0, c1 in f2}
print d2

>>>
{(5, 1): [678, 234], (0, 3): [123, 456], (0, 5): [123, 678], (0, 2): [123, 345], (2, 4): [345, 567]}
>>>

重构文件 1 和文件 2 的代码

d1, d2 = dict(), dict()
with open('inputfile1.txt', 'r') as file1:
    for row in file1:
        c0, c1 = row.strip().split()[:2]
        d1[c1] = c0

with open('inputfile2.txt', 'r') as file2:
    for row in file2:
        c0, c1 = row.strip().split()[:2]
        d2[(c0, c1)] = [d1[c0], d1[c1]]

>>> for k, v in sorted(d2.items()):
    print '\t'.join(v)


123 345
123 456
123 678
345 567
678 234
>>> 

在赋值期间解包值/项目:

>>> 
>>> x, y, z = [1, 2, 3]
>>> print x, y, z
1 2 3
>>> x, y = [1, 2, 3]

Traceback (most recent call last):
  File "<pyshell#259>", line 1, in <module>
    x, y = [1, 2, 3]
ValueError: too many values to unpack
>>> 
>>> a, b, _, _, _, _ = '1 2 3 4 5 6'.split()
>>> print a, b, _
1 2 6
>>> 

【讨论】:

  • 这看起来很棒,而且比我想写的要简单得多。但我收到一个错误:c0, c1 = row.split()ValueError: too many values to unpack
  • 如果文件多于两列,就会出现该异常。我假设您的文件(#1和#2)是结构化的 - 值空白值。如果row.split() 导致两个以上的项目,那么您可能需要重构并索引到结果列表中,或者确保分配左侧有足够的 names 来说明所有项目在row.split()
  • 该文件还有其他列,但我们不必考虑它们。所以我没有提到只是为了避免混淆。
  • 有几种方法可以解决这个问题。如果您使用的是 Python 3.x,您可以使用扩展解包 -> a, b, *c = [1, 2, 3, 4, 5, 6]PEP 3132。您可以直接从row.split() 索引您需要的项目。请参阅第三个选项的编辑。
  • 在阅读并尝试跟踪代码时,它完全正确,但我遇到了关键错误。代码已更新。
猜你喜欢
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 2011-06-25
相关资源
最近更新 更多