如何将每行列数可变的 txt 文件中的数据加载到 numpy 数组中?

How to load data from a txt file with variable number of columns in each row into a numpy array?

我的数据文件如下所示:

我想将此数据加载到一个 numpy 数组中。我该怎么做?

如果我使用 loadtxt(filename),它给出错误:

raise ValueError(errmsg)
ValueError: Some errors were detected !

如果我使用 genfromtxt(filename, delimiter=" "),它会给出相同的错误,即使这应该可以修复它。

如果我使用以下内容:

from array import array
N=84 # max number of columns in any row in the data file
with open('C:/Users/hp1/Desktop/ClusterAnalysis/hierarchical_result.txt',"r") as f:
        all_data=[x.split() for x in f.readlines()]
        a=array([map(int,x) for x in all_data[:N]])

我收到这个错误:

TypeError: array() argument 1 must be a unicode character, not list

编辑: 这是数据文件中的所有数据:

61 81
2 28
13 31
59 64
36 63
45 58
3 73
47 51
33 68
1 72
12 84
3 73 12 84
1 72 3 73 12 84
6 83
27 42
66 6 83
54 77
60 54 77
39 40
10 19
49 79
22 76
61 81 60 54 77
65 61 81 60 54 77
8 65 61 81 60 54 77
66 6 83 8 65 61 81 60 54 77
71 47 51
18 25
59 64 18 25
32 59 64 18 25
11 34
20 26
27 42 20 26
69 27 42 20 26
16 62
43 16 62
30 45 58
85 30 45 58
56 85 30 45 58
17 11 34
22 76 32 59 64 18 25
29 39 40
14 57
44 14 57
7 24
78 2 28
15 37
70 15 37
48 70 15 37
80 29 39 40
4 9
75 43 16 62
13 31 75 43 16 62
74 13 31 75 43 16 62
36 63 17 11 34
53 36 63 17 11 34
46 1 72 3 73 12 84
23 52
38 66 6 83 8 65 61 81 60 54 77
82 38 66 6 83 8 65 61 81 60 54 77
10 19 56 85 30 45 58
33 68 10 19 56 85 30 45 58
5 49 79
78 2 28 4 9
55 80 29 39 40
67 55 80 29 39 40
7 24 67 55 80 29 39 40
35 48 70 15 37
69 27 42 20 26 35 48 70 15 37
41 82 38 66 6 83 8 65 61 81 60 54 77
50 69 27 42 20 26 35 48 70 15 37
33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37
46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
44 14 57 74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
5 49 79 44 14 57 74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
71 47 51 5 49 79 44 14 57 74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
23 52 71 47 51 5 49 79 44 14 57 74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77
21 23 52 71 47 51 5 49 79 44 14 57 74 13 31 75 43 16 62 78 2 28 4 9 53 36 63 17 11 34 7 24 67 55 80 29 39 40 50 69 27 42 20 26 35 48 70 15 37 22 76 32 59 64 18 25 46 1 72 3 73 12 84 33 68 10 19 56 85 30 45 58 41 82 38 66 6 83 8 65 61 81 60 54 77

numpy.genfromtxt 不处理变长行。你应该自己解析你txt

无需使用 array 如下 Python 3.x

import numpy as np
N = 84 # max number of columns in any row in the data file
with open('C:/Users/hp1/Desktop/ClusterAnalysis/hierarchical_result.txt',"r") as f:
        all_data = [x.split() for x in f.readlines()]
        output = np.array([list(map(int,x))[:N] for x in all_data])
In [306]: with open('stack44755004.txt') as f:
     ...:     lines = f.readlines()
     ...:     
In [307]: strs = [line.split() for line in lines]
In [308]: strs
Out[308]: [['61', '81'], ['2', '28'], ['13', '31'], ['3', '73', '12', '84'], ['6', '83']]
In [309]: nums = [[int(i) for i in line.split()]for line in lines]
In [310]: nums
Out[310]: [[61, 81], [2, 28], [13, 31], [3, 73, 12, 84], [6, 83]]

nums 是数字列表的列表。无法将其变成二维数组。

但是用普通的 read 我得到一个带有换行符的字符串:

In [311]: with open('stack44755004.txt') as f:
     ...:     alldata = f.read()

In [312]: alldata
Out[312]: '61 81\n2 28\n13 31\n3 73 12 84\n6 83\n'

split 将其视为 space,因此我得到了一个字符串列表:

In [313]: alldata.split()
Out[313]: ['61', '81', '2', '28', '13', '31', '3', '73', '12', '84', '6', '83']

np.array 可以将其转换为整数数组

In [314]: np.array(alldata.split(),int)
Out[314]: array([61, 81,  2, 28, 13, 31,  3, 73, 12, 84,  6, 83])

此方法会丢失所有行信息。这重要吗?

有多种方法可以将 nums 转换为数组。例如,它可以写入零填充数组。但如果你不知道自己想要什么,我不确定这是否值得。


有各种 padding 问题。我最记得的一个工具是 itertools.zip_longest(Python3 版本):

Out[317]: <itertools.zip_longest at 0xa9c46194>
In [318]: list(itertools.zip_longest(*nums, fillvalue=0))
Out[318]: [(61, 2, 13, 3, 6), (81, 28, 31, 73, 83), (0, 0, 0, 12, 0), (0, 0, 0, 84, 0)]
In [319]: np.array(_)
Out[319]: 
array([[61,  2, 13,  3,  6],
       [81, 28, 31, 73, 83],
       [ 0,  0,  0, 12,  0],
       [ 0,  0,  0, 84,  0]])
In [320]: _.T
Out[320]: 
array([[61, 81,  0,  0],
       [ 2, 28,  0,  0],
       [13, 31,  0,  0],
       [ 3, 73, 12, 84],
       [ 6, 83,  0,  0]])

我已使用 pandas 解决该问题,您可以在其中指定所需的列。如果一列的列数较少,它们将被设置为 NaN。 您必须知道最大列数,但这很容易使用 readlines、split 和列表理解来检测。

如果你想用最大列数填充每一行,你必须自己实现。大意:

import numpy as np

def pad_list(lst, padding, default=0):
    return lst + (padding - len(lst))*[default]

N = 84 # max number of columns in any row in the data file
with open('/path/to/file',"r") as f:
        all_data=(map(int, x.split()) for x in f)
        a = np.array([pad_list(list(x), N) for x in all_data])

但是,对于这个给你一个数字而不是对象类型的数组,你需要知道实际的最大列数。所以要小心弄清楚。