Java 实现数据统计的常用算法

做数据处理的人可能经常用到一些比如求中位数、众数、均值等等的常用数学方法,下面整理一些算法,由于都比较简单,不做过多的解释了,直接拿去用就好啦!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package cn.javacodes.utils;


import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* 数据统计工具类
* @author 胡湛霏
* @since 2016-09-27
*/
public class DataStatisticsUtils {
/**
* 求和
*
* @param arr
* @return
*/
public static double getSum(double[] arr) {
double sum = 0;
for (double num : arr) {
sum += num;
}
return sum;
}

/**
* 求均值
*
* @param arr
* @return
*/
public static double getMean(double[] arr) {
return getSum(arr) / arr.length;
}

/**
* 求众数
*
* @param arr
* @return
*/
public static double getMode(double[] arr) {
Map<Double, Integer> map = new HashMap<Double, Integer>();
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(arr[i])) {
map.put(arr[i], map.get(arr[i]) + 1);
} else {
map.put(arr[i], 1);
}
}
int maxCount = 0;
double mode = -1;
Iterator<Double> iter = map.keySet().iterator();
while (iter.hasNext()) {
double num = iter.next();
int count = map.get(num);
if (count > maxCount) {
maxCount = count;
mode = num;
}
}
return mode;
}

/**
* 求中位数
*
* @param arr
* @return
*/
public static double getMedian(double[] arr) {
double[] tempArr = Arrays.copyOf(arr, arr.length);
Arrays.sort(tempArr);
if (tempArr.length % 2 == 0) {
return (tempArr[tempArr.length >> 1] + tempArr[(tempArr.length >> 1) - 1]) / 2;
} else {
return tempArr[(tempArr.length >> 1)];
}
}


/**
* 求中列数
*
* @param arr
* @return
*/
public static double getMidrange(double[] arr) {
double max = arr[0], min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
return (min + max) / 2;
}

/**
* 求四分位数
*
* @param arr
* @return 存放三个四分位数的数组
*/
public static double[] getQuartiles(double[] arr) {
double[] tempArr = Arrays.copyOf(arr, arr.length);
Arrays.sort(tempArr);
double[] quartiles = new double[3];
// 第二四分位数(中位数)
quartiles[1] = getMedian(tempArr);
// 求另外两个四分位数
if (tempArr.length % 2 == 0) {
quartiles[0] = getMedian(Arrays.copyOfRange(tempArr, 0, tempArr.length / 2));
quartiles[2] = getMedian(Arrays.copyOfRange(tempArr, tempArr.length / 2, tempArr.length));
} else {
quartiles[0] = getMedian(Arrays.copyOfRange(tempArr, 0, tempArr.length / 2));
quartiles[2] = getMedian(Arrays.copyOfRange(tempArr, tempArr.length / 2 + 1, tempArr.length));
}
return quartiles;
}

/**
* 求极差
*
* @param arr
* @return
*/
public static double getRange(double[] arr) {
double max = arr[0], min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
return max - min;
}

/**
* 求四分位数极差
*
* @param arr
* @return
*/
public static double getQuartilesRange(double[] arr) {
return getRange(getQuartiles(arr));
}

/**
* 求截断均值
*
* @param arr 求值数组
* @param p 截断量p,例如p的值为20,则截断20%(高10%,低10%)
* @return
*/
public static double getTrimmedMean(double[] arr, int p) {
int tmp = arr.length * p / 100;
double[] tempArr = Arrays.copyOfRange(arr, tmp, arr.length + 1 - tmp);
return getMean(tempArr);
}

/**
* 求方差
*
* @param arr
* @return
*/
public static double getVariance(double[] arr) {
double variance = 0;
double sum = 0, sum2 = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
sum2 += arr[i] * arr[i];
}
variance = sum2 / arr.length - (sum / arr.length) * (sum / arr.length);
return variance;
}

/**
* 求绝对平均偏差(AAD)
*
* @param arr
* @return
*/
public static double getAbsoluteAverageDeviation(double[] arr) {
double sum = 0;
double mean = getMean(arr);
for (int i = 0; i < arr.length; i++) {
sum += Math.abs(arr[i] - mean);
}
return sum / arr.length;
}

/**
* 求中位数绝对偏差(MAD)
*
* @param arr
* @return
*/
public static double getMedianAbsoluteDeviation(double[] arr) {
double[] tempArr = new double[arr.length];
double median = getMedian(arr);
for (int i = 0; i < arr.length; i++) {
tempArr[i] = Math.abs(arr[i] - median);
}
return getMedian(tempArr);
}

/**
* 求标准差
* @param arr
* @return
*/
public static double getStandardDevition(double[] arr) {
double sum = 0;
double mean = getMean(arr);
for (int i = 0; i < arr.length; i++) {
sum += Math.sqrt((arr[i] - mean) * (arr[i] - mean));
}
return (sum / (arr.length - 1));
}


}

下面还有一些做数据规范化的代码整理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package cn.javacodes.utils;

import java.util.Arrays;

/**
* 数据变化\-规范化工具类
* @author 胡湛霏
* @since 2016-09-27
*/
public class DataConversionUtils {

/**
* 最小\-最大规范化
*
* @param arr
* @return 规范化后的数组
*/
public static double[] minMaxNormalize(double[] arr) {
// 拷贝数组
double[] tempArr = Arrays.copyOf(arr, arr.length);
// 找到最大值和最小值
double max = tempArr[0], min = tempArr[0];
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] > max) {
max = tempArr[i];
}
if (tempArr[i] < min) {
min = tempArr[i];
}
}
// 规范化
for (int i = 0; i < tempArr.length; i++) {
tempArr[i] = (tempArr[i] - min) / (max - min);
}
return tempArr;
}


/**
* Z-score规范化
* @param arr
* @return 规范化后的数组
*/
public static double[] zScoreNormalize(double[] arr) {
// 拷贝数组
double[] tempArr = Arrays.copyOf(arr, arr.length);
// 求均值
double sum = 0;
for (double num : tempArr) {
sum += num;
}
double mean = sum / tempArr.length;
// 求标准差
double sum2 = 0;
for (int i = 0; i < tempArr.length; i++) {
sum2 += Math.sqrt((tempArr[i] - mean) * (tempArr[i] - mean));
}
double standardDivition = sum2 / (tempArr.length - 1);
// 标准化
for (int i = 0; i < tempArr.length; i++) {
tempArr[i] = (tempArr[i] - mean) / standardDivition;
}
return tempArr;

}

/**
* 小数定标规范化
* @param arr
* @return 规范化后的数组
*/
public static double[] decimalsNormalize(double[] arr){
// 拷贝数组
double[] tempArr = Arrays.copyOf(arr, arr.length);
// 找到最大值
double max = tempArr[0];
for (int i = 0; i < tempArr.length; i++) {
if (tempArr[i] > max) {
max = tempArr[i];
}
}
// 确定j的值(j为使max(|v'|)<1的最小整数)
int j = 0;
while (Math.abs(max/Math.pow(10,j))>=1){
j++;
}
// 规范化
for (int i = 0; i < tempArr.length; i++) {
tempArr[i] = tempArr[i] / Math.pow(10,j);
}
return tempArr;

}


}