- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
其实不是RANDBETWEEN()
。我正在尝试创建一个 UDF 来返回数组中数字的索引,其中数字越大,被选择的可能性就越大。
我知道如何将概率分配给工作表中的随机数(即对概率之和使用 MATCH()
,有很多东西解释这一点),但我想要一个 UDF因为我将一个特殊的输入数组传递到函数中 - 而不仅仅是选定的范围。
我的问题是,权重关闭,数组中后面的数字比数组中前面的数字更有可能返回,而且我看不出代码中哪里出了问题。这是到目前为止的 UDF:
Public Function PROBABLE(ParamArray inputArray() As Variant) As Long
'Takes a set of relative or absolute probabilities and ranks a random number within them
Application.Volatile (True)
Dim outputArray() As Variant
Dim scalar As Single
Dim rankNum As Single
Dim runningTot As Single
'''''
'Here I take inputArray() and convert to outputArray(),
'which is fed into the probability code below
'''''
scalar = 1 / WorksheetFunction.Sum(outputArray)
rankNum = Rnd()
runningTot = 0
For i = 0 To UBound(outputArray)
runningTot = runningTot + outputArray(i)
If runningTot * scalar >= rankNum Then
PROBABLE = i + 1
Exit Function
End If
Next i
End Function
该函数应该查看outputArray()
中数字的相对大小,并随机选择,但对较大的数字进行加权。例如。 {1,0,0,1}
的 outputArray()
应分别分配 {50%,0%,0%,50%}
的概率然而,当我针对 1000 个样本和 100 次迭代测试 outputArray()
并绘制数组中第 1 项或第 4 项的返回频率时,我得到了以下结果:
大约 20%:80% 的分布。绘制 {1,1,1,1}
(所有机会均等)给出 10%:20%:30%:40% 分布
我知道我错过了一些明显的东西,但我不知道是什么,有什么帮助吗?
有些人要求完整的代码,这里是。
Public Function PROBABLE(ParamArray inputArray() As Variant) As Long
'Takes a set of relative or absolute probabilities and ranks a random number within them
Application.Volatile (True) 'added some dimensions up here
Dim outputArray() As Variant
Dim inElement As Variant
Dim subcell As Variant
Dim scalar As Single
Dim rankNum As Single
Dim runningTot As Single
'convert ranges to values
'creating a new array from the mixture of ranges and values in the input array
''''
'This is where I create outputArray() from inputArray()
''''
ReDim outputArray(0)
For Each inElement In inputArray
'Normal values get copied from the input UDF to an output array, ranges get split up then appended
If TypeName(inElement) = "Range" Or TypeName(inElement) = "Variant()" Then
For Each subcell In inElement
outputArray(UBound(outputArray)) = subcell
ReDim Preserve outputArray(UBound(outputArray) + 1)
Next subcell
'Stick the element on the end of an output array
Else
outputArray(UBound(outputArray)) = inElement
ReDim Preserve outputArray(UBound(outputArray) + 1)
End If
Next inElement
ReDim Preserve outputArray(UBound(outputArray) - 1)
''''
'End of new code, the rest is as before
''''
scalar = 1 / WorksheetFunction.Sum(outputArray)
rankNum = Rnd()
runningTot = 0
For i = 0 To UBound(outputArray)
runningTot = runningTot + outputArray(i)
If runningTot * scalar >= rankNum Then
PROBABLE = i + 1
Exit Function
End If
Next i
End Function
开始的inputArray()
🡒 outputArray()
部分用于标准化不同的输入法。 IE。用户可以输入值、单元格引用/范围和数组的混合,并且该函数可以应对。例如{=PROBABLE(A1,5,B1:C15,IF(ISTEXT(D1:D3),LEN(D1:D3),0))}
(你明白了) 应该与 =PROBABLE(A1:A3)
一样有效。我循环遍历 inputArray() 的子元素并将它们放入我的 outputArray() 中。我相当确定这部分代码没有任何问题。
然后,为了获得结果,我将 UDF 复制到 A1:A1000
中,并使用 COUNTIF(A1:A1000,1)
或代替计数 1 ,我确实为每个可能的 UDF 输出计算了 2、3、4 等,并制作了一个简短的宏来重新计算工作表 100 次,每次将 countif 的结果复制到表格中以绘制图表。我无法准确地说出我是如何做到这一点的,因为我把这一切都留在了工作中,但我会在周一更新。
最佳答案
试试这个:
Function Probable(v As Variant) As Long
Application.Volatile 'remove this if you don't want a volatile function
Dim v2 As Variant
ReDim v2(LBound(v) To UBound(v) + 1)
v2(LBound(v2)) = 0
Dim i As Integer
For i = LBound(v) To UBound(v)
v2(i + 1) = v2(i) + v(i) / Application.Sum(v)
Next i
Probable = Application.WorksheetFunction.Match(Rnd(), v2, 1)
End Function
<小时/>
数组v
本质上是您的outputArray
。
该代码采用 {1,0,0,1}
之类的数组并将其转换为 {0,0.5,0.5,1}
(请注意 >0
开头),此时您可以按照您的建议进行 MATCH
,以相等的概率获得 1 或 4
。
同样,如果您以 {1,1,1,1}
开头,它将转换为 {0,0.25,0.5,0.75,1}
并以相同的概率返回 1、2、3 或 4
中的任何一个。
另请注意:如果将 Application.Sum(v)
的值保存在变量中,而不是对数组 v 中的每个值执行计算,则可能会更快一些
.
更新
该函数现在将v
作为参数——就像您的代码一样。我还对其进行了一些调整,以便它可以处理具有任何基数的 v
,这意味着您也可以从工作表中运行它:=Probable({1,0,0,1} )
例如
关于vba - Excel UDF 加权 RANDBETWEEN(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42159763/
我在弄清楚如何从另一个 UDF 返回 UDF 中的数组时遇到了一些麻烦。这里的一个是简单的指数移动平均 UDF,我试图将数组返回到另一个 UDF,但我收到 #value 错误。我觉得有一个我没有看到的
我需要从另一个模块(在同一个工作簿中)调用以前制作的 UDF 来构建另一个 UDF。如何调用第一个函数? 这适用于 Excel VBA。我已经构建了我的第一个函数,它计算产品在特定时间的账面值(val
这个问题可能对许多 VBA 程序员有用。它涉及实现两个有用的独立任务并使它们同时工作。 第一个任务是为 UDF 制作 Excel 函数工具提示。虽然似乎还没有找到明确的解决方案,但目前我对自定义插入函
我正在将 Spark 与 Scala 一起使用,并希望将整行传递给 udf 并选择 udf 中的每个列名和列值。我怎样才能做到这一点? 我正在尝试以下 - inputDataDF.withColumn
这个问题在这里已经有了答案: Spark functions vs UDF performance? (3 个答案) 关闭2 年前。 我从 Pyspark 网站获取了以下 UDF,因为我试图了解是否
我已经使用 Spark 2.4 一段时间了,最近几天才开始切换到 Spark 3.0。切换到 Spark 3.0 运行后出现此错误 udf((x: Int) => x, IntegerType)
这个问题源自 SQLServer: Why avoid Table-Valued User Defined Functions? 。我开始在一些评论中提出问题,而对我评论的回复却偏离了主题。 这样您就
这是我的 hive 表 CREATE TABLE `dum`(`val` map>); insert into dum select map('A',array('1','2','3'),'B',ar
我想知道编写 spark udf 是否会降低性能。一般来说,我更喜欢组合做一件事的小函数…… 这是一个简单的例子,给定一个 DataFrame df: def inc = udf( (i: Doubl
我正在尝试根据另一列的值在 Spark 数据集中创建一个新列。另一列的值作为键在 json 文件中搜索,返回的值是用于新列的值。 这是我尝试过的代码,但它不起作用,而且我不确定 UDF 是如何工作的。
SPARK_VERSION = 2.2.0 我在尝试做 filter 时遇到了一个有趣的问题。在具有使用 UDF 添加的列的数据帧上。我能够用较小的数据集复制问题。 鉴于虚拟案例类: case cla
我正在 Java 中使用 Spark 来处理 XML 文件。来自databricks的spark-xml包用于将xml文件读入dataframe。 示例 xml 文件是: 1 joh
我正在尝试创建一个 MySQL UDF getFile(),它应该从磁盘上的某个目录返回文本文件的内容。问题是调用一次或两次有效,但在第二次或第三次调用 UDF 时,MySQL 服务器崩溃。 我无法通
我听说 Microsoft SQL Server 中有多种方法可以查找“最差”存储过程:按执行次数、按 CPU 工作时间、按队列等待时间等。 我正在寻找一种方法来查找最差(最慢/最常用)的 UDF -
我已经为一个项目构建了一个包含多个公式的 Excel 工作表。然后,我添加了一个用于折叠/展开某些单元组的命令按钮。 命令按钮代码是: Private Sub CommandButton1_Click
MySQL版本:5.1.73数据库客户端版本:libmysql - 5.1.73 我试图检查 NEW.src 在过去一小时内是否存在,如果不存在则执行 sys_exec udf。 我在 mysql 中
我正在尝试将元组列表传递给 scala 中的 udf。我不确定如何为此准确定义数据类型。我试图将它作为一整行传递,但它无法真正解决它。我需要根据元组的第一个元素对列表进行排序,然后返回 n 个元素。我
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 此问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-topic
我正在尝试创建一个类似 =Extractinfo("A2","Name") 的函数,它可以从原始数据中提取姓名、电话和电子邮件 ID,一个用于所有 3 次提取的函数,我已经有一个提取电子邮件 ID 的
我正在编写一个用户定义函数(UDF),它以一些单元格作为参数。 这些单元格包含相同的数据,但精度不同;该功能显示可用的最佳精度。 函数的参数按精度升序编写。 这是一个例子: +---+--------
我是一名优秀的程序员,十分优秀!