我想要做的是获得我的数字的每一半的中间.所以我已经创建了一种方法来获得数字的中间值(数学术语的中位数);
public static String Find_Median()
{
double Size = list.Count;
double Final_Number = 0;
if (Size % 2 == 0)
{
int HalfWay = list.Count / 2;
double Value1 = Convert.ToDouble(list[HalfWay - 1].ToString());
double Value2 = Convert.ToDouble(list[HalfWay - 1 + 1].ToString());
double Number = Value1 + Value2;
Final_Number = Number / 2;
}
else
{
int HalfWay = list.Count / 2;
double Value1 = Convert.ToDouble(list[HalfWay].ToString());
Final_Number = Value1;
}
return Convert.ToString(Final_Number);
}
Run Code Online (Sandbox Code Playgroud)
这得到了列表中所有数字的确切中间数,即使它到达中间也会进行数学运算.我想双方都这样做; 这是一个例子;
3 2 1 4 5 6
Run Code Online (Sandbox Code Playgroud)
该列表的中间(中位数)是3.5.我想用数学来找到2,它位于等式的开始和中间之间.也称为IQR中的Q1.我也想知道如何在中位数(中间)和结尾之间找到中间数字,即5.

IE所以我可以找到70,80和90代码.
我刚刚遇到了同样的问题,并检查了Quartile的维基百科条目,它比它首次出现时要复杂一些.
我的方法如下:(对于所有情况似乎都很好,N = 1)...
/// <summary>
/// Return the quartile values of an ordered set of doubles
/// assume the sorting has already been done.
///
/// This actually turns out to be a bit of a PITA, because there is no universal agreement
/// on choosing the quartile values. In the case of odd values, some count the median value
/// in finding the 1st and 3rd quartile and some discard the median value.
/// the two different methods result in two different answers.
/// The below method produces the arithmatic mean of the two methods, and insures the median
/// is given it's correct weight so that the median changes as smoothly as possible as
/// more data ppints are added.
///
/// This method uses the following logic:
///
/// ===If there are an even number of data points:
/// Use the median to divide the ordered data set into two halves.
/// The lower quartile value is the median of the lower half of the data.
/// The upper quartile value is the median of the upper half of the data.
///
/// ===If there are (4n+1) data points:
/// The lower quartile is 25% of the nth data value plus 75% of the (n+1)th data value.
/// The upper quartile is 75% of the (3n+1)th data point plus 25% of the (3n+2)th data point.
///
///===If there are (4n+3) data points:
/// The lower quartile is 75% of the (n+1)th data value plus 25% of the (n+2)th data value.
/// The upper quartile is 25% of the (3n+2)th data point plus 75% of the (3n+3)th data point.
///
/// </summary>
internal Tuple<double, double, double> Quartiles(double[] afVal)
{
int iSize = afVal.Length;
int iMid = iSize / 2; //this is the mid from a zero based index, eg mid of 7 = 3;
double fQ1 = 0;
double fQ2 = 0;
double fQ3 = 0;
if (iSize % 2 == 0)
{
//================ EVEN NUMBER OF POINTS: =====================
//even between low and high point
fQ2 = (afVal[iMid - 1] + afVal[iMid]) / 2;
int iMidMid = iMid / 2;
//easy split
if (iMid % 2 == 0)
{
fQ1 = (afVal[iMidMid - 1] + afVal[iMidMid]) / 2;
fQ3 = (afVal[iMid + iMidMid - 1] + afVal[iMid + iMidMid]) / 2;
}
else
{
fQ1 = afVal[iMidMid];
fQ3 = afVal[iMidMid + iMid];
}
}
else if (iSize == 1)
{
//================= special case, sorry ================
fQ1 = afVal[0];
fQ2 = afVal[0];
fQ3 = afVal[0];
}
else
{
//odd number so the median is just the midpoint in the array.
fQ2 = afVal[iMid];
if ((iSize - 1) % 4 == 0)
{
//======================(4n-1) POINTS =========================
int n = (iSize - 1) / 4;
fQ1 = (afVal[n - 1] * .25) + (afVal[n] * .75);
fQ3 = (afVal[3 * n] * .75) + (afVal[3 * n + 1] * .25);
}
else if ((iSize - 3) % 4 == 0)
{
//======================(4n-3) POINTS =========================
int n = (iSize - 3) / 4;
fQ1 = (afVal[n] * .75) + (afVal[n + 1] * .25);
fQ3 = (afVal[3 * n + 1] * .25) + (afVal[3 * n + 2] * .75);
}
}
return new Tuple<double, double, double>(fQ1, fQ2, fQ3);
}
Run Code Online (Sandbox Code Playgroud)
有多种方法可以计算四分位数:
我在这里尽力实现Quartiles的版本,Quartile(array, type=8)在R文档中描述为type = 8 :https://www.rdocumentation.org/packages/stats/versions/3.5.1/topics/quantile.这种方法是这里描述的R函数的作者的首选,因为它在值之间产生更平滑的过渡.但是,R默认为方法7,这与S和Excel使用的功能相同.
如果你只是谷歌搜索答案而不考虑输出意味着什么,或者你想要达到什么结果,这可能会给你一个惊喜.
我知道这是一个老问题,所以我争论是否应该添加下面的答案一段时间,并且由于投票最多的答案与 Excel 四分位数的数字不匹配,我决定发布下面的答案。
\n\n我还需要找到第一和第三四分位数,因为我正在尝试绘制直方图并创建箱宽度和范围,我正在使用 Freedman\xe2\x80\x93Diaconis 规则,该规则需要知道第一和第三四分位数。我从迈克的回答开始。
\n\n但在数据验证过程中,我注意到结果与 Excel 中四分位数的计算方式以及使用Plotly创建的直方图不匹配,因此我进一步挖掘并偶然发现了以下两个链接:
\n\n\n\n第二个链接中的幻灯片 12 指出“第 P 个百分位数的位置由 给出(n + 1)P/100,其中 n 是集合中的观测值数量。”
因此,C# 描述性统计类中的等效 C# 代码是:
\n\n /// <summary>\n /// Calculate percentile of a sorted data set\n /// </summary>\n /// <param name="sortedData"></param>\n /// <param name="p"></param>\n /// <returns></returns>\n internal static double Percentile(double[] sortedData, double p)\n {\n // algo derived from Aczel pg 15 bottom\n if (p >= 100.0d) return sortedData[sortedData.Length - 1];\n\n double position = (sortedData.Length + 1) * p / 100.0;\n double leftNumber = 0.0d, rightNumber = 0.0d;\n\n double n = p / 100.0d * (sortedData.Length - 1) + 1.0d;\n\n if (position >= 1)\n {\n leftNumber = sortedData[(int)Math.Floor(n) - 1];\n rightNumber = sortedData[(int)Math.Floor(n)];\n }\n else\n {\n leftNumber = sortedData[0]; // first data\n rightNumber = sortedData[1]; // first data\n }\n\n //if (leftNumber == rightNumber)\n if (Equals(leftNumber, rightNumber))\n return leftNumber;\n double part = n - Math.Floor(n);\n return leftNumber + part * (rightNumber - leftNumber);\n } // end of internal function percentile\nRun Code Online (Sandbox Code Playgroud)\n\n测试用例(用 Visual Studio 2017 编写):
\n\n static void Main()\n {\n double[] x = { 18, 18, 18, 18, 19, 20, 20, 20, 21, 22, 22, 23, 24, 26, 27, 32, 33, 49, 52, 56 };\n var q1 = Percentile(x, 25);\n var q2 = Percentile(x, 50);\n var q3 = Percentile(x, 75);\n var iqr = q3 - q1;\n\n var (q1_mike, q2_mike, q3_mike) = Quartiles(x); //Uses named tuples instead of regular Tuple\n var iqr_mike = q3_mike - q1_mike;\n }\nRun Code Online (Sandbox Code Playgroud)\n\n结果对比:
\n\n您会注意到 Excel 的结果与幻灯片 12 中提到的统计理论相匹配。
\n\n对以下列表运行相同的方法:
list1 = list.Where(x => x < Median)
list2 = list.Where(x => x > Median)
Run Code Online (Sandbox Code Playgroud)
Find_Median(list1)将返回第一个四分位数,
Find_Median(list2)将返回第三个四分位数
| 归档时间: |
|
| 查看次数: |
9012 次 |
| 最近记录: |