สร้างตัวเลขสุ่มตัวอักษรและตัวเลขเป็นตัวเลข

ฉันต้องการตัวเลขสุ่ม 100,000+ ฉันพบว่า numpy เหมาะสำหรับโปรเจ็กต์ของฉันโดยพิจารณาจากประสิทธิภาพที่ดี แต่ฉันต้องการตัวเลขสุ่ม 4 ตำแหน่งตามรูปแบบด้านล่าง

'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

ในกรณีข้างต้น ตัวอักษรเล็ก 26 ตัว ตัวพิมพ์ใหญ่ 26 ตัว และตัวเลข 10 หลัก เท่ากับตัวอักษรทั้งหมด 62 ตัว แล้วให้เราทำการเรียงสับเปลี่ยนและผสมกัน

ฉันต้องการตัวเลข 4 หลักจากตัวอักษรเหล่านั้น ดังนั้น

62 ^ 4 / 4! = 615680 (Combinations)

หากฉันใช้ตัวอักษรตัวเล็ก 26 ตัว + 10 หลักและผลลัพธ์คือ

(26+10) ^ 4 / 4! = 69984 (Combinations)

จากสองกรณีนี้ กรณีแรกดีที่สุด มันให้ตัวเลขสุ่มที่ดีกว่า ฉันใช้ตรรกะบางอย่างตรงนี้

from numpy.random.mtrand import RandomState
import binascii
lo = 1000000000000000
hi = 999999999999999999
In [65]: %timeit [ binascii.b2a_hex(rand.randint(lo, hi, 2).tostring())[:4] for _ in xrange(100000)]
1 loops, best of 3: 272 ms per loop

แต่การนับเลขสุ่มนั้นต่ำกว่า 100,000 เพราะใช้เพียงตัวอักษร + หลักเล็กเท่านั้น

In [66]: len(set([binascii.b2a_hex(rand.randint(lo, hi, 2).tostring())[:4] for _ in xrange(100000)]))
Out[66]: 51210

มีใครแนะนำฉันถึงวิธีการใช้สิ่งนี้ใน numpy บ้างไหม?


person dhana    schedule 18.09.2014    source แหล่งที่มา
comment
numpy.random.choice() เวกเตอร์ 4 ตัวจากตัวอักษร แล้วตามด้วย ''.join() ตัวละ?   -  person NPE    schedule 19.09.2014
comment
หรือหากคุณบอกเราถึงปัญหาจริงที่คุณกำลังพยายามแก้ไข เราอาจจะช่วยคุณได้ดีขึ้น   -  person NPE    schedule 19.09.2014
comment
@NPE ขอบคุณสำหรับการตอบกลับ ฉันกำลังพยายามสร้างตัวเลขสุ่ม 100,000 ทุกครั้ง ดังนั้นฉันจึงต้องบันทึกตัวเลขสุ่มที่ไม่ซ้ำทุกตัวลงใน nosql db และปัญหาคืออะไรคือฉันต้องการตัวเลขสุ่ม 4 ตำแหน่ง ตัวอักษร 62 ตัวให้ตัวเลขสุ่มที่ไม่ซ้ำใครมากกว่าเมื่อเปรียบเทียบกับตัวอักษร 36 ตัว จากตรรกะข้างต้นต้องใช้ตัวอักษร 32 ตัว ไม่ใช่ 64 ตัวอักษร   -  person dhana    schedule 19.09.2014
comment
โดยทั่วไปผู้คนจะใช้ฐาน 64 สำหรับสิ่งนี้ ซึ่งก็คือตัวอักษรของคุณและอักขระ '+' และ '/' สิ่งนี้ทำให้ทุกอย่างง่ายขึ้น เนื่องจากตอนนี้คุณแค่สร้างตัวเลขสุ่มแล้วแปลงเลขฐาน 64 เทียบกับตัวเลขนั้น   -  person Clarus    schedule 19.09.2014
comment
@Claris บางทีคุณสามารถโพสต์ความคิดเห็นของคุณเป็นคำตอบได้ ...   -  person Saullo G. P. Castro    schedule 20.09.2014


คำตอบ (4)


ตามที่ NPE ชี้ให้เห็น คุณสามารถใช้ numpy.random.choice รหัสนี้บรรลุสิ่งที่คุณต้องการหรือไม่?

import numpy as np

LENGTH = 4
NO_CODES = 100000

alphabet = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
np_alphabet = np.array(alphabet, dtype="|S1")
np_codes = np.random.choice(np_alphabet, [NO_CODES, LENGTH])
codes = ["".join(np_codes[i]) for i in range(len(np_codes))]

print(codes)

ใช้เวลาสองสามวินาทีในการดำเนินการด้วย NO_CODES = 1000000 บนคอมพิวเตอร์อายุ 2 ขวบของฉันแต่ก็ไม่ได้แย่

person marcotama    schedule 22.09.2014
comment
การรันสิ่งนี้บน python 3.5 ทำให้ฉันมีข้อความแสดงข้อผิดพลาด sequence item 0: expected str instance, numpy.bytes_ found - person NeStack; 20.03.2019
comment
ลองเปลี่ยน dtype เป็น dtype="|U1" - person xyzzyqed; 18.11.2019

สามารถทำได้เร็วขึ้นมากโดยใช้มุมมองแบบตัวเลข

A, Z = np.array(["A","Z"]).view("int32") 

NO_CODES = 100
LEN = 20

np.random.randint(low=A,high=Z,size=NO_CODES*LEN,dtype="int32").view(f"U{LEN}")
person Ales Novak    schedule 18.11.2019

คำตอบที่ยอมรับสามารถทำได้เร็วขึ้นเล็กน้อยด้วยรหัสต่อไปนี้:

import numpy as np

length  = 4
n_codes = 100000
alpha_num = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')

np_codes = np.random.choice(alpha_num, size=[n_codes, length])
codes = [code.tostring() for code in np_codes]

รันไทม์ดั้งเดิมบนเครื่องของฉัน: 10 loops, best of 3: 204 ms per loop

รันไทม์ใหม่: 10 loops, best of 3: 27.6 ms per loop

person Francois    schedule 15.08.2018

อีกสองคำตอบไม่ได้ผลสำหรับฉัน แต่ฉันสามารถใช้มันเพื่อสร้างวิธีแก้ปัญหาต่อไปนี้:

import numpy as np

length  = 4
n_codes = 100000
alpha_num = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')

np_codes = np.random.choice(alpha_num, size=[n_codes, length])
codes = [''.join(code) for code in np_codes]
person mgoldwasser    schedule 11.09.2019