Fortran:有两个大的整数数组,目的是找出它们是否有任何共同的数字,怎么样?
您可以认为两者的大小相同(情况1)或大小不同(情况2).它们也可能有许多重复的常用数字,因此应该对其进行处理以避免不必要的搜索或操作符.最简单的方法是进行不合适的暴力搜索.我们正在考虑SET类似于Python的操作,如下所示:
a = set([integers])
b = set([integers])
incommon = len(a.intersection(b)) > 0 #True if so, otherwise False
Run Code Online (Sandbox Code Playgroud)
例如:
a = [1,2,3,4,5]
b = [0,6,7,8,9]
sa = set(a)
sb = set(b)
incommon = len(sa.intersection(sb)) > 0
>>> incommon: False
b = [0,6,7,8,1]
incommon = len(sa.intersection(sb)) > 0
>>> incommon: True
Run Code Online (Sandbox Code Playgroud)
如何在Fortran中实现这一点?请注意,数组大小(> 10000),操作将重复数百万次!
更新: [关于问题的评论]我们绝对尝试了很多我们所知道的方法.例如,如BFS方法所述.它有效但效率不高有两个原因:1)需要大量迭代的方法的性质,2)我们可以实现的代码.接受的答案(由yamajun提供)对我们来说非常有益,而不仅仅是问题本身.Quick-Sort,Shrink和Isin的实现非常简单,并且非常好地实现了.我们赞赏这种迅速和完美的解决方案.
在Python中numpy.unique可以非常有效地从一维数组中删除所有重复项。
1)如何删除二维数组中重复的行或列?
2) nD 数组怎么样?
通常1e3意味着10**3.
>>> 1e3
1000.0
>>> 10**3
1000
Run Code Online (Sandbox Code Playgroud)
类似案例进行了exp(3)比较e**3.
>>> exp(3)
20.085536923187668
>>> e**3
20.085536923187664
Run Code Online (Sandbox Code Playgroud)
但是现在请注意,如果指数是一个float值:
>>> exp(3.1)
22.197951281441636
>>> e**3.1
22.197951281441632
Run Code Online (Sandbox Code Playgroud)
这很好.现在是第一个例子:
>>> 1e3.1
File "<stdin>", line 1
1e3.1
^
SyntaxError: invalid syntax
>>> 10**3.1
1258.9254117941675
Run Code Online (Sandbox Code Playgroud)
这表明Python不喜欢1e3.1,Fortran太.无论它可能是一个标准(!)为什么它是这样的?
考虑到以下两个版本的Python中非常简单的函数,问题是哪个优先于另一个,为什么?
与使用了其他分配相比,是否有额外的内存使用和/或CPU使用?case 1case 2
情况1:
def f(x):
y = x*x
return y
案例2:
def f(x):
return x*x
从我的观点来看,case 1它比另一个更清晰,特别是在复杂计算和提供许多返回对象的情况下.另一方面,case 2外观非常紧凑,因此被认为是非常有吸引力的.因为简单只是简单有效.你怎么看?
更新:
我不知道Python中有反汇编程序!当我了解到我的问题的答案以及检查类似想法的方法时,真是太神奇了.特别欣赏.
from dis import dis as dasm
dasm(f)
什么是Matlab中以下简单代码的等效pythonic实现.
Matlab的:
B = 2D array of integers as indices [1...100]
A = 2D array of numbers: [10x10]
A[B] = 0
Run Code Online (Sandbox Code Playgroud)
这样可以很好地工作,例如B[i]=42它找到要设置2的列的位置5.在Python中它会导致错误:超出界限是合乎逻辑的.然而,为了将上述Matlab代码翻译成Python,我们正在寻找pythonic方法.还请考虑更高尺寸的问题,例如:
B = 2D array of integers as indices [1...3000]
C = 3D array of numbers: [10x10x30]
C[B] = 0
Run Code Online (Sandbox Code Playgroud)
我们考虑的一种方法是改进索引数组元素i,j而不是绝对位置.也就是说,定位42到divmod(42,m=10)[::-1] >>> (2,4).所以我们将有一个nx2 >>> ii,jj索引向量,可以A很容易地用于索引.我们认为这可能是一种更好的方法,对于Python中的更高维度也是有效的.
我们使用以下代码计算两条线之间的锐角。
def AcuteAngle2(line1,line2):
''':: line(x1,y1,x2,y2)'''
u = (line1[2]-line1[0], line1[3]-line1[1])
v = (line2[2]-line2[0], line2[3]-line2[1])
return arccos(abs(dot(u,v)/(norm(u)*norm(v))))
Run Code Online (Sandbox Code Playgroud)
它按预期工作。例如:
>>> AcuteAngle2([0,0,1,0],[0,0,0,1])
1.5707963267948966 #in rad = 90 degree
Run Code Online (Sandbox Code Playgroud)
但是我们最近发现它在某些特殊情况下会失败!
>>> AcuteAngle2([0,0,1,0],[0,0,1,0])
0.0
Run Code Online (Sandbox Code Playgroud)
这是正确的,但是:
>>> AcuteAngle2([0,0,1,1],[0,0,1,1])
2.1073424255447017e-08 #failed!
Run Code Online (Sandbox Code Playgroud)
这是不正确的!它应该是 0.0。
任何想法和解决方案?
更新 1:按照以下答案中的建议
使用Decimal包可能对某些情况有所帮助。然而,我们的问题仍未解决,因为 (1) 有很多代码需要大量时间来调整每个部分以使用Decimal. 此外,(2)性能显着下降。此外,在处理numpy数组时需要 (3) 大量更改。因此它对我们的情况没有用。我们正在考虑某种装饰器等,而不改变事物并保持numpy性能。顺便说一句,有些人可能会建议使用多精度包,例如 gmpy 等,请注意,它们需要在代码中进行大量调整,这对我们的情况没有帮助。
简单但可能很明显但不适合我们:当命令有相同的名称变量时,
使用pdb快捷方式会变得烦人,因此,如何删除pdb中的所有密钥快捷方式?我们使用pdb的spyder,顺便说一句.
>>> p = 1
Run Code Online (Sandbox Code Playgroud)
虽然p我们对变量感兴趣,但在尝试调试时,上面显示为命令(abr.用于打印)!混乱!
据我所知,没有完全令人满意的3D可视化包.我的意思是完全的,因为可以很容易地看到可用包的以下问题:
ETS-Mayavi2,...)OpenGLimplements(VPython,...)也很慢任何帮助,如果你能满足Python/ Fortran?