pandas groupby에서 데이터 프레임 행을 목록으로 그룹화하는 방법은 무엇입니까?


274

다음 df과 같은 팬더 데이터 프레임 이 있습니다.

a b
A 1
A 2
B 5
B 5
B 4
C 6

첫 번째 열 을 기준으로 그룹화하고 두 번째 열을 행 목록으로 가져 오려고합니다 .

A [1,2]
B [5,5,4]
C [6]

팬더 그룹을 사용하여 이와 같은 작업을 수행 할 수 있습니까?

답변:


394

groupby관심있는 열을 그룹화 한 다음 apply list모든 그룹을 사용하여이 작업을 수행 할 수 있습니다 .

In [1]: df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6]})
        df

Out[1]: 
   a  b
0  A  1
1  A  2
2  B  5
3  B  5
4  B  4
5  C  6

In [2]: df.groupby('a')['b'].apply(list)
Out[2]: 
a
A       [1, 2]
B    [5, 5, 4]
C          [6]
Name: b, dtype: object

In [3]: df1 = df.groupby('a')['b'].apply(list).reset_index(name='new')
        df1
Out[3]: 
   a        new
0  A     [1, 2]
1  B  [5, 5, 4]
2  C        [6]

7
데이터 세트가 큰 경우 (예 : 천만 행) 많은 시간이 걸립니다. 더 빠른 방법이 있습니까? 그러나 'a'의 고유 숫자는 약 500k입니다.
Abhishek Thakur

6
groupby는 악명 높고 메모리가 부족합니다. 열 A로 정렬 한 다음 idxmin과 idxmax를 찾아 (아마도 이것을 dict에 저장) 이것을 사용하여 데이터 프레임을 더 빨리 슬라이스 할 수 있습니다.
EdChum

1
내 문제 로이 솔루션을 시도했을 때 (groupBy 및 group에 여러 열이 있음) 작동하지 않았습니다. 팬더는 'Function does not reduce'를 보냈습니다. 그런 tuple다음 여기에 두 번째 답변을 사용했습니다 : stackoverflow.com/questions/19530568/… . 설명 은 stackoverflow.com/questions/27439023/…의 두 번째 답변을 참조하십시오 .
Andarin

이 솔루션은 훌륭하지만 목록 세트를 저장하는 방법이 있습니까? 중복 항목을 제거한 다음 저장할 수 있습니까?
Sriram Arvind Lakshmanakumar

1
@PoeteMaudit 죄송합니다. 귀하가 의견을 묻거나 질문하는 것이 무엇인지 이해하지 못합니다. 여러 열을 단일 목록으로 연결하는 방법을 묻고 있습니까?
EdChum

47

성능이 중요한 경우 numpy 수준으로 내려갑니다.

import numpy as np

df = pd.DataFrame({'a': np.random.randint(0, 60, 600), 'b': [1, 2, 5, 5, 4, 6]*100})

def f(df):
         keys, values = df.sort_values('a').values.T
         ukeys, index = np.unique(keys, True)
         arrays = np.split(values, index[1:])
         df2 = pd.DataFrame({'a':ukeys, 'b':[list(a) for a in arrays]})
         return df2

테스트 :

In [301]: %timeit f(df)
1000 loops, best of 3: 1.64 ms per loop

In [302]: %timeit df.groupby('a')['b'].apply(list)
100 loops, best of 3: 5.26 ms per loop

8
우리가 예 두 개 이상의 키에 의해 그룹화하는 경우 우리는 어떻게이 사용할 수있는 .groupby([df.index.month, df.index.day])대신의 .groupby('a')?
ru111

25

이를 달성하는 편리한 방법은 다음과 같습니다.

df.groupby('a').agg({'b':lambda x: list(x)})

https://www.kaggle.com/akshaysehgal/how-to-group-by-aggregate-using-py : 사용자 지정 집계를 작성 하십시오.


5
lambda args: f(args)에 해당합니다f
BallpointBen

6
실제로 agg(list)는 충분합니다. 또한 여기를 참조 하십시오 .
cs95

!! 나는 단지 몇 가지 구문을 인터넷 검색하고 내 노트북이 솔루션 lol에 대해 참조되었다는 것을 깨달았다. 연결해 주셔서 감사합니다. 추가하기 위해 'list'는 시리즈 함수가 아니므로 apply와 함께 df.groupby('a').apply(list)사용하거나 dict의 일부로 agg와 함께 사용해야합니다 df.groupby('a').agg({'b':list}). 더 많은 것을 할 수 있기 때문에 람다 (내가 권장하는)와 함께 사용할 수도 있습니다. 예 : df.groupby('a').agg({'c':'first', 'b': lambda x: x.unique().tolist()})col c에 직렬 함수를 적용하고 col b에 고유 한 다음 list 함수를 적용 할 수 있습니다.
Akshay Sehgal

21

말했듯이 객체 의 groupby방법으로 pd.DataFrame작업을 수행 할 수 있습니다.

 L = ['A','A','B','B','B','C']
 N = [1,2,5,5,4,6]

 import pandas as pd
 df = pd.DataFrame(zip(L,N),columns = list('LN'))


 groups = df.groupby(df.L)

 groups.groups
      {'A': [0, 1], 'B': [2, 3, 4], 'C': [5]}

그룹을 설명하고 색인 방식으로 설명합니다.

단일 그룹의 요소를 얻으려면 예를 들어

 groups.get_group('A')

     L  N
  0  A  1
  1  A  2

  groups.get_group('B')

     L  N
  2  B  5
  3  B  5
  4  B  4

21

데이터 프레임의 여러 열에 대해이 문제를 해결하려면

In [5]: df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6],'c'
   ...: :[3,3,3,4,4,4]})

In [6]: df
Out[6]: 
   a  b  c
0  A  1  3
1  A  2  3
2  B  5  3
3  B  5  4
4  B  4  4
5  C  6  4

In [7]: df.groupby('a').agg(lambda x: list(x))
Out[7]: 
           b          c
a                      
A     [1, 2]     [3, 3]
B  [5, 5, 4]  [3, 4, 4]
C        [6]        [4]

이 답변은 Anamika Modi 의 답변에서 영감을 얻은 것입니다. 감사합니다!


12

다음 중 하나를 사용 groupby하고agg 조리법 .

# Setup
df = pd.DataFrame({
  'a': ['A', 'A', 'B', 'B', 'B', 'C'],
  'b': [1, 2, 5, 5, 4, 6],
  'c': ['x', 'y', 'z', 'x', 'y', 'z']
})
df

   a  b  c
0  A  1  x
1  A  2  y
2  B  5  z
3  B  5  x
4  B  4  y
5  C  6  z

여러 열을 목록으로 집계하려면 다음 중 하나를 사용하십시오.

df.groupby('a').agg(list)
df.groupby('a').agg(pd.Series.tolist)

           b          c
a                      
A     [1, 2]     [x, y]
B  [5, 5, 4]  [z, x, y]
C        [6]        [z]

단일 열만 그룹화하려면 groupby를 SeriesGroupBy객체 로 변환 한 다음을 호출하십시오 SeriesGroupBy.agg. 사용하다,

df.groupby('a').agg({'b': list})  # 4.42 ms 
df.groupby('a')['b'].agg(list)    # 2.76 ms - faster

a
A       [1, 2]
B    [5, 5, 4]
C          [6]
Name: b, dtype: object

위의 방법이 순서를 유지하도록 보장 됩니까? 동일한 행의 요소 (그러나 위의 코드에서 다른 열, bc )는 결과 목록에서 동일한 색인을 갖습니다.
Kai

@ 카이 오, 좋은 질문입니다. 예, 아니오 GroupBy는 그룹화 키 값을 기준으로 출력을 정렬합니다. 그러나 정렬은 일반적으로 안정적이므로 그룹당 상대 순서가 유지됩니다. 정렬 동작을 완전히 비활성화하려면을 사용하십시오 groupby(..., sort=False). 여기서는 이미 정렬 된 A 열을 그룹화하기 때문에 아무런 차이가 없습니다.
cs95

죄송합니다. 귀하의 답변을 이해하지 못합니다. 더 자세히 설명해 주시겠습니까? 나는 이것이 그 자신의 질문이 가치가 있다고 생각합니다 ..
Kai

1
이것은 매우 좋은 답변입니다! 목록의 값을 고유하게 만드는 방법도 있습니까? .agg (pd.Series.tolist.unique) 같은 것?
Federico Gentile

1
@FedericoGentile 당신은 람다를 사용할 수 있습니다. 여기에 한 가지 방법이다 :df.groupby('a')['b'].agg(lambda x: list(set(x)))
cs95은

7

여러 열을 그룹화하는 동안 고유 한 목록 을 찾고 있다면 아마도 도움이 될 수 있습니다.

df.groupby('a').agg(lambda x: list(set(x))).reset_index()

2

df.groupby리스트와 Series생성자로 사용하자

pd.Series({x : y.b.tolist() for x , y in df.groupby('a')})
Out[664]: 
A       [1, 2]
B    [5, 5, 4]
C          [6]
dtype: object

2

agg대신에 사용할 시간 입니다 apply.

언제

df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6], 'c': [1,2,5,5,4,6]})

여러 열을 list에 쌓으려면 pd.DataFrame

df.groupby('a')[['b', 'c']].agg(list)
# or 
df.groupby('a').agg(list)

목록에 단일 열을 원하면 결과 ps.Series

df.groupby('a')['b'].agg(list)
#or
df.groupby('a')['b'].apply(list)

단일 열만 집계 할 때의 pd.DataFrame결과보다 결과가 약 10 배 느리다는 점에 유의하십시오 ps.Series. 다중 열의 경우 사용하십시오.


0

여기에 "|"로 요소를 그룹화했습니다. 분리기로서

    import pandas as pd

    df = pd.read_csv('input.csv')

    df
    Out[1]:
      Area  Keywords
    0  A  1
    1  A  2
    2  B  5
    3  B  5
    4  B  4
    5  C  6

    df.dropna(inplace =  True)
    df['Area']=df['Area'].apply(lambda x:x.lower().strip())
    print df.columns
    df_op = df.groupby('Area').agg({"Keywords":lambda x : "|".join(x)})

    df_op.to_csv('output.csv')
    Out[2]:
    df_op
    Area  Keywords

    A       [1| 2]
    B    [5| 5| 4]
    C          [6]

0

내가 아는 가장 쉬운 방법 은 집계 함수에 대한 튜플 구문을 사용하여 Anamika의 대답 과 비슷한 하나의 열에 대해 적어도 동일한 것을 달성하지 못합니다 .

df.groupby('a').agg(b=('b','unique'), c=('c','unique'))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.