gpt4 book ai didi

python - 使用numpy的genfromtxt用python加载三角矩阵

转载 作者:行者123 更新时间:2023-12-01 04:21:12 24 4
gpt4 key购买 nike

我有一个文本文件,其中包含上部“三角”矩阵,下部值被省略(下面是一个示例):

3 5 3 5 1 8 1 6 5 8

5 8 1 1 6 2 9 6 4

2 0 5 2 1 0 0 3

2 2 5 1 0 1 0

1 3 6 3 6 1

4 2 4 3 7

4 0 0 1

0 1 8

2 1

1

由于有问题的文件大小约为 10000 行,我想知道是否有一种“智能”方法可以从中生成 numpy 矩阵,例如使用 genfromtxt 函数。但是直接使用它会在以下行上引发错误第 #12431 行(有 6 列,而不是 12437) 和使用 filling_values 将不起作用,因为无法指定无缺失值占位符。

现在我必须手动打开和关闭文件:

import numpy as np
def load_updiag(filename, size):
output = np.zeros((size,size))
line_count = 0
for line in f:
data = line.split()
output[line_count,line_count:size]= data
line_count += 1
return output

我觉得对于大文件来说可能不太可扩展。有没有办法在这样的矩阵上正确使用 genfromtxt (或 numpy 库中的任何其他优化函数)?

最佳答案

您可以将文件中的原始数据读入字符串,然后使用 np.fromstring 获取矩阵上三角部分的一维数组:

with open('data.txt') as data_file:
data = data_file.read()

arr = np.fromstring(data, sep=' ')

或者,您可以定义一个生成器来一次读取文件的一行,然后使用 np.fromiter 从此生成器读取一维数组:

def iter_data(path):
with open(path) as data_file:
for line in data_file:
yield from line.split()

arr = np.fromiter(iter_data('data.txt'), int)

如果您知道矩阵的大小(可以从文件的第一行确定),则可以指定 np.fromitercount 关键字参数这样函数就会预先分配正确数量的内存,这样会更快。这就是这些函数的作用:

def iter_data(fileobj):
for line in fileobj:
yield from line.split()

def read_triangular_array(path):
with open(path) as fileobj:
n = len(fileobj.readline().split())

count = int(n*(n+1)/2)

with open(path) as fileobj:
return np.fromiter(iter_data(fileobj), int, count=count)

这“浪费”了一些工作,因为它打开文件两次来读取第一行并获取条目数。 “改进”是保存第一行并将其与迭代器链接到文件的其余部分,如以下代码所示:

from itertools import chain

def iter_data(fileobj):
for line in fileobj:
yield from line.split()

def read_triangular_array(path):
with open(path) as fileobj:
first = fileobj.readline().split()
n = len(first)
count = int(n*(n+1)/2)
data = chain(first, iter_data(fileobj))
return np.fromiter(data, int, count=count)

所有这些方法都会产生效果

>>> arr
array([ 3., 5., 3., 5., 1., 8., 1., 6., 5., 8., 5., 8., 1.,
1., 6., 2., 9., 6., 4., 2., 0., 5., 2., 1., 0., 0.,
3., 2., 2., 5., 1., 0., 1., 0., 1., 3., 6., 3., 6.,
1., 4., 2., 4., 3., 7., 4., 0., 0., 1., 0., 1., 8.,
2., 1., 1.])

这种紧凑的表示形式可能就是您所需要的,但如果您想要完整的方阵,您可以分配一个正确大小的零矩阵,并使用 np.triu_indices_from< 将 arr 复制到其中,或者您可以使用scipy.spatial.distance.squareform:

>>> from scipy.spatial.distance import squareform
>>> squareform(arr)
array([[ 0., 3., 5., 3., 5., 1., 8., 1., 6., 5., 8.],
[ 3., 0., 5., 8., 1., 1., 6., 2., 9., 6., 4.],
[ 5., 5., 0., 2., 0., 5., 2., 1., 0., 0., 3.],
[ 3., 8., 2., 0., 2., 2., 5., 1., 0., 1., 0.],
[ 5., 1., 0., 2., 0., 1., 3., 6., 3., 6., 1.],
[ 1., 1., 5., 2., 1., 0., 4., 2., 4., 3., 7.],
[ 8., 6., 2., 5., 3., 4., 0., 4., 0., 0., 1.],
[ 1., 2., 1., 1., 6., 2., 4., 0., 0., 1., 8.],
[ 6., 9., 0., 0., 3., 4., 0., 0., 0., 2., 1.],
[ 5., 6., 0., 1., 6., 3., 0., 1., 2., 0., 1.],
[ 8., 4., 3., 0., 1., 7., 1., 8., 1., 1., 0.]])

关于python - 使用numpy的genfromtxt用python加载三角矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33675624/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com