字节数组numpython2与python3
我需要生成以下形式的元组:(string,string)或(string,int) 我有以下代码,在Python2中似乎运行良好,但在Python3中没有返回所需的结果(在Python3.5上测试): 在Python 2中,结果是:字节数组numpython2与python3,python,python-3.x,numpy,numpy-random,Python,Python 3.x,Numpy,Numpy Random,我需要生成以下形式的元组:(string,string)或(string,int) 我有以下代码,在Python2中似乎运行良好,但在Python3中没有返回所需的结果(在Python3.5上测试): 在Python 2中,结果是: Generate 10 lines 10 lines generated 0 : ('zvtMIBpQZhjpyqt', '63') 1 : ('mVMkbqBHetqEJdc', '70') 2 : ('uWAwOYIBwzyDdhR', '54') 3 : ('
Generate 10 lines
10 lines generated
0 : ('zvtMIBpQZhjpyqt', '63')
1 : ('mVMkbqBHetqEJdc', '70')
2 : ('uWAwOYIBwzyDdhR', '54')
3 : ('WZvXdFYewrOIYfp', '90')
4 : ('uzszDaTwajsADag', '37')
5 : ('HmBSpSBbQeOixII', '88')
6 : ('VACSDjDtQqqjPWh', '84')
7 : ('XiZJbYQkgpgohMJ', '93')
8 : ('JiFSbeUBYtqhXQk', '93')
9 : ('xLuBXBGYPTogDwo', '41')
在Python 3.5中,结果如下所示:
Generate 10 lines
10 lines generated
0 : (b'z\x00\x00\x00v\x00\x00\x00t\x00\x00\x00M\x00\x00\x00I\x00\x00\x00B\x00\x00\x00p\x00\x00\x00Q\x00\x00\x00Z\x00\x00\x00h\x00\x00\x00j\x00\x00\x00p\x00\x00\x00y\x00\x00\x00q\x00\x00\x00t\x00\x00\x00', '63')
1 : (b'm\x00\x00\x00V\x00\x00\x00M\x00\x00\x00k\x00\x00\x00b\x00\x00\x00q\x00\x00\x00B\x00\x00\x00H\x00\x00\x00e\x00\x00\x00t\x00\x00\x00q\x00\x00\x00E\x00\x00\x00J\x00\x00\x00d\x00\x00\x00c\x00\x00\x00', '70')
2 : (b'u\x00\x00\x00W\x00\x00\x00A\x00\x00\x00w\x00\x00\x00O\x00\x00\x00Y\x00\x00\x00I\x00\x00\x00B\x00\x00\x00w\x00\x00\x00z\x00\x00\x00y\x00\x00\x00D\x00\x00\x00d\x00\x00\x00h\x00\x00\x00R\x00\x00\x00', '54')
3 : (b'W\x00\x00\x00Z\x00\x00\x00v\x00\x00\x00X\x00\x00\x00d\x00\x00\x00F\x00\x00\x00Y\x00\x00\x00e\x00\x00\x00w\x00\x00\x00r\x00\x00\x00O\x00\x00\x00I\x00\x00\x00Y\x00\x00\x00f\x00\x00\x00p\x00\x00\x00', '90')
4 : (b'u\x00\x00\x00z\x00\x00\x00s\x00\x00\x00z\x00\x00\x00D\x00\x00\x00a\x00\x00\x00T\x00\x00\x00w\x00\x00\x00a\x00\x00\x00j\x00\x00\x00s\x00\x00\x00A\x00\x00\x00D\x00\x00\x00a\x00\x00\x00g\x00\x00\x00', '37')
5 : (b'H\x00\x00\x00m\x00\x00\x00B\x00\x00\x00S\x00\x00\x00p\x00\x00\x00S\x00\x00\x00B\x00\x00\x00b\x00\x00\x00Q\x00\x00\x00e\x00\x00\x00O\x00\x00\x00i\x00\x00\x00x\x00\x00\x00I\x00\x00\x00I\x00\x00\x00', '88')
6 : (b'V\x00\x00\x00A\x00\x00\x00C\x00\x00\x00S\x00\x00\x00D\x00\x00\x00j\x00\x00\x00D\x00\x00\x00t\x00\x00\x00Q\x00\x00\x00q\x00\x00\x00q\x00\x00\x00j\x00\x00\x00P\x00\x00\x00W\x00\x00\x00h\x00\x00\x00', '84')
7 : (b'X\x00\x00\x00i\x00\x00\x00Z\x00\x00\x00J\x00\x00\x00b\x00\x00\x00Y\x00\x00\x00Q\x00\x00\x00k\x00\x00\x00g\x00\x00\x00p\x00\x00\x00g\x00\x00\x00o\x00\x00\x00h\x00\x00\x00M\x00\x00\x00J\x00\x00\x00', '93')
8 : (b'J\x00\x00\x00i\x00\x00\x00F\x00\x00\x00S\x00\x00\x00b\x00\x00\x00e\x00\x00\x00U\x00\x00\x00B\x00\x00\x00Y\x00\x00\x00t\x00\x00\x00q\x00\x00\x00h\x00\x00\x00X\x00\x00\x00Q\x00\x00\x00k\x00\x00\x00', '93')
9 : (b'x\x00\x00\x00L\x00\x00\x00u\x00\x00\x00B\x00\x00\x00X\x00\x00\x00B\x00\x00\x00G\x00\x00\x00Y\x00\x00\x00P\x00\x00\x00T\x00\x00\x00o\x00\x00\x00g\x00\x00\x00D\x00\x00\x00w\x00\x00\x00o\x00\x00\x00', '41')
当然,如果我删除所有\x00,我会得到所需的结果
结果链接到Python 3.5,因为Windows或Linux Python 3.5返回相同类型的字节数组
如何在Python3.5中从Python2获得所需的结果表单
此脚本将用于生成2000000行包,numpy是这一代的最佳脚本,速度比多处理解决方案快,但Python 3.5中的最终结果并非预期的结果
有什么想法吗?代码必须在多个平台(Windows、Linux、Mac)上以尽可能快的速度运行。将
全局选项卡
替换为:
global_tab = [(''.join(u), str(v)) for u, v in zip(np.random.choice(list(string.ascii_letters), (N, 15)), np.random.randint(0, 100, N) )]
ascii\u字母
是字符串类型,因此您可能不需要调用encode('utf-8')
:
>>从字符串导入ascii字母
>>>ascii_字母
“ABCDEFGHIjklmnopqrstuvwxyzABCDEFGHIjklmnopqrstuvxyz”
>>>类型(ascii_字母)
然后使用.join
将结果数组u
转换为字符串。为什么
在python 2中,字符串。ascii字母是以字节字符串开头的。当调用方法.encode('utf-8')
时,python 2的“魔力”首先使用默认编码对其进行解码,然后根据请求重新编码。在Python2和Python3中,编码的结果都是字节
在python 3中,字节字符串在迭代时的行为不同:它返回整数,而不是长度为1的字节字符串:
In [52]: list(string.ascii_letters.encode('utf-8'))
Out[52]:
[97,
98,
99,
...
因此,在Python3中
np.random.choice(list(string.ascii_letters.encode('utf-8')), (N, 15))
不是由15个1字节字符串元素组成的N个数组。它是由15个整数组成的N个数组。当您稍后调用以获取数组的原始字节时,您将获得4或8字节整数。在你的例子中,你似乎得到了4,在这台机器上它们是8
可能的解决办法
一个选项是添加强制类型转换:
In [63]: [(u.tostring(),str(v)) for u, v in zip(
np.random.choice(list(string.ascii_letters.encode("utf-8")),
(N, 15)).astype('|S1'), # Cast to array-protocol type string
np.random.randint(0, 100, N))]
Out[63]:
[(b'811881611111171', '82'),
(b'816878668111171', '46'),
(b'811118881668718', '53'),
(b'971861817181818', '49'),
(b'118618991678978', '81'),
...
另一种方法是完全跳过编码,尽可能信任本机字符串类型(除非您确实需要字节字符串),并使用str.join()
:
第三种方法是使用bytearray()
而不是list()
:
一些时间安排
下面是他们如何在python 3中使用N=2000000
在这台机器上执行的:
没有(要求)铸件的原件:
演员阵容:
In [70]: %timeit [(u.tostring(), str(v)) for u, v in zip( np.random.choice(list(string.ascii_letters.encode('utf-8')), (N, 15)).astype('|S1'), np.random.randint(0, 100, N))]
1 loops, best of 3: 7.07 s per loop
使用本机字符串类型和联接:
In [71]: %timeit [(''.join(u), str(v)) for u, v in zip( np.random.choice(list(string.ascii_letters), (N, 15)), np.random.randint(0, 100, N))]
1 loops, best of 3: 12.1 s per loop
使用bytearray()包装:
感谢bytearray包装,保持了出色的性能。我在u.tostring()上添加了解码(“utf-8”),我仍然有很好的性能(在Windows平台上的3.9中有2000000个)。今晚我会看看一台旧电脑,它在不到15秒的时间内运行了第一个版本,但这台机器上的时间是原始版本的近3倍。我用了11.7秒来运行,而不是用bytearray将前面的答案用解码(“utf-8”)包装成3.9秒。
In [74]: [(''.join(u), str(v)) for u, v in zip(
np.random.choice(list(string.ascii_letters),
(N, 15)),
np.random.randint(0, 100, N))]
Out[74]: [('IJTlleYqZXmSJaW', '32')]
In [95]: [(u.tostring(), str(v)) for u, v in zip(
np.random.choice(bytearray(string.ascii_letters.encode('utf-8')),
(N, 15)),
np.random.randint(0, 100, N))]
Out[95]: [(b'MPvbDEQIdAVBQVz', '83')]
In [69]: %timeit [(u.tostring(), str(v)) for u, v in zip( np.random.choice(list(string.ascii_letters.encode('utf-8')), (N, 15)), np.random.randint(0, 100, N))]
1 loops, best of 3: 4.62 s per loop
In [70]: %timeit [(u.tostring(), str(v)) for u, v in zip( np.random.choice(list(string.ascii_letters.encode('utf-8')), (N, 15)).astype('|S1'), np.random.randint(0, 100, N))]
1 loops, best of 3: 7.07 s per loop
In [71]: %timeit [(''.join(u), str(v)) for u, v in zip( np.random.choice(list(string.ascii_letters), (N, 15)), np.random.randint(0, 100, N))]
1 loops, best of 3: 12.1 s per loop
In [93]: %timeit [(u.tostring(), str(v)) for u, v in zip( np.random.choice(bytearray(string.ascii_letters.encode('utf-8')), (N, 15)), np.random.randint(0, 100, N))]
1 loops, best of 3: 4.56 s per loop