之前提过,array对象往往要求所有元素保持统一的数据类型,因此numpy的运算能以数组为单位,而不用将元素提出来。
这也是numpy能够胜任高效运算的原因之一。
来看几个例子:
import numpy as np
arr = np.arange(1,10).reshape(3, 3)
array_1 = arr > 7 # 条件比较,返回bool
array_2 = arr * 0.3 # 加减乘除运算
arrs = np.arange(11,20).reshape(3,3)
array_3 = arrs / arr # 数组间的运算
print(array_1)
print('* '*20)
print(array_2)
print('* '*20)
print(array_3)
# 运行结果:
[[False False False]
[False False False]
[False True True]]
* * * * * * * * * * * * * * * * * * * *
[[0.3 0.6 0.9]
[1.2 1.5 1.8]
[2.1 2.4 2.7]]
* * * * * * * * * * * * * * * * * * * *
[[11. 6. 4.33333333]
[ 3.5 3. 2.66666667]
[ 2.42857143 2.25 2.11111111]]
可以看到,numpy甚至支持两个数组对象的算数运算。我们因此得到结论:
在numpy中,参与算术运算的单位可以是数组(“可以”不是“只能”)。
数组和数字的计算没什么好说的。
而数组与数组的运算,我们发现上面的例子中,两个运算的数组结构相同。这很好理解,两组的元素呈一一对应关系,这是映射。
那如果一对结构不同的数组呢?这就是我们要讲的广播机制。
numpy的广播机制也是如此,指两个不同shape的数组,在它们的shape满足一定条件时,可进行广播运算。这时,两个数组的元素按照一定规则扩散开来运算,并得到一个新的数组。
借用经典的描述就是,numpy中的广播机制旨在解决不同形状数组之间的算数运算问题。
我们来看数组运算的几个例子,观察广播机制是如何运作的:
import numpy as np
arr_2d_3x3 = np.arange(1,10).reshape(3, 3) # 3*3
arr_1d_3 = np.arange(1,4) # 3个元素的一维数组
arr_1d_4 = np.arange(1,5) # 4个元素
array_jia = arr_2d_3x3 + arr_1d_3 # 3*3 与 3个元素 运算(拿拼音代替了..)
array_jian = arr_2d_3x3 - arr_1d_4 # 3*3 与 4个元素 运算
print(arr_2d_3x3)
print('- '*5)
print(arr_1d_3)
print(arr_1d_4)
print('* '*20)
print(array_jia)
print('* '*20)
print(array_jian)
# 运行结果:
[[1 2 3]
[4 5 6]
[7 8 9]] # arr_2d_3x3
- - - - -
[1 2 3] # arr_1d_3
[1 2 3 4] # arr_1d_4
* * * * * * * * * * * * * * * * * * * *
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]] # array_jia,3*3 与 3个元素 运算
* * * * * * * * * * * * * * * * * * * *
ValueError: operands could not be broadcast together with shapes (3,3) (4,) # array_jian,3*3 与 4个元素 运算
可以看到,两个数组在列数(个数)相同、行数(长短)不同时,“较短”的数组对“较长”的数组向下做了传播式的运算,这便是"广播机制"叫法的由来。而列数不同的数组就报错了,便不能广播。
到这还没完,再看一组例子:
import numpy as np
arr_2d_3x3 = np.arange(1,10).reshape(3, 3) # 3*3
arr_2d_1x3 = np.arange(1,4).reshape(1, 3) # 1*3
arr_2d_3x1 = np.arange(1,4).reshape(3, 1) # 3*1
array_jia = arr_2d_3x3 + arr_2d_1x3 # 3*3 与 1*3 运算
array_jian = arr_2d_3x3 - arr_2d_3x1 # 3*3 与 3*1 运算
print(arr_2d_3x3)
print('- '*5)
print(arr_2d_1x3)
print('- '*5)
print(arr_2d_3x1)
print('* '*20)
print(array_jia)
print('* '*20)
print(array_jian)
# 运行结果:
[[1 2 3]
[4 5 6]
[7 8 9]] # 3*3
- - - - -
[[1 2 3]] # 1*3
- - - - -
[[1]
[2]
[3]] # 3*1
* * * * * * * * * * * * * * * * * * * *
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]] # 3*3 与 1*3 运算
* * * * * * * * * * * * * * * * * * * *
[[0 1 2]
[2 3 4]
[4 5 6]] # 3*3 与 3*1 运算
arr_2d_3x3 = np.arange(1,10).reshape(3, 3) # 3*3
arr_2d_1x3 = np.arange(1,7).reshape(2, 3) # 2*3
array_jia = arr_2d_3x3 + arr_2d_1x3 # 3*3 与 2*3 运算
print(array_jia)
# 运行结果:
ValueError: operands could not be broadcast together with shapes (3,3) (2,3)
通过上面第一个例子,很明显numpy在对两个方向不一致的数组进行运算时,基于“较短”数组的shape,选择运算规则是向行扩散还是列扩散。
用大白话说就是,相对于大数组,小数组行、列的饱和度。即:
无论如何,只要行/列有一个饱和的情况下,就将不饱和的地方广播至饱和。
而第二个例子可能你也感觉到了,3x3 和 2x3 这种形状好像根本没法广播,因为小数组拿来广播的元素是不唯一的。
其实,我们已经知道高维数组(体)由多个2维数组(面)组成。
所以你可能知道了,无非就是对多个“面”逐一广播而已。
就像这样:
import numpy as np
arr_2d_3x3 = np.arange(1,13).reshape(2, 3, 2) # 3*3
arr_2d_3x1 = np.arange(1,4).reshape(3,1)
array_jia = arr_2d_3x3 + arr_2d_3x1 # 3*3 与 3*1 运算
print(arr_2d_3x3)
print('- '*5)
print(arr_2d_3x1)
print('* '*20)
print(array_jia)
# 运行结果:
[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]
- - - - -
[[1]
[2]
[3]] # 这是多行一列,一行多列就不举例了
* * * * * * * * * * * * * * * * * * * *
[[[ 2 3]
[ 5 6]
[ 8 9]] # 先广播第一块
[[ 8 9]
[11 12]
[14 15]]] # 再广播第二块
广播的本质是一种算数运算,适用于加减乘除及其他所有的运算方式。

我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']