我正在将多行字符串转换为一个 numpy 数组,如下所示:
names = """
1 2 1
1 1 0
0 1 1
"""
names_list = names.splitlines()
tem = []
for i in [row for row in names_list if row]:
tem.append([col for col in list(i) if col != ' '])
np.array(tem, dtype=np.int)
虽然这段代码有效,但我想知道是否有更有效的方法来做到这一点?
最佳答案
一个答案因未 self 解释而被标记为低质量。但其他三个都没有这样做,它们只是彼此的复制品。
In [227]: names = """
...: 1 2 1
...: 1 1 0
...: 0 1 1
...: """
In [238]: np.genfromtxt(StringIO(names), dtype=int)
Out[238]:
array([[1, 2, 1],
[1, 1, 0],
[0, 1, 1]])
In [239]: timeit np.genfromtxt(StringIO(names), dtype=int)
135 µs ± 286 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
实际上我们不需要StringIO
层;只需将字符串分成几行(有时我们需要一个 format=None
参数):
In [242]: np.genfromtxt(names.splitlines(), dtype=int)
Out[242]:
array([[1, 2, 1],
[1, 1, 0],
[0, 1, 1]])
原始函数比接受的函数快 10 倍:
def orig(names):
names_list = names.splitlines()
tem = []
for i in [row for row in names_list if row]:
tem.append([col for col in list(i) if col != ' '])
return np.array(tem, dtype=np.int)
In [244]: orig(names)
Out[244]:
array([[1, 2, 1],
[1, 1, 0],
[0, 1, 1]])
In [245]: timeit orig(names)
11.1 µs ± 194 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
genfromtxt
基本上做同样的事情 - 拆分行,收集列表列表中的值,然后将其转换为数组。它没有被编译。
标记的答案用 split
方法替换列表理解:
def czisws(names):
names_list = names.splitlines()
tem = []
for i in [row for row in names_list if row]:
tem.append(i.split())
return np.array(tem, dtype=np.int)
In [247]: timeit czisws(names)
8.58 µs ± 274 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
它更快,这不足为奇。 split
是一个字符串方法。内置方法通常更快,并且更可取,即使它们不是。
拆分也更通用:
In [251]: 'abc de f'.split()
Out[251]: ['abc', 'de', 'f']
In [252]: [i for i in list('abc de f') if i!=' ']
Out[252]: ['a', 'b', 'c', 'd', 'e', 'f']
关于python - 有没有更有效的方法将多行字符串转换为 numpy 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55917564/