使用Numpy Concatenate生成牌组时原有数组数据被覆盖的问题求助
问题描述
尝试用NumPy生成一副扑克牌二维数组,每张牌为子数组:索引0是牌值(1-13对应A到K),索引1是花色(0=黑桃S、1=红桃H、2=梅花C、3=方块D)。但运行代码后,前13个本该是黑桃的元素花色全部变为红桃,最终得到0张黑桃、26张红桃、13张梅花、13张方块的异常结果,用np.empty或np.zeros初始化数组都无法解决问题。
附原代码:
import numpy as np suits = 4 suitsize = np.empty(shape=(13,2)) suitsize[:,0] = np.arange(1,suitsize.shape[0]+1) a = suitsize print(suitsize) for i in range(1,suits): a[:,1] = i suitsize = np.concatenate([suitsize,a]) print(suitsize)
问题原因
核心问题是NumPy数组的引用赋值:
a = suitsize并没有创建新数组,只是让a指向了suitsize的内存地址,二者是同一个数组的别名。- 第一次循环时
i=1,执行a[:,1] = 1会直接修改suitsize(也就是初始的黑桃组)的花色为1(红桃),此时原本的黑桃组已经被篡改。 - 后续
concatenate操作是把被修改后的数组拼接到自身,导致红桃数量翻倍,而黑桃彻底消失。
修复方案
方案1:每次循环复制数组
每次循环时创建数组的副本,避免修改原数组:
import numpy as np suits = 4 suitsize = np.empty(shape=(13,2)) suitsize[:,0] = np.arange(1,suitsize.shape[0]+1) # 初始化黑桃花色为0 suitsize[:,1] = 0 for i in range(1,suits): # 复制基础牌值数组,再设置对应花色 a = suitsize.copy() a[:,1] = i suitsize = np.concatenate([suitsize,a]) print(suitsize)
方案2:更高效的向量生成(推荐)
利用NumPy的广播特性直接生成整个牌组,无需循环,效率更高:
import numpy as np # 生成牌值(1-13),重复4次对应4种花色 values = np.tile(np.arange(1,14), 4) # 生成花色(0-3),每个花色重复13次 suits = np.repeat(np.arange(4), 13) # 组合成二维数组 deck = np.column_stack((values, suits)) print(deck)
内容的提问来源于stack exchange,提问作者Kristen
相关产品推荐
相关产品推荐

