Python_如何解析数据并将其转换为新文件
这里是input.txt文件Python_如何解析数据并将其转换为新文件,python,parsing,dictionary,Python,Parsing,Dictionary,这里是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) 键是两个值,从输入文件的第1列字符串中用“u”分隔。2) 此外,如果列和行的名称相同(例如Jan和Jan),则按如下所示编写0.0。3) 最后,如果在字典中找不到键,
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) 键是两个值,从输入文件的第1列字符串中用“u”分隔。2) 此外,如果列和行的名称相同(例如Jan和Jan),则按如下所示编写0.0。3) 最后,如果在字典中找不到键,请写“NA”。Output.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
如果有人能帮我弄清楚,我将不胜感激实际上,real input.txt中大约有100000000行*2列。我的名字提前非常感谢你
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
现在,在矩阵中,您有了您想要的表格。1)确定结果列/行的所有可能标题。在你的例子中,这是A-D。你如何做到这一点可能会有所不同。您可以解析文件2x(不理想,但可能是必要的),或者您可以在某个地方参考不同的列
2) 建立标题。在上面的示例中,您将有头=[“A”、“B”、“C”、“D”]。如果必须解析第一列,则可以在#1期间构建此函数。使用len(索引)确定N
< P> 3)解析数据,这一次考虑两列。您将使用第一列上的.split(“389;”)获取两个键,然后通过执行简单的算术运算获取数据的索引:
x,y = [headers.index(a) for a in row[0].split("_")]
data[x+y*len(headers)] = row[1]
这应该比较快,除了两次解析文件。如果它可以放入内存,您可以将文件加载到内存中,然后扫描两次,或者使用命令行技巧建立这些头条目
--我应该说,在开始存储实际数据之前,需要确定N。(即数据=[0]*N)。此外,在保存过程中还需要使用x+y*len(标题)。如果您使用的是numpy,则可以使用“重塑”来获得实际的行/列布局,这将更易于操作和打印(即数据[x,y]=行[1])
如果你做了大量的大数据操作,特别是如果你可能正在执行计算,你真的应该学习numpy(www.numpy.org) 如果你想要一本字典,可以这样:
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"
其他人可能不同意这一点,但一种解决方案是使用与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亿张唱片了。将它们全部读入内存也可能有问题。通过这种方式,您可以一次构造一行矩阵,并将该行输出到文件中
它可能不是最快的,但它可能是非常清晰和直接的代码。考虑到您输入的大小,我会在您的文件中将其分为几个过程:
识别标题的第一步(在所有行上循环,读取第一组,查找标题)
再次读取该文件以查找要放入矩阵中的值。有几种选择
- 最简单(但速度较慢)的选择是为矩阵的每一行读取整个文件,只识别文件中需要的行。这样,一次内存中只有一行矩阵
- 从您的示例文件来看,您的输入文件似乎已正确排序。如果不是,则对其进行排序是一个好主意。这样,您就知道您正在读取的输入文件中的行是矩阵中的下一个单元格(当然,除了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'])
然后,您需要做的是创建从标题
到值的映射,这些值存储在数据
中。理想情况下,您需要创建一个表。请看一下答案,以帮助您了解如何做到这一点(我们无法为您编写代码)
其次,为了正确地打印出来,您需要使用该方法。理想情况下,它将帮助您处理字符串,并以特定方式打印它们
之后,您可以简单地使用open('output.txt','w')
这样写,您是否预先知道列的名称?名称本身就是gene的名称。大多数是由字符(例如VCL)组成的,但有些是由字符和数字(例如p53)组成的。长度也各不相同。如果有100万行,字典可能会非常慢。特别是如果你用字符串作为键(如更新的问题中所示),那么表显然是100000000个单元格。我不明白为什么你认为字典相对于你的建议会慢一些。如果标题长度约为10000个元素,headers.index(a)
将比索引到字典中慢得多。实际上,你买的只是内存,我承认,内存是数据大小的一个问题。也许你是对的。我不知道字典是如何索引的,也不知道索引是如何工作的(如果每次都创建一棵树,那就不好了)。如果它是一个真正的散列,那么它可能会更快,我可能错了,但根据我的经验,大型双字典似乎速度非常慢。在Python中,您要做的是使用一个字典(这是一个散列映射)并使用一个2元组(左,右)
作为键.index
执行线性搜索。非常感谢您。我对Python还是新手。您能让我进一步了解如何1)将标题映射为值并创建表,2)以字符串格式打印出来吗?我确实在我的文件中定义了值和头,但不幸的是,我不能再进一步了。