python - 如何生成如下矩阵?
问题描述
所以给定 numbern
和一个数组a
,我们需要创建一个n
bylen(a)
矩阵,其中矩阵的i,j
第 th 项是1
ifi
等于j
th 项,a
否则-1
。i
即对于从0
到的每个数字n-1
,我们需要一个数组来告诉我们该数字i
是否等于该数组a
。
如果我们有像函数式编程那样的地图功能,那就太酷了。然后我可以通过检查数组中的每个元素a
是否等于给定数字来创建行。
那么有没有我可以使用的功能,如下所示?
result=[]
for i in range(n):
result=np.vstack(result, np.map(checkequals(x,i),a)
return result
解决方案
通常,函数或映射方法不是最佳的numpy
。 numpy
都是关于数组的,所以最好从提供的整个数组构建块的角度来考虑numpy
。那些在编译代码中运行。
例如你的情况:
定义一个数组:
In [10]: a = np.random.randint(0,10,9)
In [11]: a
Out[11]: array([6, 0, 2, 5, 0, 5, 2, 0, 1])
将其与值的范围进行比较n
- 使用整个数组==
测试(和broadcasting
。结果是一个布尔数组,每个 (i,j) 的真/假值:
In [12]: np.arange(8)[:,None]==a
Out[12]:
array([[False, True, False, False, True, False, False, True, False],
[False, False, False, False, False, False, False, False, True],
[False, False, True, False, False, False, True, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False],
[False, False, False, True, False, True, False, False, False],
[ True, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False]])
鉴于此,很容易将其映射到 (-1,1) 值。 np.where
只是这样一种方式:
In [13]: np.where(np.arange(8)[:,None]==a, 1, -1)
Out[13]:
array([[-1, 1, -1, -1, 1, -1, -1, 1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, 1],
[-1, -1, 1, -1, -1, -1, 1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, 1, -1, 1, -1, -1, -1],
[ 1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1]])
更接近您的地图想法,我们可以定义一个对一对标量值进行操作的函数:
def foo(i,x):
if i==x:
return 1
else:
return -1
并用于np.vectorize
制作一个需要 2 个数组的函数,并将成对的标量传递给该函数。
In [16]: np.vectorize(foo)(np.arange(8)[:,None], a)
Out[16]:
array([[-1, 1, -1, -1, 1, -1, -1, 1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, 1],
[-1, -1, 1, -1, -1, -1, 1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, 1, -1, 1, -1, -1, -1],
[ 1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1]])
但这比第一种方法慢得多。
列表理解方法:
In [22]: [[(1 if i==x else -1) for x in a] for i in range(8)]
Out[22]:
[[-1, 1, -1, -1, 1, -1, -1, 1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, 1],
[-1, -1, 1, -1, -1, -1, 1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, 1, -1, 1, -1, -1, -1],
[1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1]]
然后可以将其制成一个数组(这实际上可能比该vectorize
方法更快)。
推荐阅读
- c# - 绑定到 MenuCommand 时,如何使上下文菜单按钮动态可见?
- google-chrome-extension - 如何从外部 URL 重定向到 chrome 扩展 URL?
- java - 如何在spring-cloud中禁用aws secrets manager查找,仅适用于本地配置文件?
- reactjs - 如何基于 Redux 全局触发事件
- ssms - 如何向 SQL Server 添加更多服务器?
- css - R Shiny - 使用 SliderInput 为静态图像设置动画时如何消除闪烁?
- amazon-web-services - 按日期过滤 s3 中的对象,而不是最后一次修改
- curl - curl splunk strftime 给出不可解析的 URI 编码请求数据
- excel - 需要一个 VBA 模块来循环遍历 word 文件、查找内容并在 Excel 电子表格中报告
- python - 根据上一行中的字符串获取数据框的值