2013-04-16 4 views
3
이이 질문에 매우 유사하다

: Finding minimum, maximum and average values for nested lists?- 중첩 된 목록에서 고유 한 일치하는 값을 가진 열에 대한 평균 찾을

질문의 중요한 차이점 루트 나는 내 최소, 최대, 평균을 찾고 싶은 것 고유 한 각 열 이름 (사람 이름)에 대한 목록 (목록 내에 중첩 됨). 예를 들어

: 각 라인 (비슷한 가상 이름) 기본적 -

epochtime, name, score, level, extralives 

예컨대

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 

그리고이 시간에 의해 목록에 배치됩니다 :

listoflists = [timechunk1, timechunk2....] 

이 또는하지 않을 수 있습니다 시간 청크의 각각리스트의 목록이있다

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

이 질문에 대한 과잉/외계.

각 고유 이름 (빌리 또는 스와지 - )에 대해 각 필드 (점수, 레벨, extralives)에 대한 최소값, 최대 값, 평균값을 찾는 방법은 무엇입니까? 각 목록 (timechunk1, timechunk2)에 개별적으로 나열하지 않는 것이 더 좋을까요?)?

+0

은 아마도 이름은 *하지 * 클러스터? –

+0

아니요. 정렬 된 (alist, key = lambda 플레이어 : player [1]) 목록을 재배치 할 생각이었습니다. 그러나 아니요. 각 목록 (timechunk1 등) 내의 각 '이름'에 대해 다양한 항목이 있습니다. – Donnied

답변

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을 사용하려면 확실히 판다를 사용해보십시오. 당신은 또한 다중 열 groupbys을 할 수

참고 : timechunks에

>>> 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 
+0

좋아 보이지만 csv는 한 시간 그룹과 관련이 없습니다. 예를 들어, 프로그램은 다른 시간 청크로 줄을 구분합니다. 목록에서 데이터 프레임을 생성하거나 데이터 프레임에 직접 추가해야합니다. http://stackoverflow.com/questions/10715965/add-one-row-in-a-pandas-dataframe – Donnied

+0

위의 내용은 더 암시적인 내용이었습니다. 당신의 덩어리가 어떻게 행해지는지에 따라 - 나는 당신의 예에서 꽤 일반화 할 수 없다 - 당신은 벡터화 된 방식으로 그렇게 할 수도있을 것이다. – DSM

+0

좋은 예입니다. 목록 (예 : 'timechunk1')을 데이터 프레임으로 변환하거나 다양한 데이터 프레임에 직접 추가해야하는 작업을 재구성해야합니다. – Donnied

2

당신은 이름 별, 필드 별 목록을 수집해야합니다. 공장과 collections.defaultdict를 사용

중첩 된 목록을 만들 : 하나 timechunk으로 예를 들어, 입력 데이터를 덤프

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과 같은 것을 사용하면 데이터를보다 효율적으로 분석하는 데 도움이됩니다.

+0

확실히. 나는 제안에 개방적이다.기본 파일은 예제와 비슷한 각 줄이있는 csv입니다. 그래, 나는 그것을보고 있었고 내가 SQL로 일을하는 것이 더 쉬울 수도 있다고 생각했지만 가능한 한 파이썬에 머물고 싶었다. 팬더의 제안은 좋았다. 나는 R에서도이 일을 조금 해왔지만, Python의 R은 나에게 매우 직관적이지 않은 것처럼 보였다. – Donnied

+1

팬더가 다음 호출 포트가되어야합니다. 명시된 목표는 정확히 이러한 종류의 분석을 처리하는 것입니다. –

+0

나는 그 제안을 시도했다. 하지만 뭔가 잘못 됐고 stats_per_time_chunk가 empty {}, {}, {}, – Donnied