程序在每个特征向量(列)中获得0和1的频率并将其存储到数组中。但是当我访问我的数组列表(观察到例如observe.get(0)[0])时,它返回矩阵中的所有0。
DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
for (int i = 0; i< featurevec.length; i++) {
featurevec[i] = tempfeatures.extractVector(false,i);
}
double[]f = new double[2];
ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++)
{
for (int i = 0; i< featurevec[j].getNumElements(); i++)
{
if (featurevec[j].get(i) == 1)
f[0]++;
else
f[1]++;
}
observed.add(f);
}
答案 0 :(得分:1)
问题是你永远不会重置f []。您总是递增相同的数组,您需要在每次传递时创建一个新数组。
ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++) {
double[] f = new double[2]; //move this here
for (int i = 0; i< featurevec[j].getNumElements(); i++) {
if (featurevec[j].get(i) == 0) //I recommend changing this
f[0]++;
else
f[1]++;
}
observed.add(f);
}
另请注意,我将if (featurevec[j].get(i) == 1)
更改为if (featurevec[j].get(i) == 0)
,因此0计数存储在f [0]中,1计数存储在f [1]中。我认为这更清楚,并且更容易管理。
这取决于DoubleMatrix
是什么,不确定,因为你没有告诉我们。你可以通过做这样的事情来消除你的if / else语句,因为你知道你只有0和1:
ArrayList<int[]> observed = new ArrayList<int[]>();
for (int j = 0; j< featurevec.length; j++) {
int[] f = new int[2];
totalOnes = arraySum(featurevec[j]);
//total elements - total one count = total zero count
f[0] = featurevec[j].getNumElements() - totalOnes;
f[1] = totalOnes;
observed.add(f);
}
//not sure of arr's type, unclear from your code, probably Integer?
private int arraySum(ArrayList<T> arr) {
int sum = 0;
//this loop syntax might not work depending on DoubleMatrix's implementation
for(int i : arr)
sum+=i;
return sum;
}
虽然这个解决方案仍然是O(n ^ 2),但也许它更清晰一点。
我也不确定你为什么要把f []设为double [],因为你只得到0和1的数。我也改变了。
答案 1 :(得分:0)
我已经弄明白了:我只需要像这样初始化我的列表:
DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
for (int i = 0; i< featurevec.length; i++) {
featurevec[i] = tempfeatures.extractVector(false,i);
}
double[]f = new double[2];
ArrayList<double[]> observed = new ArrayList<>(tempfeatures.numCols());
for (int i = 0; i< featurevec.length; i++)
observed.add(new double[2]);
for (int j = 0; j< featurevec.length; j++) {
for (int i = 0; i< featurevec[j].getNumElements(); i++) {
if (featurevec[j].get(i) == 1) {
observed.get(j)[0]++;
// f[0]++;
}
else
observed.get(j)[1]++;
// f[1]++;
//observed.add(f);
}
}
但它的性能很低。因为我有1461 * 18584行列矩阵。有人可以向我建议一个更好的方法吗?
答案 2 :(得分:0)
问题是您只创建一个数组并重复修改并再次将其添加到列表中。
你需要移动
double[]f = new double[2];
在循环中。
DoubleMatrix[] featurevec = new DoubleMatrix[tempfeatures.numCols()];
for (int i = 0; i< featurevec.length; i++) {
featurevec[i] = tempfeatures.extractVector(false,i);
}
ArrayList<double[]> observed = new ArrayList<>();
for (int j = 0; j< featurevec.length; j++)
{
double[]f = new double[2];
for (int i = 0; i< featurevec[j].getNumElements(); i++)
{
if (featurevec[j].get(i) == 1)
f[0]++;
else
f[1]++;
}
observed.add(f);
}
答案 3 :(得分:0)
每次调用observed.add(f)
时,它都会再次将相同的数组添加到观察列表中。最后,您有一个包含featurevec.length
对同一数组的引用的ArrayList。你需要在循环中创建数组f
,所以每次都得到一个新数组:
for (int j = 0; j < featurevec.length; j++) {
double[] f = new double[2];
...
observed.add(f);
}