Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/simple_stats.py : 28%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2012-2019 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
7# Simple statistical functions
9import math
11def to_std_unit(v, unit=1000):
12 if v>=unit**3:
13 return "G", v//(unit**3)
14 if v>=unit**2:
15 return "M", v//(unit**2)
16 if v>=unit:
17 return "K", v//unit
18 return "", v
20def std_unit(v, unit=1000) -> str:
21 unit, value = to_std_unit(v, unit)
22 return "%s%s" % (int(value), unit)
24def std_unit_dec(v):
25 unit, value = to_std_unit(v*10.0)
26 if value>=100:
27 return "%s%s" % (int(value//10), unit)
28 if int(value)%10==0:
29 return "%s%s" % (int(value/10), unit)
30 return "%s%s" % (int(value)/10.0, unit)
33def absolute_to_diff_values(in_data):
34 """ Given a list of values, return a new list
35 containing the incremental diff between each value
36 ie: [0,2,2,10] -> [2,0,8]
37 """
38 last_value = None
39 data = []
40 for x in in_data:
41 if last_value is not None:
42 data.append(x-last_value)
43 last_value = x
44 return data
46def values_to_scaled_values(data, scale_unit=10, min_scaled_value=10, num_values=20):
47 #print("values_to_scaled_values(%s, %s, %s)" % (data, scale_unit, num_values))
48 if not data:
49 return 0, data
50 max_v = max(data)
51 #pad with None values so we have at least num_values:
52 if len(data)<num_values:
53 if isinstance(data, tuple):
54 data = list(data)
55 for _ in range(num_values-len(data)):
56 data.insert(0, None)
57 scale = 1
58 assert scale_unit>1
59 while scale*scale_unit*min_scaled_value<=max_v:
60 scale *= scale_unit
61 if scale==1:
62 return scale, data
63 sdata = []
64 for x in data:
65 if x is None:
66 sdata.append(None)
67 else:
68 sdata.append(x/scale)
69 return scale, sdata
71def values_to_diff_scaled_values(data, scale_unit=10, min_scaled_value=10, num_values=20):
72 return values_to_scaled_values(absolute_to_diff_values(data), scale_unit=scale_unit, min_scaled_value=min_scaled_value, num_values=num_values)
74def get_weighted_list_stats(weighted_values, show_percentile=False):
75 values = tuple(x[0] for x in weighted_values)
76 if not values:
77 return {}
78 #weighted mean:
79 tw = 0
80 tv = 0
81 for v, w in weighted_values:
82 tw += w
83 tv += v * w
84 avg = tv/tw
85 stats = {
86 "min" : int(min(values)),
87 "max" : int(max(values)),
88 "avg" : int(avg),
89 }
90 if show_percentile:
91 #percentile
92 svalues = sorted(values)
93 for i in range(1,10):
94 pct = i*10
95 index = len(values)*i//10
96 stats["%ip" % pct] = int(svalues[index])
97 return stats
100def find_invpow(x, n):
101 """Finds the integer component of the n'th root of x,
102 an integer such that y ** n <= x < (y + 1) ** n.
103 """
104 high = 1
105 while high ** n < x:
106 high *= 2
107 low = high/2
108 while low < high:
109 mid = (low + high) // 2
110 if low < mid and mid**n < x:
111 low = mid
112 elif high > mid and mid**n > x:
113 high = mid
114 else:
115 return mid
116 return mid + 1
118def get_list_stats(in_values, show_percentile=(5, 8, 9), show_dev=False):
119 #this may be backed by a deque/list whichi is used by other threads
120 #so make a copy before use:
121 values = tuple(in_values)
122 if not values:
123 return {}
124 #arithmetic mean
125 avg = sum(values)/len(values)
126 lstats = {
127 "cur" : int(values[-1]),
128 "min" : int(min(values)),
129 "max" : int(max(values)),
130 "avg" : int(avg),
131 }
132 if show_dev:
133 p = 1 #geometric mean
134 h = 0 #harmonic mean
135 var = 0 #variance
136 counter = 0
137 for x in values:
138 if x!=0:
139 p *= x
140 h += 1.0/x
141 counter += 1
142 var += (x-avg)**2
143 #standard deviation:
144 std = math.sqrt(var/len(values))
145 lstats["std"] = int(std)
146 if avg!=0:
147 #coefficient of variation
148 lstats["cv_pct"] = int(100.0*std/avg)
149 if counter>0 and p<float('inf'):
150 #geometric mean
151 try:
152 v = int(math.pow(p, 1.0/counter))
153 except OverflowError:
154 v = find_invpow(p, counter)
155 lstats["gm"] = v
156 if h!=0:
157 #harmonic mean
158 lstats["h"] = int(counter/h)
159 if show_percentile:
160 #percentile
161 svalues = sorted(values)
162 for i in show_percentile:
163 pct = i*10
164 index = len(values)*i//10
165 lstats["%ip" % pct] = int(svalues[index])
166 return lstats