Replacing sequence with random number
For generating unique and random-looking identifiers from a serial, using ciphers might be a good idea. Since their output is bijective (there is a one-to-one mapping between input and output values) -- you will not have any collisions, unlike hashes. Which means your identifiers don't have to be as long as hashes.
Most cryptographic ciphers work on 64-bit or larger blocks, but the PostgreSQL wiki has an example PL/pgSQL procedure for a "non-cryptographic" cipher function that works on (32-bit) int
type. Disclaimer: I have not tried using this function myself.
To use it for your primary keys, run the CREATE FUNCTION call from the wiki page, and then on your empty tables do:
ALTER TABLE foo ALTER COLUMN foo_id SET DEFAULT pseudo_encrypt(nextval('foo_foo_id_seq')::int);
And voila!
pg=> insert into foo (foo_id) values(default);
pg=> insert into foo (foo_id) values(default);
pg=> insert into foo (foo_id) values(default);
pg=> select * from foo;
foo_id
------------
1241588087
1500453386
1755259484
(4 rows)
How to replace x to a random number
Here is a possible answer for your problem
input_string = 'GGI20-xxxxxxx'
import random
def replace_val(input_str):
str_list = list(input_str)
str_list = [str(i).replace('x',str(random.randint(0,9))) for i in str_list]
return ''.join(str_list)
replace_val(input_string)
o/p : 'GGI20-3428855' (it will vary as result will be random)
`
Replace Values in Column with Random Sequence of Values
The problem is that you are taking the row out of the dataframe, edit it, but don't put it back.
To get your code working, you can do
for(i in 1:nrow(df)) {
df$acq_date[i] <- sample(seq(as.Date('2020/12/15'), as.Date('2021/01/30'), by="day"), 1)
}
But i would suggest creating the randomdates all at one via
randomDates <- sample(seq(as.Date('2020/12/15'), as.Date('2021/01/30'), by="day"), nrow(df))
and then insert them into the df via
df$acq_date <- randomDates
Multiple sequences of random numbers without replacement
Approach #1
For N
>> n
, we can use an iterative method with masking, so that at each iteration we pick one not-previously picked element per row. The implementation would look something like this -
R = np.arange(M)
mask = np.ones((M,N), dtype=bool)
idx = np.random.randint(0,N,(M))
mask[R,idx] = 0
for i in range(1,n):
lim = N-i
m2 = np.ones((M,lim), dtype=bool)
idx2 = np.random.randint(0,lim,(M))
m2[R,idx2] = 0
mask[mask] = m2.ravel()
out = np.nonzero(~mask)[1].reshape(-1,n)
If you need to randomize numbers per row, use the rand-trick as linked in question post :
out = np.take_along_axis(out, np.random.rand(M,n).argsort(1), axis=1)
If the constant array-creation with m2
bothers you, re-use after initializing before looping, while keeping the rest of the code same -
m2 = np.ones((M,N-1), dtype=bool)
for i in range(1,n):
lim = N-i
idx2 = np.random.randint(0,lim,(M))
m2[R,idx2] = 0
mask[mask] = m2.ravel()
m2[R,idx2] = 1
m2 = m2[:,:-1]
Approach #2 Similar to Approach #1
, but the initialization part does most of the job to setup unqiue random numbers per row. An additional while
iterative part takes care of the rows that could not assign unique ones. With N
>> n
, we will hardly need to iterate though. The implementation would look something like this -
# https://stackoverflow.com/a/51915131/ @Divakar
def random_num_per_grp(L):
# For each element in L pick a random number within range specified by it
r1 = np.random.rand(np.sum(L)) + np.repeat(np.arange(len(L)),L)
offset = np.r_[0,np.cumsum(L[:-1])]
return r1.argsort()[offset] - offset
R = np.arange(M)
mask = np.ones((M,N), dtype=bool)
idx = np.random.randint(0,N,(M,n))
mask[R[:,None],idx] = 0
rows_notdone = mask.sum(1)!=N-n
while np.any(rows_notdone):
idx0 = random_num_per_grp(mask[rows_notdone].sum(1))
steps = np.r_[0,mask.sum(1).cumsum()[:-1]]
flat_idx0 = steps[rows_notdone] + idx0
m2 = np.ones(mask.sum(), dtype=bool)
m2[flat_idx0] = 0
mask[mask] = m2
rows_notdone = mask.sum(1)!=N-n
out = np.nonzero(~mask)[1].reshape(-1,n)
Replace ending integer number of a function with another random integer number
If the method names follow a specific pattern as you say, you can use the getattr
function to get the method based on a calculated name:
def roll(self):
sense = SenseHat()
self.number = random.randint(1,6)
getattr(self, 'dice_%d' % self.number)()
But in this case it's more likely that you can combine your dice_#
methods into one method that makes use of the dice number of the instance instead, resulting in more elegant code:
def roll(self):
sense = SenseHat()
self.number = random.randint(1,6)
self.dice()
def dice(self):
print(self.number)
# so something with self.number
How can I replace the random values in a column in Studio with a sequential number set?
If you don't care about the order, then you may use ROW_NUMBER
ordered by the data column:
WITH cte AS (
SELECT data, 1000 + ROW_NUMBER() OVER (ORDER BY data) rn
FROM yourTable
)
If you also want to update then use:
UPDATE cte
SET data = rn;
Why are my random numbers not changing accordingly in Excel?
The behaviour you described is a bug.
First, if we replace line:
Randomize i
with:
Randomize 0
we can see that on Windows we get the exact same repeated values as we would get on a Mac:
This immediately suggested to me that there can only be 2 possible explanations:
- Maybe the algorithm is different
- There is an issue and the value of
i
is not passed/read correctly.
In order to find a rule, I used a separate method (brute-forced i/x) and found the following magic numbers. Again, if we replace line:
Randomize i
with:
#If Mac Then
Dim arr() As Variant: arr = Array(26489, 63707, 185603, 15365, 92513)
Randomize i / arr(i - 1)
#Else
Randomize i
#End If
we get the same results on Windows and Mac.
I could not find a clear pattern in those magic numbers so I discarded that the algorithm is different. This left me with finding the issue/bug.
After some trial and error I found that if we pass a Double
data type to the Randomize
method it does not read the full 8 bytes but instead only reads the first 4 bytes. That is why dividing by those magic numbers worked, because the resulting numbers (of those divisions) were using the first 4 bytes (including the exponent bits) instead of the 8 full bytes.
The fix is to offset (to the left) the double value by 4 bytes. Here is the final code that works on both Windows and Mac:
Option Explicit
#If Mac Then
#If VBA7 Then
Public Declare PtrSafe Function CopyMemory Lib "/usr/lib/libc.dylib" Alias "memmove" (Destination As Any, Source As Any, ByVal Length As LongPtr) As LongPtr
#Else
Public Declare Function CopyMemory Lib "/usr/lib/libc.dylib" Alias "memmove" (Destination As Any, Source As Any, ByVal Length As Long) As Long
#End If
#End If
Sub Macro1()
Dim i As Long
Dim j As Long
Dim RA1 As Variant
ReDim RA1(1 To 5)
For i = 1 To 5
Rnd (-1)
#If Mac Then
Dim d As Double
d = CDbl(i)
CopyMemory d, ByVal VarPtr(d) + 4, 4 'Read the last 4 double bytes into the first 4
Randomize d
#Else
Randomize i
#End If
For j = 1 To 5
RA1(j) = Rnd
Next j
With Sheets("Sheet1")
.Range(Cells(i, 1), Cells(i, 5)).Value = RA1
End With
Next i
End Sub
You'll have noticed that I've also added Option Explicit
, declared all variables and indented the code.
Related Topics
SQL Server:Check If Variable Is Empty or Null for Where Clause
Get .SQL File from SQL Server 2012 Database
Select All Threads and Order by the Latest One
Performance Issue in Update Query
MySQL Views - When to Use & When Not To
Fast Update of Access Data with Excel Data Using Excel Vba
SQL Profiler and Tuning Advisor
How to Find Least Non-Null Column in One Particular Row in SQL
What Is the Optimal Way to Compare Dates in Microsoft SQL Server
How to Use a Case Statement in a SQL from Clause
How to Execute Table Valued Function
Remove Duplicates from SQL Union
SQL Server - Can You Add Field Descriptions in Create Table
A Simple Way to Sum a Result from Union in MySQL
What's the Right Way to Compare an Ntext Column with a Constant Value