元素充足的1维numpy数组无法按预期reshape为(20,5)问题求解
问题原因与解决方案
问题根源
当调用df.apply(..., axis=1)时,每行返回的长度为5的numpy数组会被pandas当作单个元素存储,最终得到的是一个长度为20、元素类型为object的Series,每个元素对应一行返回的5元素数组。此时直接用np.array()转换得到的是形状为(20,)的对象数组,数组总长度就是20,自然无法reshape成(20,5)。
可用解决方案
方案1:使用np.vstack直接堆叠
这是最简洁的方案,直接把Series中存储的20个单行数组合并成二维数组,转换后直接得到形状为(20,5)的数值数组,无需额外reshape:
z = np.vstack(df.apply(new_vectors, args=(df.iloc[0].to_numpy(), df.iloc[11].to_numpy()), axis=1))
方案2:先转列表再转numpy数组
把Series先转为嵌套列表,再通过numpy数组构造函数生成二维数组:
res_series = df.apply(new_vectors, args=(df.iloc[0].to_numpy(), df.iloc[11].to_numpy()), axis=1) z = np.array(res_series.tolist())
方案3:修改返回值适配pandas自动对齐
让自定义函数返回pandas的Series对象,此时apply会自动把返回结果拼接成DataFrame,再转numpy数组即可:
# 仅修改自定义函数的返回部分即可 def new_vectors(current, best, worst): # 原有逻辑不变 current = current.to_numpy() new = np.add(current, np.subtract((rng.random()*(np.subtract(best, np.absolute(current)))), ((rng.random()*(np.subtract(worst, np.absolute(current))))))) summed = current.sum() newsummed = new.sum() res = np.add(((newsummed < summed)*(new)), ((newsummed > summed)*(current))).flatten() # 把返回的numpy数组转为pd.Series return pd.Series(res) # 调用apply后直接转numpy即可 z = df.apply(new_vectors, args=(df.iloc[0].to_numpy(), df.iloc[11].to_numpy()), axis=1).to_numpy()
以上方案均可在你提供的复现代码上直接运行,得到符合要求的(20,5)尺寸数组。
内容的提问来源于stack exchange,提问作者Guardian
相关产品推荐
相关产品推荐

