0

这是 input.txt 文件

Jan_Feb    0.11
Jan_Mar   -1.11
Jan_Apr    0.2
Feb_Jan    0.11
Feb_Mar   -3.0
Mar_Jan   -1.11
Mar_Feb   -3.0
Mar_Apr    3.5

从这个文件中,我试图从输入文本文件中创建一个字典。1)键是两个值,从输入文件的第一列字符串中用“_”分割。2)另外,如果列名和行名相同(如Jan和Jan),写0.0如下。3)最后,如果在字典中没有找到键,写“NA”。输出.txt

         Jan     Feb       Mar      Apr
 Jan     0.0     0.11     -1.11     0.2
 Feb     0.11    0.0      -3.0      NA
 Mar    -1.11    -3.0      0.0      3.5    
 Apr     0.2     NA        3.5      0.0

如果有人能帮我弄清楚,我将不胜感激。
实际上,实际 input.txt 中大约有 100,000,000 行 * 2 列。提前谢谢你的名字。

4

6 回答 6

1

其他人可能不同意这一点,但一种解决方案是split使用与 MySQL 或 SQLite 接口的模块将所有 1 亿行读入关系数据库表(当然,适当地找出你需要的内容):

Your_Table:
    ID
    Gene_Column
    Gene_Row
    Value

一旦它们在那里,您可以用类似于英语的方式查询该表:

获取所有列标题:

select distinct Gene_Column from Your_Table order by Gene_Column asc

获取特定行的所有值,以及它们所在的列:

select Gene_Column, Value from Your_Table where Gene_Row = "Some_Name"

获取特定单元格的值:

select Value from Your_Table where Gene_Row = "Some_Name" and Gene_Column = "Another_Name"

那,你真的不想洗牌大约 1 亿条记录,而不是你必须做的。将它们全部读入内存也可能有问题。这样做,您可以一次构造一行矩阵,并将该行输出到您的文件。

它可能不是最快的,但它可能是非常清晰和直接的代码。

于 2013-10-30T19:12:35.003 回答
0
matrix = dict()
with open('inpu.txt') as f:
   content = f.read()
   tmps = content.split('\n')
   for tmp in tmps:
     s = tmp.split(' ')
     latter = s[0].split('_')
     try:
       if latter[0] in matrix:
         matrix[latter[0]][latter[1]] = s[1]
       else:
         matrix[latter[0]] = dict()
         matrix[latter[0]][latter[1]] = s[1]
     except:
       pass
print matrix

现在在矩阵中你有你想要的表格。

于 2013-10-30T18:57:54.480 回答
0

1) 确定结果列/行的所有可能标题。在您的示例中,这就是 AD。你如何做到这一点可能会有所不同。您可以解析文件 2x(不理想,但可能有必要),或者您可能有某个地方可以参考不同的列。

2) 建立标题。在上面的示例中,您将有 headers=["A","B","C","D"]。如果您必须解析第一列,您可以在 #1 期间构建它。使用 len(indexes) 确定 N

3)解析数据,这次考虑两列。您将在第一列上使用 .split("_") 获得两个键,然后通过简单的算术获得数据的索引:

x,y = [headers.index(a) for a in row[0].split("_")]
data[x+y*len(headers)] = row[1]

这应该是比较快的,除了文件的两次解析。如果它可以放入内存,您可以将文件加载到内存中,然后对其进行两次扫描,或者使用命令行技巧来建立这些标题条目。

-- 我应该说你需要在开始存储实际数据之前确定 N。(即数据=[0]*N)。此外,您还需要在保存期间使用 x+y*len(headers) 。如果您使用的是 numpy,则可以使用 reshape 来获得实际的行/列布局,这将更容易操作和打印(即 data[x,y]=row[1])

如果您进行大量大型数据操作,特别是如果您可能正在执行计算,您真的应该考虑学习 numpy (www.numpy.org)。

于 2013-10-30T19:05:11.803 回答
0

如果你想要一本字典,就像这样:

dico = {}
keyset=set()
with open('input.txt','r') as file:
    line = file.readline()
    keys = line.split('\t')[0]
    value = line.split('\t')[1]
    key1 = keys.split('_')[0]
    keyset.add(key1)
    key2 = keys.split('_')[1]
    keyset.add(key2)

    if key1 not in dico:
        dico[key1] = {}
    dico[key1][key2] = value

for key in keyset:
    dico[key][key] = 0.0
    for secondkey in keyset:
        if secondkey not in dico[key].keys():
            dico[key][secondkey]="NA" 
于 2013-10-30T19:06:32.153 回答
0

鉴于您输入的大小,我将在您的文件中将其拆分为几遍:

  1. 首先通过识别标题(循环所有行,读取第一组,找到标题)
  2. 再次阅读文件以找到要放入矩阵的值。有几种选择。

    • 最简单(但速度较慢)的选项是读取矩阵每一行的整个文件,仅识别文件中需要的行。这样,您一次只有一行矩阵在内存中
    • 从您的示例文件中,您的输入文件似乎已正确排序。如果不是,最好对其进行排序。这样,您就知道您正在读取的输入文件中的行是矩阵中的下一个单元格(当然除了您只需要添加的 0 对角线。)
于 2013-10-30T19:16:37.907 回答
0

您首先需要做的是以可理解的格式获取数据。因此,首先,您需要创建一行。我会得到这样的数据:

with open('test.txt') as f:
    data = [(l.split()[0].split('_'), l.split()[1]) for l in f]
    # Example:
    # [(['Jan', 'Feb'], '0.11'), (['Jan', 'Mar'], '-1.11'), (['Jan', 'Apr'], '0.2'),                   (['Feb', 'Jan'], '0.11'), (['Feb', 'Mar'], '-3.0'), (['Mar', 'Jan'], '-1.11'), (['Mar', 'Feb'], '-3.0'), (['Mar', 'Apr'], '3.5')]
    headers = set([var[0][0] for var in data] + [var[0][1] for var in data])
    # Example:
    # set(['Jan', 'Apr', 'Mar', 'Feb'])

然后您需要做的是创建一个从您headers的值到您的值的映射,这些值存储在data. 理想情况下,您需要创建一个表。看看这个答案,以帮助您弄清楚如何做到这一点(我们无法为您编写代码)。

其次,为了正确打印内容,您需要使用该format方法。理想情况下,它将帮助您处理字符串,并以特定方式打印它们。

之后,您可以使用open('output.txt', 'w').

于 2013-10-30T19:25:21.923 回答