Hasilkan angka acak alfanumerik dalam numpy

Saya ingin angka acak 100000+, menurut saya numpy cocok untuk proyek saya berdasarkan kinerjanya bagus. Tapi saya ingin 4 tempat nomor acak berdasarkan pola di bawah ini,

'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

Dalam kasus di atas 26 huruf kecil, 26 huruf kapital dan 10 angka sama dengan 62 huruf total dan mari kita ambil permutasi dan kombinasi,

Saya ingin 4 digit dari huruf-huruf itu jadi,

62 ^ 4 / 4! = 615680 (Combinations)

Jika saya mengambil 26 huruf kecil + 10 digit dan hasilnya adalah,

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

Dari dua kasus tersebut, yang pertama adalah yang terbaik, Ini memberikan angka acak yang lebih baik, saya melakukan beberapa logika di sini,

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

Namun hitungan angka acaknya dibawah 100000, Karena hanya membutuhkan huruf + angka kecil saja

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

Adakah yang menyarankan saya bagaimana menerapkan ini di numpy?


person dhana    schedule 18.09.2014    source sumber
comment
numpy.random.choice() 4-vektor dari alfabet, lalu ''.join() masing-masing?   -  person NPE    schedule 19.09.2014
comment
Atau jika Anda memberi tahu kami masalah sebenarnya yang ingin Anda selesaikan, kami mungkin dapat membantu Anda dengan lebih baik.   -  person NPE    schedule 19.09.2014
comment
@NPE terima kasih atas balasannya, saya mencoba menghasilkan angka acak 100000 setiap kali. Jadi saya perlu menyimpan setiap nomor acak unik ke dalam nosql db. Dan masalahnya adalah saya ingin 4 tempat nomor acak. 62 huruf memberikan angka acak yang lebih unik dibandingkan dengan 36 huruf. Jadi dari logika diatas dibutuhkan 32 huruf bukan 64 huruf.   -  person dhana    schedule 19.09.2014
comment
Biasanya orang menggunakan basis 64 untuk ini, yaitu alfabet dan karakter '+' dan '/'. Ini membuat segalanya lebih mudah karena Anda sekarang hanya membuat angka acak dan kemudian melakukan konversi basis 64 terhadapnya.   -  person Clarus    schedule 19.09.2014
comment
@Claris mungkin Anda dapat mengirim komentar Anda sebagai jawaban...   -  person Saullo G. P. Castro    schedule 20.09.2014


Jawaban (4)


Seperti yang ditunjukkan oleh NPE, Anda dapat menggunakan numpy.random.choice. Apakah kode ini mencapai apa yang Anda inginkan?

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)

Dibutuhkan beberapa detik untuk mengeksekusi dengan NO_CODES = 1000000 di komputer saya yang berumur 2 tahun tetapi lumayan.

person marcotama    schedule 22.09.2014
comment
Menjalankan ini di python 3.5 memberi saya pesan kesalahan sequence item 0: expected str instance, numpy.bytes_ found - person NeStack; 20.03.2019
comment
Coba ubah dtype menjadi dtype="|U1" - person xyzzyqed; 18.11.2019

Ini dapat dilakukan lebih cepat dengan menggunakan tampilan numpy.

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

Jawaban yang diterima dapat dibuat sedikit lebih cepat dengan kode berikut:

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]

Runtime asli di mesin saya: 10 loops, best of 3: 204 ms per loop.

Waktu proses baru: 10 loops, best of 3: 27.6 ms per loop.

person Francois    schedule 15.08.2018

Tak satu pun dari dua jawaban lainnya yang berhasil untuk saya, namun saya dapat menggunakannya untuk membuat solusi berikut:

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