将三列文本文件转换为矩阵

1 投票
3 回答
3407 浏览
提问于 2025-04-16 01:25

你好,我想把一个用制表符分隔的文件转换成这样的格式:

Species Date Data
1       Dec   3 
2       Jan   4
2       Dec   6
2       Dec   3

然后变成一个像这样的矩阵(物种是行的标题):

    1  2
Dec 3  9
Jan    4

我猜解决这个问题的一部分是创建一个字典,里面有两个键,并使用defaultdict来给这个键对添加新值。我想把这个结果输出成制表符分隔的格式,同时也希望能转换成可以用scipy的聚类功能的格式。

3 个回答

1

我对 numpy 不太了解,所以只能提供部分帮助。不过我觉得写这个小代码片段挺有意思的,所以就分享一下用 defaultdict 的写法:

# we'll pretend *f* is a file below
f = '''Species Date Data
1       Dec   3 
2       Jan   4
2       Dec   6
2       Dec   3'''.split('\n')[1:]

from collections import defaultdict

d = defaultdict(int)
for ln in f:
    x,y,n = ln.split()
    d[x,y] += int(n)

# transpose the list of tuples (keys) to get the two dimensions, remove the duplicates
x,y = map(set, zip(*d))

print list(x)
for yy in y:
    print yy, [d[xx,yy] for xx in x]

运行这个代码的结果是

['1', '2']
Jan [0, 4]
Dec [3, 9]

挺可爱的,对吧?

2

用pandas处理这个问题非常简单。你可以使用read_table()来读取你的文本文件,不过我在下面手动创建了一个数据框。

from pandas import DataFrame    
#create the data frame
df = DataFrame({'Species' : [1,2,2,2],
     'Date' : ['Dec','Jan', 'Dec', 'Dec'],
     'Data' : [3,4,6,3]} )

#group by the Date and Species columns, and take the sume of the Data column
df2 = df.groupby(['Date','Species'])['Data'].sum()

# unstack the Species Column to reshape your data
df2.unstack('Species')
2

库中,DataFrame对象让这件事变得很简单。

import csv
from collections import defaultdict
from pandas import DataFrame

rdr = csv.reader(open('mat.txt'), delimiter=' ', skipinitialspace=True)
datacols = defaultdict(list)

# skip header
rdr.next()
for spec, dat, num in rdr:
    datacols['species'].append(int(spec))
    datacols['dates'].append(dat)
    datacols['data'].append(int(num))

df = DataFrame(datacols)
df2 = df.pivot(index='dates', columns='species', values='data')

首先,我们从你提供的文件中读取数据。接着,我们需要构建一个列的字典(datacol),因为这正是DataFrame所需要的。一旦构建好DataFramedf),就可以调用它的pivot方法,把数据转换成你想要的格式。下面是dfdf2在控制台中的样子:

In [205]: df
Out[205]:
     data           dates          species
0    3              Dec            1
1    4              Jan            2
2    6              Dec            2
3    3              Dec            2


In [206]: df2
Out[206]:
       1              2
Dec    3              3
Jan    NaN            4

然后,你可以使用toCSV方法把它保存到一个文件中(具体可以参考之前提到的DataFrame文档)。

撰写回答