我有一个如下所示的数据集:
# sparse.txt
1 1:1 2:1 3:1
0 1:1 4:1
1 12:1 13:1 14:1
我想创建一个没有冒号的矩阵,如下所示:
# sparse2.txt
1 1 1 2 1 3 1
0 1 1 4 1
1 2 1 3 1 4 1
我使用在线python正则表达式来查找正则表达式模式来读取文件的行。 https://pythex.org/
我使用了模式:
pat = [0-1]\s+([0-9]:1\s*)+
哪个满足在线regexer中的正则表达式,但是,当我在np.fromregex中使用它时 它不起作用。
import numpy as np
pat = r'[0-1]\s+([0-9]:1\s*)+'
data = np.fromregex('sparse.txt', pat, dtype='str')
print("data = {}".format(data))
我们如何修复错误?
答案 0 :(得分:0)
<强> [0-1]\s+([0-9]:1\s*)+
强>
import numpy as np
pat = r'^\d|[^0-9\:\n][\d]?'
data = np.fromregex('sparse.txt', pat, [('num', np.int64)])
print("data = {}".format(data))
numpy.fromregex
官方参考link 答案 1 :(得分:0)
使用@ Wiktor的模式
In [58]: pat1 = r'([0-1])\s+([0-9]):(1)\s+([0-9]):(1)(?:\s+([0-9]):(1))?'
In [59]: np.fromregex('stack47266965.txt', pat1, dtype='str')
Out[59]:
array([['1', '1', '1', '2', '1', '3', '1'],
['0', '1', '1', '4', '1', '', ''],
['1', '2', '1', '3', '1', '4', '1']],
dtype='<U1')
这是一个dd字符串的二维数组(这里是unicode);注意第二行短的填充。这是由模式的?:
部分产生的。
fromregex
执行re.findall
并将该元组列表转换为数组:
In [60]: re.findall(pat1, open('stack47266965.txt').read())
Out[60]:
[('1', '1', '1', '2', '1', '3', '1'),
('0', '1', '1', '4', '1', '', ''),
('1', '2', '1', '3', '1', '4', '1')]
请注意,fromregex
文档强调它返回structured array
。该元组列表可以是np.array(seq, dtype=dt)
的正确输入,其中dt
是复合dtype。每个元组应该具有相同的长度,一个与dtype
匹配。
此案例表明它适用于像str
这样的简单dtype。但这对你有什么用呢。你不能将这些字符串转换为数字,而不会以某种方式过滤空白。没有空白,阵列不能再是2d。那条短的中间线阻止了这一点。
numpy
中的文本文件读取器旨在逐行读取文件,将每个文件解析为2d数组的行或1d结构化数组的记录。不规则的线长是一个问题,需要某种填充。
@ XetRAFHan的模式会提取您想要的所有数字,但会丢失行结构:
In [93]: pat2 = r'^\d|[^0-9\:\n][\d]?'
In [94]: re.findall(pat2, open('stack47266965.txt').read())
Out[94]: ['1', ' 1', ' 2', ' 3', ' 1', ' 4', ' 2', ' 3', ' 4']
您在保留文件结构之前所做的拆分
Create dense matrix from sparse matrix efficently (numpy/scipy but NO sklearn)
In [95]: lines = open('stack47266965.txt').readlines()
In [96]: lines
Out[96]: ['1 1:1 2:1 3:1\n', '0 1:1 4:1\n', '1 2:1 3:1 4:1\n']
In [97]: alist = []
In [98]: for line in lines:
...: row = line.split()
...: label = int(row[0])
...: values = [int(a.split(':')[0]) for a in row[1:]]
...: alist.append((label, values))
...:
In [99]: alist
Out[99]: [(1, [1, 2, 3]), (0, [1, 4]), (1, [2, 3, 4])]