题主需要将 input.txt 文件中的数据解析并生成一个新的 output.txt 文件。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
题主希望将这些数据解析成一个字典,其中:
- 键是第一列字符串中用 "_" 分割的两个值。
- 如果列名和行名相同(如 Jan 和 Jan),则将值写为 0.0。
- 如果键在字典中未找到,则写为 "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
由于实际的 input.txt 文件中有约 1 亿行 * 2 列的数据,因此需要一种高效且可扩展的解决方案。
2、解决方案
一种可能的解决方案是将数据读入关系型数据库表中,然后使用 SQL 查询构建所需的字典。具体步骤如下:
- 使用一个与 MySQL 或 SQLite 接口的模块,将所有 1 亿行数据读入一个名为 Your_Table 的表中。在读入时,将需要的数据拆分出来,如列名、行名和值。
- 在表中创建适当的索引,以提高查询速度。
- 使用 SQL 查询构建所需的字典。例如,要获取所有列标题,可以使用以下查询:
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"
- 将查询结果以所需的形式输出到 output.txt 文件中。
这种方法的好处是,它可以将所有数据存储在数据库中,并使用 SQL 查询对其进行高效处理。缺点是,它需要安装和配置数据库,并且可能需要学习一些 SQL 知识。
代码示例:
import sqlite3
import csv
# 连接到数据库
conn = sqlite3.connect('matrix.db')
c = conn.cursor()
# 创建表
c.execute('''CREATE TABLE IF NOT EXISTS Your_Table (
ID INTEGER PRIMARY KEY,
Gene_Column TEXT,
Gene_Row TEXT,
Value REAL
)''')
# 将数据读入表中
with open('input.txt', 'r') as f:
reader = csv.reader(f, delimiter='\t')
for row in reader:
c.execute("INSERT INTO Your_Table (Gene_Column, Gene_Row, Value) VALUES (?, ?, ?)", row)
# 创建索引
c.execute("CREATE INDEX idx_Gene_Column ON Your_Table (Gene_Column)")
c.execute("CREATE INDEX idx_Gene_Row ON Your_Table (Gene_Row)")
# 获取所有列标题
columns = [row[0] for row in c.execute("SELECT DISTINCT Gene_Column FROM Your_Table ORDER BY Gene_Column ASC")]
# 创建输出文件
with open('output.txt', 'w') as f:
# 写入表头
f.write(' ' * 9)
for column in columns:
f.write('{:>9}'.format(column))
f.write('\n')
# 写入数据
for row in columns:
f.write('{:>3}'.format(row))
for column in columns:
value = c.execute("SELECT Value FROM Your_Table WHERE Gene_Row = ? AND Gene_Column = ?", (row, column)).fetchone()
f.write('{:>9}'.format(value[0] if value else 'NA'))
f.write('\n')
# 关闭数据库连接
conn.close()