如何计算 JMP 11 中超过 100 亿个条目的列的移动平均值?我正在尝试在具有 1 亿行的列上运行以下公式来计算移动平均值。您能否建议一个 JMP11 替代方案上校移动平均线
JMP11 不支持 Col Moving Average( :x, 1, 9999999, 0 )。</CODE></P><P><CODE class=" language-jsl">请在下面找到我尝试过的代码:
NamesDefaultToHere(1);
// Use a function to open a .CSV file: Given the path to such a file, returns a reference to the resulting table
openMyCSV =
function({path2File}, {Default Local},
dt = Open(
path2File,
columns(
New Column( "column 1", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "items", Numeric, "Continuous", Format( "Best", 12 ) )
),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Comma, CSV( 0 ) ),
Strip Quotes( 1 ),
Use Apostrophe as Quotation Mark( 0 ),
Use Regional Settings( 0 ),
Scan Whole File( 1 ),
Treat empty columns as numeric( 0 ),
CompressNumericColumns( 0 ),
CompressCharacterColumns( 0 ),
CompressAllowListCheck( 0 ),
Labels( 0 ),
Column Names Start( 1 ),
Data Starts( 1 ),
Lines To Read( "All" ),
Year Rule( "20xx" )
)
)
);
dt = New Table( "My data file");
dt << New Column( "cc", Character, width( 40 ) );
dt << New Column( "MovAvgMean", Numeric );
dt << New Column( "MovAvgMax", Numeric );
// Put all the .csv files to process into a list
dir = Pick Directory(
"Directory containing your csv files",
"C:\Users\xxx\Documents\test\"
);
files = Files In Directory( dir );
For( f = N Items( files ), f >= 1, f--,
If( !Ends With( Uppercase( files[f] ), ".CSV" ),
Remove From( files, f )
)
);
// Process each file - Incomplete!
For( f = 1, f <= N Items( files ), f++,
thisTable = openMyCSV( dir || files[f] );
thisTable << New Column( "x",
Numeric,
Continuous,
Formula( (87 *:items)-(0.03998113) ));
thisTable << New Column( "av", Numeric, Continuous, Formula( Col Moving Average( :x, 1, 9999999, 0 ) ) );
// This will insure that all formula processing is complet before the next statement is run
thisTable << run formulas;
FileName = files[f];
// Add the summary statistics to the summary table
dt << Add Rows( 1 );
dt:cc[N Rows( dt )] = FileName;
dt:MovAvgMean[N Rows( dt )] = Col Mean( thisTable:x );
dt:MovAvgMax[N Rows( dt )] = Col Max( thisTable:x );
Close( thisTable, nosave );
);
9
回复:如何计算 JMP 11 中具有 1 亿个条目的列的移动平均值?@jojmp ,
鉴于您的原始脚本甚至没有保存您的表格并且您引用了一个从未创建的列,并且考虑到大量值的平均值通过删除一行并添加另一行而发生非常小的变化,您的问题非常奇怪的。
下面是一个脚本,它创建一个包含 nr 行的表,而不是读取 nr = nrow(dt) 的文件。 如果你有 1 亿行,内存管理非常重要,计算应该尽量按 n 阶,O(n) 而不是 O(n*rng)
如果您显示嵌入式日志,将打印出进行计算的时间。还开始数据更新()和结束数据更新()用于节省 IO(渲染)时间。在我的电脑上,这是我的一些结果:
| 天然橡胶 |
nrg |
秒 |
| 100,000 |
100 |
0.34 |
| 10,000,000 |
1,000,000 |
10.66 |
| 100,000,000 |
100,000,000 |
85.74 |
| 100,000,000 |
10,000,000 |
104.50 |
请注意,此脚本假定没有缺失值.该脚本将需要修改,性能将大大降低以适应缺失值。 更改 nr 和 nrg 的值以测试您的 PC 的性能。
Names Default to Here(1);
nr = 100000;
dt = new table("test", new column("x"), Add rows(nr));
dt:x << set each value(Random Integer(100,200));
nrg = 100;
dt << begin data update();
t0 = hp time();
mvcol = dt << new column("MV");
mvcol[1] = :x[1];
for(j=2, j<=nrg, j++,
mvcol[j] = (:x[j] + (j-1)*mvcol[j-1])/j; //assumes no missing values
);
if(nrg < nr,
for(j=nrg+1, j<=nr, j++,
mvcol[j] = (:x[j] + (nrg)*mvcol[j-1] - :x[j - nrg])/ (nrg)
);
); //end if,
wait(0);
dt << end data update();
t1= hp time();
show((t1-t0)*1e-6);
鉴于这一切,我仍然觉得你所描述的不是你所需要的。
回复:如何计算 JMP 11 中具有 1 亿个条目的列的移动平均值?抱歉不清楚我已经将问题更改为超过 100 亿个条目并且条目数量不固定它可以增加到任何数量。 寻找一个通用公式来计算任意数量项目的移动平均值。回复:如何计算 JMP 11 中具有 1 亿个条目的列的移动平均值?@jojmp ,
要么我不理解您的要求,要么您不理解 Col Moving Avg()。您声明您有 1 亿行,您在脚本中指定的跨度为 99,999,999。因此,最后一行将是整列的平均值,而前几行将是直到并包括当前行的所有值。 下面是一张Big Class的图片和一个跨度为5(n之前)的列移动平均线。请注意,少于 6 的行仅使用所有行,并且会根据少于 6 个值得出平均值。从第 6 行开始,使用当前行和前 5 行计算平均值。
所以请提供更多细节。 现在,如果您的文件有超过 1 亿行,则需要修改自定义公式。

回复:如何计算 JMP 11 中具有 1 亿个条目的列的移动平均值?在这个自定义公式中,我们如何知道它是 9999 项的移动平均数?
回复:如何计算 JMP 11 中具有 1 亿个条目的列的移动平均值?@jojmp ,你的移动平均线公式有点外国
thisTable << New Column( "av", Numeric, Continuous, Formula( Col Moving Average( :x, 1, 9999999, 0 ) ) );
第三个参数 99999999 是通过序列(行)创建某种类型的(历史)平均值。第三个参数是平均值的跨度。 更常见的跨度是 5 或 10 或 ??为时间附近的值提供平均值,不包括整个历史。
假设这就是您想要的,替代公式可以做同样的事情
If( Row() == 1,
:x,
(:x + (Row() - 1) * Lag( :av, 1 )) / Row()
)
附件是样本数据 Big Class.jmp 的一个版本,其中包含两列带公式
Col Moving Average( :weight, 1, 9999, 0 )
和可比较的自定义公式
If( Row() == 1,
:weight,
(:weight + (Row() - 1) * Lag( :Custom Formula, 1 )) / Row()
)