简体   繁体   English

从已解析的XML文件计算标准差

[英]Counting standard deviation from parsed XML file

I wrote a method that counts average of sell currency exchange-course(ASK) and standard deviation of it , but i think that it isn't the easiest way to define such behavior so i need a help . 我写了一种方法来计算卖出货币兑换过程的平均值和它的标准差,但是我认为这不是定义这种行为的最简单方法,因此我需要帮助。

  1. In my opinion there is too much creating Bigdecimal values . 我认为创建Bigdecimal值太多了。

  2. I have also doubts about use Arraylist to getting values in order to count standard deviation , maybe it is better data structure to achieve that goal . 我也对使用Arraylist来获取值以计算标准偏差存有疑问,也许达到该目标的数据结构更好。

The method contains also counting average of buy currency exchange-course(BID in parsed file) but don't focus on it please. 该方法还包括计算购买货币兑换过程的平均值(已解析文件中的BID),但请不要关注它。

package pl.parser.nbp;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Counting {
public void countAverageAndStandartDeviaton(String address){
    try
    {
        DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = df.newDocumentBuilder();
        Document doc = db.parse(address);
        doc.getDocumentElement().normalize();

        NodeList nList = doc.getElementsByTagName("Rate");

        List<BigDecimal> listForStandartDeviation = new ArrayList<>();
        BigDecimal averageOfBid = new BigDecimal("0");
        BigDecimal averageOfAsk = new BigDecimal("0");
        BigDecimal divisor = new BigDecimal(nList.getLength());

        for (int temp = 0; temp < nList.getLength(); temp++) {

            Node nNode = nList.item(temp);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                Element eElement = (Element) nNode;

                BigDecimal valueForBidAverage = new BigDecimal(eElement.getElementsByTagName("Bid").item(0).getTextContent());
                BigDecimal valueForStandartDeviation = new BigDecimal(eElement.getElementsByTagName("Ask").item(0).getTextContent());
                averageOfBid = averageOfBid.add(valueForBidAverage);
                averageOfAsk = averageOfAsk.add(valueForStandartDeviation);
                listForStandartDeviation.add(valueForStandartDeviation);


            }
        }
        averageOfBid = new BigDecimal(averageOfBid.divide(divisor).toString()).setScale(4, RoundingMode.HALF_UP);
        averageOfAsk = new BigDecimal(averageOfAsk.divide(divisor).toString());
        System.out.println(averageOfBid + " - BID Average");

        BigDecimal sumStandartDeviation = new BigDecimal("0");
        for(int i = 0 ; i<listForStandartDeviation.size(); i++){
            BigDecimal valueFromList = new BigDecimal(listForStandartDeviation.get(i).toString());
            sumStandartDeviation = sumStandartDeviation.add((valueFromList.subtract(averageOfAsk)).pow(2));
        }
        sumStandartDeviation = sumStandartDeviation.divide(divisor);
        sumStandartDeviation = new BigDecimal(Math.sqrt(sumStandartDeviation.doubleValue()))
                .setScale(4, RoundingMode.HALF_UP);
        System.out.println(sumStandartDeviation +  " - ASK Standart Deviation");

    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}

It's not clear to me why you want to do so much of the calculation using BigDecimal rather than double arithmetic, when you end up reverting to double arithmetic to compute the square root anyway. 对我来说,目前还不清楚为什么要使用BigDecimal而不是双精度算法来进行大量计算,而最终还是要转换为双精度算法以计算平方根。

Here's an XPath 3.1 solution (which can of course be invoked easily from Java): 这是XPath 3.1解决方案(当然可以从Java轻松调用它):

let $rates := //Rate
return (avg($rates/Bid), math:sqrt(sum($rates/(Ask*Ask))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM