A beginner here looking for some help with getting statistics from a list of tuples, where a tuple contains names and the data.
I have a list of the following format:
list = [(name1, name2, name3, name(...), value1, value2, value3, value(...))]
Example:
mylist = [('red', 1, 100, 0.075, 0.055, 1.88),
('red', 1, 100, 0.0825, 0.05, 1.84),
('red', 1, 2, 3.7, 0.08, 4.20),
('green', 2, 2, 0.37, 0.8, 0.9),
('green', 2, 2, 0.85, 0.35, 1.24)]
What I need is means and standard deviations of values from tuples where the names are identical.
The output should be:
output = [(name1, name2, name3, name(...), value1_mean, value1_stdev, value2_mean, value2_stdev, value3_mean, value3_stdev, value(...)_mean, value(...)_stdev)]
For all unique name1, name2, name3, name(...) combinations.
In the case of the list above the desired output is the following:
output = [('green', 2, 2, 0.61, 0.33941125496954283, 0.575, 0.3181980515339464, 1.07, 0.2404163056034261),
('red', 1, 2, 3.7, 0, 0.08, 0, 4.2, 0),
('red', 1, 100, 0.07875, 0.005303300858899111, 0.052500000000000005, 0.003535533905932736, 1.8599999999999999, 0.02828427124746177)]
I managed to get this to work, not in an elegant way, where I am limited to 3 names and 3 values:
import statistics
mylist = [('red', 1, 100, 0.075, 0.055, 1.88),
('red', 1, 100, 0.0825, 0.05, 1.84),
('red', 1, 2, 3.7, 0.08, 4.20),
('green', 2, 2, 0.37, 0.8, 0.9),
('green', 2, 2, 0.85, 0.35, 1.24)]
d_0 = []
d_1 = []
d_2 = []
for i in mylist:
d_0.append(i[0])
d_1.append(i[1])
d_2.append(i[2])
s_d_0 = set(d_0)
s_d_1 = set(d_1)
s_d_2 = set(d_2)
for d0 in s_d_0:
for d1 in s_d_1:
for d2 in s_d_2:
for c in [3,4,5]:
exec('v' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = []')
results = []
for t in mylist:
for d0 in s_d_0:
for d1 in s_d_1:
for d2 in s_d_2:
if d0 == t[0] and d1 == t[1] and d2 == t[2]:
for c in [3,4,5]:
exec('v' + str(c) + '_' + str(d0) + str(d1) + str(d2) + '.append( t[' + str(c) + '])')
for d0 in s_d_0:
for d1 in s_d_1:
for d2 in s_d_2:
asd = [d0, d1, d2]
for c in [3, 4, 5]:
length = 0
exec('length = len(v' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ')')
if length == 0:
exec('mean' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = 0')
exec('stdev' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = 0')
if not length == 0:
exec('mean' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = statistics.mean(v' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ')')
exec('stdev' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = 0')
if not length == 1 and not length == 0:
exec('stdev' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ' = statistics.stdev(v' + str(
c) + '_' + str(d0) + str(d1) + str(d2) + ')')
exec('fgh = (mean' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ', stdev' + str(c) + '_' + str(d0) + str(d1) + str(d2) + ')')
asd.append(fgh)
results.append(asd)
final = []
for z in results:
if z[3][0] is not 0:
final.append(z)
output = []
for fin in final:
final3 = []
for fiin in fin:
if not isinstance(fiin, tuple):
final3.append(fiin)
if isinstance(fiin, tuple):
fiin1, fiin2 = fiin[0], fiin[1]
final3.append(fiin1)
final3.append(fiin2)
output.append(tuple(final3))
for f in output:
print(f)
Is there a way of obtaining the same output in a more robust way, perhaps using numpy or pandas? Preferably where I could specify a number different than 3 for how many of the left values of the tuple define names.
Thanks!