Python - 在嵌套列表中查找具有唯一匹配值的列的平均值

时间:2013-04-16 13:44:06

标签: python list unique identity-column

这与此问题非常相似:Finding minimum, maximum and average values for nested lists?

问题的重要区别和根源是我希望在列表(嵌套在列表中)中找到每个唯一列名称(人名)的最小值,最大值,平均值。

例如: 每一行基本上(具有类似的虚构名称) -

epochtime, name, score, level, extralives 

e.g。

    1234455, suzy, 120, 3, 0
    1234457, billy, 123, 1, 2
    1234459, billy, 124, 2, 4
    1234459, suzy, 224, 5, 4
    1234460, suzy, 301, 7, 1
    1234461, billy, 201, 3, 1

这些按时间列在一个列表中:

if epochtime < 1234500 and epochtime > 1234400:
        timechunk1.append(line)

每个时间块都有一个列表列表:

listoflists = [timechunk1, timechunk2....]

对于这个问题,这可能是也可能不是过分/无关。

如何为每个唯一名称(比利或suzy - )找到每个字段的最小值,最大值,平均值(,不仅仅是比利或suzy,所以它应该是最好不要在每个列表中单独列出)(timechunk1,timechunk2)?

2 个答案:

答案 0 :(得分:3)

pandas示例:

>>> import pandas as pd
>>> df = pd.read_csv("grouped.csv", sep="[,\s]*")
>>> df
   epochtime   name  score  level  extralives
0    1234455   suzy    120      3           0
1    1234457  billy    123      1           2
2    1234459  billy    124      2           4
3    1234459   suzy    224      5           4
4    1234460   suzy    301      7           1
5    1234461  billy    201      3           1
>>> g = df.groupby("name").describe()
>>> g
                  epochtime       score  level  extralives
name                                                      
billy count        3.000000    3.000000    3.0    3.000000
      mean   1234459.000000  149.333333    2.0    2.333333
      std          2.000000   44.747439    1.0    1.527525
      min    1234457.000000  123.000000    1.0    1.000000
      25%    1234458.000000  123.500000    1.5    1.500000
      50%    1234459.000000  124.000000    2.0    2.000000
      75%    1234460.000000  162.500000    2.5    3.000000
      max    1234461.000000  201.000000    3.0    4.000000
suzy  count        3.000000    3.000000    3.0    3.000000
      mean   1234458.000000  215.000000    5.0    1.666667
      std          2.645751   90.835015    2.0    2.081666
      min    1234455.000000  120.000000    3.0    0.000000
      25%    1234457.000000  172.000000    4.0    0.500000
      50%    1234459.000000  224.000000    5.0    1.000000
      75%    1234459.500000  262.500000    6.0    2.500000
      max    1234460.000000  301.000000    7.0    4.000000

或者简单地说:

>>> df.groupby("name").mean()
       epochtime       score  level  extralives
name                                           
billy    1234459  149.333333      2    2.333333
suzy     1234458  215.000000      5    1.666667

然后:

>>> g.ix[("billy","mean")]
epochtime     1234459.000000
score             149.333333
level               2.000000
extralives          2.333333
Name: (billy, mean), dtype: float64
>>> g.ix[("billy","mean")]["score"]
149.33333333333334
>>> g["score"]
name        
billy  count      3.000000
       mean     149.333333
       std       44.747439
       min      123.000000
       25%      123.500000
       50%      124.000000
       75%      162.500000
       max      201.000000
suzy   count      3.000000
       mean     215.000000
       std       90.835015
       min      120.000000
       25%      172.000000
       50%      224.000000
       75%      262.500000
       max      301.000000
Name: score, dtype: float64

等等。如果您正在考虑R / SQL方式,但想要使用Python,那么一定要尝试一下pandas。

请注意,您还可以执行多列groupbys:

>>> df.groupby(["epochtime", "name"]).mean()
                 score  level  extralives
epochtime name                           
1234455   suzy     120      3           0
1234457   billy    123      1           2
1234459   billy    124      2           4
          suzy     224      5           4
1234460   suzy     301      7           1
1234461   billy    201      3           1

答案 1 :(得分:2)

您必须收集每个字段的每个字段列表。

collections.defaultdict与工厂一起使用以创建嵌套列表:

from collections import defaultdict

columns = ('score', 'level', 'extralives')

def per_user_data():
    return {k: [] for k in columns}

stats_per_timechunk = []

for timechunk in listoflists:
    # group data per user, per column (user -> {c1: [], c2: [], c3: []})
    data = defaultdict(per_user_data)    
    for userdata in timechunk:
        per_user = data[userdata[1]]
        for column, value in zip(columns, userdata[2:]):
            per_user[column].append(value)

    # collect min, max and average stats per user, per column 
    # (user -> {c1: {min: 0, max: 0, avg: 0}, ..})
    stats = {}

    for user, per_user in data.iteritems():
        stats[user] = {column: {
                'min': min(per_user[column]),
                'max': max(per_user[column]),
                'avg': sum(per_user[column]) / float(len(per_user[column])),
            } for column in columns}

    stats_per_timechunk.append(stats)

将您的示例输入数据转储到一个时间段中,我得到了:

>>> pprint(stats_per_timechunk)
[{'billy': {'extralives': {'avg': 2.3333333333333335, 'max': 4, 'min': 1},
            'level': {'avg': 2.0, 'max': 3, 'min': 1},
            'score': {'avg': 149.33333333333334, 'max': 201, 'min': 123}},
  'suzy': {'extralives': {'avg': 1.6666666666666667, 'max': 4, 'min': 0},
           'level': {'avg': 5.0, 'max': 7, 'min': 3},
           'score': {'avg': 215.0, 'max': 301, 'min': 120}}}]

也许您应该考虑使用不同的数据结构而不是所有这些列表,或使用pandas之类的内容来帮助您更有效地分析数据。