Статистика для данных в нескольких кортежах имен и данных - PullRequest
0 голосов
/ 07 ноября 2018

Новичок здесь ищет некоторую помощь в получении статистики из списка кортежей, где кортеж содержит имена и данные.

У меня есть список следующего формата:

list = [(name1, name2, name3, name(...), value1, value2, value3, value(...))]

Пример:

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)]

Мне нужны средства и стандартные отклонения значений от кортежей, имена которых идентичны.

Вывод должен быть:

output = [(name1, name2, name3, name(...), value1_mean, value1_stdev, value2_mean, value2_stdev, value3_mean, value3_stdev, value(...)_mean, value(...)_stdev)]

Для всех уникальных комбинаций name1, name2, name3, name(...).

В случае списка выше желаемым выводом является следующее:

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)]

Мне удалось заставить это работать, не изящным способом, где я ограничен 3 именами и 3 значениями:

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)

Есть ли способ получить тот же вывод более надежным способом, возможно, используя numpy или pandas? Предпочтительно, чтобы я мог указать число, отличное от 3, для того, сколько левых значений кортежа определяют names.

Спасибо!

1 Ответ

0 голосов
/ 07 ноября 2018

Я не уверен, что задаю вам вопрос очень точно. Следующая функция принимает ваш myList в качестве аргумента и возвращает

output = [(name1, name2, name3, name(...), value1_mean, value1_stdev, value2_mean, value2_stdev, value3_mean, value3_stdev, value(...)_mean, value(...)_stdev)]
import numpy as np

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)]

def getStats(myList):
    # dict containing mean and std for each name, ie dico[name1][value_number]=[list of value_numbers]
    dico={}

    # Fill dico
    for t in myList: # For each tuple
        name=t[0] # Get the name
        if name not in dico: # Check wether the name is already registered in dico. If not, add it
            dico[name]={nv:[] for nv in range(len(t)-1)}

        l=[]
        for nval in range(len(t)-1): # Browse values
            dico[name][nval].append(t[nval+1]) # Store them at the right place in dico

    # Create the output
    output=[]

    # Fill output
    for name in dico: # Browse through dico's names
        lval=[name]
        for nval in dico[name]: # For each value_i from tuple
            l=dico[name][nval]
            mu=np.mean(l) # Compute mean...
            std=np.std(l) # ... and standard deviation thanks to NumPy
            lval.append(mu)
            lval.append(std)
        output.append(tuple(lval)) # Format output to match your desires

    return(output)

>>> getStats(mylist)
[('red', 1.0, 0.0, 67.33333333333333, 46.197643037521104, 1.2858333333333334, 1.7070763668395805, 0.06166666666666667, 0.013123346456686353, 2.64, 1.1032074449833391), ('green', 2.0, 0.0, 2.0, 0.0, 0.61, 0.24, 0.575, 0.22500000000000003, 1.07, 0.16999999999999998)]

Надеюсь, что это будет соответствовать вашим потребностям! Я рекомендую вам погрузиться в использование dict [https://www.w3schools.com/python/python_dictionaries.asp], чтобы узнать больше об этом мощном инструменте, особенно когда вам приходится иметь дело с многомерным набором данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...