我有一个DataFrame:
time_diff avg_trips
0 0.450000 1.0
1 0.483333 1.0
2 0.500000 1.0
3 0.516667 1.0
4 0.533333 2.0
我想获取列time_diff
的第一四分位数、第三四分位数和中位数。要获取中位数,我使用np.median(df["time_diff"].values)
。
我该如何计算四分位数?
我有一个DataFrame:
time_diff avg_trips
0 0.450000 1.0
1 0.483333 1.0
2 0.500000 1.0
3 0.516667 1.0
4 0.533333 2.0
我想获取列time_diff
的第一四分位数、第三四分位数和中位数。要获取中位数,我使用np.median(df["time_diff"].values)
。
我该如何计算四分位数?
通过使用pandas
:
df.time_diff.quantile([0.25,0.5,0.75])
Out[793]:
0.25 0.483333
0.50 0.500000
0.75 0.516667
Name: time_diff, dtype: float64
df.quantile(q=[0.25, 0.75], axis=0, numeric_only=True, interpolation='midpoint')
-- 这会为数据框计算Q1和Q3(每个序列分别)。 - RAM237AttributeError: 'DataFrame'对象没有'time_diff'属性
。 - Charlie Parkernp.percentile
来计算四分位数(包括中位数):>>> np.percentile(df.time_diff, 25) # Q1
0.48333300000000001
>>> np.percentile(df.time_diff, 50) # median
0.5
>>> np.percentile(df.time_diff, 75) # Q3
0.51666699999999999
或者一次性完成:
>>> np.percentile(df.time_diff, [25, 50, 75])
array([ 0.483333, 0.5 , 0.516667])
恰巧,这个信息可以使用describe
方法进行捕获:
df.time_diff.describe()
count 5.000000
mean 0.496667
std 0.032059
min 0.450000
25% 0.483333
50% 0.500000
75% 0.516667
max 0.533333
Name: time_diff, dtype: float64
my_mean
和my_firstquartile
? - 3kstcmy_mean = df.time_diff.describe()[1]
my_firstquartile = df.time_diff.describe()[4]
- MSaltynp.percentile
不计算 Q1、中位数和Q3的值。考虑以下排序后的列表:
samples = [1, 1, 8, 12, 13, 13, 14, 16, 19, 22, 27, 28, 31]
运行 np.percentile(samples, [25, 50, 75])
返回列表中的实际值:
Out[1]: array([12., 14., 22.])
然而,四分位数为Q1=10.0,中位数=14,Q3=24.5
(您也可以使用此链接在线查找四分位数和中位数)。
可以使用以下代码计算排序列表的四分位数和中位数(由于排序,此方法需要O(nlogn)
计算,其中n
是项数)。
此外,使用中位数选择算法(顺序统计)可以进行O(n)
计算来查找四分位数和中位数。
samples = sorted([28, 12, 8, 27, 16, 31, 14, 13, 19, 1, 1, 22, 13])
def find_median(sorted_list):
indices = []
list_size = len(sorted_list)
median = 0
if list_size % 2 == 0:
indices.append(int(list_size / 2) - 1) # -1 because index starts from 0
indices.append(int(list_size / 2))
median = (sorted_list[indices[0]] + sorted_list[indices[1]]) / 2
pass
else:
indices.append(int(list_size / 2))
median = sorted_list[indices[0]]
pass
return median, indices
pass
median, median_indices = find_median(samples)
Q1, Q1_indices = find_median(samples[:median_indices[0]])
Q3, Q3_indices = find_median(samples[median_indices[-1] + 1:])
quartiles = [Q1, median, Q3]
print("(Q1, median, Q3): {}".format(quartiles))
describe
没有输出精确的四分位值,直到我想到第25个百分位数并不等于Q1。干得好! - Wladston Ferreira Filhonp.percentile
做的就是它该做的... 如果你习惯于使用中点的“定义”... 只需检查 numpy 文档的链接以查看正确的签名即可。 - cards基于或者说是在Babak所说的基础上做出一点修正....
np.percentile 非常明确地 计算Q1,中位数和Q3的值。请考虑以下排序后的列表:
s1=[18,45,66,70,76,83,88,90,90,95,95,98]
运行np.percentile(s1, [25, 50, 75])
会返回列表中的实际值:
[69. 85.5 91.25]
然而,四分位数为Q1=68.0、中位数=85.5、Q3=92.5,这是需要说的正确事情。
我们在这里缺少的是np.percentile
和相关函数的插值参数。默认情况下,此参数的值为线性。这个可选参数指定了当所需分位数位于两个数据点i<j之间时要使用的插值方法:
线性:i + (j - i) * fraction,其中fraction是被i和j包围的索引的小数部分。
lower:i。
higher:j。
nearest:最近的i或j。
midpoint:(i + j)/2。
因此,使用np.percentile(s1, [25, 50, 75], interpolation='midpoint')
运行将返回列表的实际结果:
[68. 85.5 92.5]
numpy
>= 1.22 开始,interpolation
已被弃用,请使用 method
替代。详情请参见我的回答。 - cards >>> import statistics as stat
>>> def quartile(data):
data.sort()
half_list = int(len(data)//2)
upper_quartile = stat.median(data[-half_list:])
lower_quartile = stat.median(data[:half_list])
print("Lower Quartile: "+str(lower_quartile))
print("Upper Quartile: "+str(upper_quartile))
print("Interquartile Range: "+str(upper_quartile-lower_quartile)
>>> quartile(df.time_diff)
upper_quartile = stat.median(data[-half_list:])
(需要冒号来定义切片)。 - zvxrupper_quartile = stat.median(data[-half_list:])
(需要冒号来定义切片)。 - undefined在学习统计学和面向对象编程的过程中,我做了这个东西,也许你会觉得它有用:
最初的回答:
samplesCourse = [9, 10, 10, 11, 13, 15, 16, 19, 19, 21, 23, 28, 30, 33, 34, 36, 44, 45, 47, 60]
class sampleSet:
def __init__(self, sampleList):
self.sampleList = sampleList
self.interList = list(sampleList) # interList is sampleList alias; alias used to maintain integrity of original sampleList
def find_median(self):
self.median = 0
if len(self.sampleList) % 2 == 0:
# find median for even-numbered sample list length
self.medL = self.interList[int(len(self.interList)/2)-1]
self.medU = self.interList[int(len(self.interList)/2)]
self.median = (self.medL + self.medU)/2
else:
# find median for odd-numbered sample list length
self.median = self.interList[int((len(self.interList)-1)/2)]
return self.median
def find_1stQuartile(self, median):
self.lower50List = []
self.Q1 = 0
# break out lower 50 percentile from sampleList
if len(self.interList) % 2 == 0:
self.lower50List = self.interList[:int(len(self.interList)/2)]
else:
# drop median to make list ready to divide into 50 percentiles
self.interList.pop(interList.index(self.median))
self.lower50List = self.interList[:int(len(self.interList)/2)]
# find 1st quartile (median of lower 50 percentiles)
if len(self.lower50List) % 2 == 0:
self.Q1L = self.lower50List[int(len(self.lower50List)/2)-1]
self.Q1U = self.lower50List[int(len(self.lower50List)/2)]
self.Q1 = (self.Q1L + self.Q1U)/2
else:
self.Q1 = self.lower50List[int((len(self.lower50List)-1)/2)]
return self.Q1
def find_3rdQuartile(self, median):
self.upper50List = []
self.Q3 = 0
# break out upper 50 percentile from sampleList
if len(self.sampleList) % 2 == 0:
self.upper50List = self.interList[int(len(self.interList)/2):]
else:
self.interList.pop(interList.index(self.median))
self.upper50List = self.interList[int(len(self.interList)/2):]
# find 3rd quartile (median of upper 50 percentiles)
if len(self.upper50List) % 2 == 0:
self.Q3L = self.upper50List[int(len(self.upper50List)/2)-1]
self.Q3U = self.upper50List[int(len(self.upper50List)/2)]
self.Q3 = (self.Q3L + self.Q3U)/2
else:
self.Q3 = self.upper50List[int((len(self.upper50List)-1)/2)]
return self.Q3
def find_InterQuartileRange(self, Q1, Q3):
self.IQR = self.Q3 - self.Q1
return self.IQR
def find_UpperFence(self, Q3, IQR):
self.fence = self.Q3 + 1.5 * self.IQR
return self.fence
samples = sampleSet(samplesCourse)
median = samples.find_median()
firstQ = samples.find_1stQuartile(median)
thirdQ = samples.find_3rdQuartile(median)
iqr = samples.find_InterQuartileRange(firstQ, thirdQ)
fence = samples.find_UpperFence(thirdQ, iqr)
print("Median is: ", median)
print("1st quartile is: ", firstQ)
print("3rd quartile is: ", thirdQ)
print("IQR is: ", iqr)
print("Upper fence is: ", fence)
使用Python统计模块可以轻松完成此操作。 https://docs.python.org/3/library/statistics.html
import statistics
time_diff = [0.45,0.483333,0.5,0.516667,0.5333333]
statistics.quantiles(time_diff, method='inclusive')
[0.483333, 0.5, 0.516667]
以上默认为4组数据(n=4),有3个分割点(第一四分位数、中位数、第三四分位数),并将方法设置为包含,使用列表中的所有数据。 输出是第一四分位数、中位数和第三四分位数的列表。
pd.qcut
。 - cs95AttributeError: 'Series' object has no attribute 'time_diff'
。 - Charlie Parker