提问人:Maluma Corazón 提问时间:9/3/2023 最后编辑:CristiFatiMaluma Corazón 更新时间:9/3/2023 访问量:63
如何在 Python 中通过行和列约束来改进数组矩阵 [0,1]?
How can I and improve array matrix [0,1] by row and column constraints in Python?
问:
假设我有一个矩阵数组表。
uvv = np.array([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]])
我将重点关注值为零的行,例如 然后,我想在某一列中,但该列不得在其他行中显示 1。根据 uvv 表,I 可以在列中随机 1 。row 2
random 1 two or three times
row 2
row 2
1,2,3,7,8,9,10,11,12,14,16,18
这是我的目标示例,当在列中添加随机 1 时:2, 14, 18
row 2
tem = np.array([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]])
谢谢。
答:
0赞
Jesse Sealand
9/3/2023
#1
解决方案:
解释作为注释包含在整个代码中。
# Loop over each column in array
for col_num in range(uvv.shape[1]):
# Get column and list of non-zero row positions
col_arr = uvv[:, col_num]
index_pos = np.where(col_arr!=0)
# If only zeroes exist in row, proceed
if len(index_pos[0]) == 0:
# Get number of times to insert a value (num_inserts)
# Get row numbers to insert value into (row_inserts)
num_inserts = random.choice([2,3])
row_numbers = range(0, len(col_arr)-1)
row_inserts = random.sample(row_numbers, num_inserts)
# For each time to insert a value
for i in range(num_inserts):
# Insert value into selected row
uvv[row_inserts[i], col_num] = 1
print(f"Inserted value in row: {row_inserts[i]}, col: {col_num}")
0赞
CristiFati
9/3/2023
#2
不是 NumPy 专家,这里有一个有效的解决方案(当然还有其他更快、更优雅的解决方案)。
使用的功能:
code00.py:
#!/usr/bin/env python
import sys
import numpy as np
def modify(arr, max_row_count=1, max_element_count=3, value=1):
ret = arr.copy() # Don't operate on original array
rows = np.where(~ret.any(axis=1))[0] # All rows that only have 0s
for idx, row in enumerate(rows):
if idx >= max_row_count:
break
column_choices = np.where(~ret.any(axis=0))[0] # All columns that only have 0s
#print(column_choices)
columns = np.random.choice(
column_choices,
size=min(max_element_count, len(column_choices)),
replace=False
) # Select randomly from (above) columns
ret[row, columns] = value
return ret
def main(*argv):
arr0 = np.array([
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1-1, 0, 0, 0]
])
print("Original:\n{:}".format(arr0))
for i in range(3):
arr = modify(arr0)
print("\nModified (variant {:}):\n{:}".format(i + 1, arr))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
输出:
(py_pc064_03.08_test0_lancer) [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackExchange/StackOverflow/q077032322]> python ./code00.py Python 3.8.18 (default, Aug 25 2023, 13:20:30) [GCC 11.4.0] 064bit on linux Original: [[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] Modified (variant 1): [[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0] [1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] Modified (variant 2): [[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] Modified (variant 3): [[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] Done.
1赞
Corralien
9/3/2023
#3
您可以使用布尔掩码来查找行和可用列:
m1 = ~uvv.any(axis=1) # rows with all zeroes
m2 = ~uvv.any(axis=0) # columns with all zeroes
rows = np.nonzero(m1)[0] # find rows to fill
cols = np.nonzero(m2)[0] # find available columns
for row in rows:
idx = np.random.choice(cols, np.random.randint(1, 4), replace=False)
uvv[row, idx] = 1
cols = np.setdiff1d(cols, idx)
输出:
>>> uvv
array([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]])
# rows to fill
>>> rows
array([1])
# before the loop
>>> cols
[ 0 1 2 6 7 8 9 10 11 13 15 17]
# after the loop
[ 0 1 2 6 8 9 10 11 13 15] # col 7 and 17 are not available now
评论
0赞
Maluma Corazón
9/4/2023
如果有一个可用的列,但我们在 2 到 3 之间随机以替换 1 ?当随机值超过可用列时,我该如何解决此问题?
0赞
Corralien
9/4/2023
这应该没什么大不了的。尝试将 替换为 。现在有效吗?np.random.randint(1, 4)
1+np.random.randint(min(3, len(cols)))
评论