我有一个简单的问题-我需要将整数字符串转换为整数列表,然后将其插入numpy数组。
我有可以使用的代码,但是我对一种更有效的方法感兴趣,如果有的话。起始条件是我有一个整数字符串列表(第4行),目标是得到一个用这些整数填充的numpy数组。
这是我使用的代码示例:
import numpy as np
print("Hello StackOverflow")
listOfStringOfINTs = ["123231231231231"]*5
print(listOfStringOfINTs)
numpyVectorOfInts = np.empty([len(listOfStringOfINTs),len(listOfStringOfINTs[0]) ], dtype='int')
for i, IntString in enumerate(listOfStringOfINTs):
numpyVectorOfInts[i] = list(map(int, IntString))
print(numpyVectorOfInts)
答案 0 :(得分:3)
我不确定速度是否会更好,但更简单:
In [68]: np.array([list(astr) for astr in listOfStringOfINTs],int)
Out[68]:
array([[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1]])
list(astr)
将字符串分成1个字符串的列表。 dtype为np.array
的{{1}}负责转换所有字符串。
或者您可以将所有字符串连接到字符串中,列出列表,然后重新排列数组的形状:
int
答案 1 :(得分:2)
利用所有字符串具有相同数量的字符这一事实,我们可以使用带有view
的矢量化字符-
def get_int_ar(a):
return (np.array(a).view('u1')-48).reshape(len(a),-1)
样品运行-
In [143]: listOfStringOfINTs = ["123231231231231"]*5
In [144]: get_int_ar(listOfStringOfINTs)
Out[144]:
array([[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1]], dtype=uint8)
答案 2 :(得分:1)
只是为了娱乐,这是另一种方式:
>>> np.vstack(np.frombuffer(a,dtype=np.uint8)-48 for a in listOfStringOfINTs)
array([[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1],
[1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1]], dtype=uint8)
此方法依赖于以无符号字符的形式读取ASCII字符,然后依赖于数字1-9在ASCII表示中顺序排列的事实。由于数字0表示为48,因此我们只需从所有值中减去48即可得到整数值。
对于较小的字符串,它并没有比@hpaulj的方法更快的可读性:
In [1]: listOfStringOfINTs = ["123231231231231"]*10000
In [2]: %timeit np.vstack(np.frombuffer(a,dtype=np.uint8)-48 for a in listOfStringOfINTs)
10 loops, best of 3: 42.1 ms per loop
In [3]: %timeit np.array([list(astr) for astr in listOfStringOfINTs],int)
10 loops, best of 3: 36.3 ms per loop
但是对于较大的字符串,可以有很大的不同:
In [4]: listOfStringOfINTs = ["123231231231231"*1000]*10000
In [5]: %timeit np.vstack(np.frombuffer(a,dtype=np.uint8)-48 for a in listOfStringOfINTs)
10 loops, best of 3: 115 ms per loop
In [6]: %timeit np.array([list(astr) for astr in listOfStringOfINTs],int)
1 loop, best of 3: 30.4 s per loop
答案 3 :(得分:1)
以上所有答案都是正确的,但直觉上,对我来说最容易理解的是:
>>> k = [list(x) for x in listOfStringOfINTs ]
>>> print(np.array(k, dtype=np.int64))
[[1 2 3 2 3 1 2 3 1 2 3 1 2 3 1]
[1 2 3 2 3 1 2 3 1 2 3 1 2 3 1]
[1 2 3 2 3 1 2 3 1 2 3 1 2 3 1]
[1 2 3 2 3 1 2 3 1 2 3 1 2 3 1]
[1 2 3 2 3 1 2 3 1 2 3 1 2 3 1]]
答案 4 :(得分:0)
这是一个使用"".join
的溶液:
def digit_ize(a):
r = np.fromstring(''.join(a), 'u1')
r &= 0x0f
return r.reshape(len(a), -1)
或(快一点):
def digit_ize(a):
r = np.frombuffer(''.join(a).encode(), 'u1') & 0x0f
return r.reshape(len(a), -1)
时间:
small
pp1 4.314555088058114
pp2 2.933372976258397
div 3.740947926416993
usr 29.473979957401752
hpj 12.974489014595747
large
pp1 9.718517074361444
pp2 7.069707033224404
div 37.66830707900226
usr 2321.8201039126143
hpj 1103.1720889732242
产生时序的脚本,必要时包含其他Soln的Py3调整。
import numpy as np
def digit_ize():
r = np.fromstring(''.join(a), 'u1')
r &= 0x0f
return r.reshape(len(a), -1)
def digit_ize_2():
r = np.frombuffer(''.join(a).encode(), 'u1') & 0x0f
return r.reshape(len(a), -1)
def get_int_ar():
return (np.array(a, 'S').view('u1')-48).reshape(len(a),-1)
def use_vstack():
np.vstack(np.frombuffer(b.encode(), dtype=np.uint8)-48 for b in a)
def use_list():
return np.array([list(astr) for astr in a],int)
from timeit import timeit
listOfStringOfINTs = ["123231231231231"]*5
a = listOfStringOfINTs
print("small")
print("pp1", timeit(digit_ize, number=1000)*1000)
print("pp2", timeit(digit_ize_2, number=1000)*1000)
print("div", timeit(get_int_ar, number=1000)*1000)
print("usr", timeit(use_vstack, number=1000)*1000)
print("hpj", timeit(use_list, number=1000)*1000)
a = a*100
print("large")
print("pp1", timeit(digit_ize, number=1000)*1000)
print("pp2", timeit(digit_ize_2, number=1000)*1000)
print("div", timeit(get_int_ar, number=1000)*1000)
print("usr", timeit(use_vstack, number=1000)*1000)
print("hpj", timeit(use_list, number=1000)*1000)