[python] Pandas Groupby : 문자열 통합을 얻는 방법

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

   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

부름

In [10]: print df.groupby("A")["B"].sum()

돌아올 것이다

A
1    1.615586
2    0.421821
3    0.463468
4    0.643961

이제 “C”열에 대해 “동일”을 수행하고 싶습니다. 해당 열에 문자열이 포함되어 있기 때문에 sum ()은 작동하지 않습니다 (문자열을 연결한다고 생각할 수 있지만). 내가 정말로보고 싶은 것은 각 그룹에 대한 목록 또는 문자열 세트입니다.

A
1    {This, string}
2    {is, !}
3    {a}
4    {random}

나는 이것을 할 방법을 찾으려고 노력하고 있습니다.

Series.unique () ( http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.unique.html )는 작동하지 않지만

df.groupby("A")["B"]

이다

pandas.core.groupby.SeriesGroupBy object

그래서 어떤 시리즈 방법이 작동하길 바랬습니다. 어떤 아이디어?



답변

In [4]: df = read_csv(StringIO(data),sep='\s+')

In [5]: df
Out[5]:
   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

In [6]: df.dtypes
Out[6]:
A      int64
B    float64
C     object
dtype: object

자체 함수를 적용 할 때 숫자가 아닌 열을 자동으로 제외하지 않습니다. 그러나 이것은의 응용 프로그램보다 느립니다 .sum().groupby

In [8]: df.groupby('A').apply(lambda x: x.sum())
Out[8]:
   A         B           C
A
1  2  1.615586  Thisstring
2  4  0.421821         is!
3  3  0.463468           a
4  4  0.643961      random

sum 기본적으로 연결

In [9]: df.groupby('A')['C'].apply(lambda x: x.sum())
Out[9]:
A
1    Thisstring
2           is!
3             a
4        random
dtype: object

원하는 것을 거의 할 수 있습니다.

In [11]: df.groupby('A')['C'].apply(lambda x: "{%s}" % ', '.join(x))
Out[11]:
A
1    {This, string}
2           {is, !}
3               {a}
4          {random}
dtype: object

한 번에 한 그룹 씩 전체 프레임에서이 작업을 수행합니다. 열쇠는Series

def f(x):
     return Series(dict(A = x['A'].sum(),
                        B = x['B'].sum(),
                        C = "{%s}" % ', '.join(x['C'])))

In [14]: df.groupby('A').apply(f)
Out[14]:
   A         B               C
A
1  2  1.615586  {This, string}
2  4  0.421821         {is, !}
3  3  0.463468             {a}
4  4  0.643961        {random}


답변

apply방법을 사용 하여 그룹화 된 데이터에 임의의 함수를 적용 할 수 있습니다 . 따라서 세트를 원하면 set. 목록을 원하시면 신청하십시오 list.

>>> d
   A       B
0  1    This
1  2      is
2  3       a
3  4  random
4  1  string
5  2       !
>>> d.groupby('A')['B'].apply(list)
A
1    [This, string]
2           [is, !]
3               [a]
4          [random]
dtype: object

다른 것을 원한다면 원하는 것을 수행하는 함수를 작성하십시오 apply.


답변

당신은 사용할 수 있습니다 aggregate(또는 agg값을 연결하는) 기능. (테스트되지 않은 코드)

df.groupby('A')['B'].agg(lambda col: ''.join(col))


답변

이것을 시도해 볼 수 있습니다.

df.groupby('A').agg({'B':'sum','C':'-'.join})


답변

간단한 해결책은 다음과 같습니다.

>>> df.groupby(['A','B']).c.unique().reset_index()


답변

명명 된 집계 pandas >= 0.25.0

pandas 버전 0.25.0부터는 그룹화, 집계 및 동시에 열에 새 이름을 할당 할 수있는 집계 이름이 지정되었습니다. 이렇게하면 MultiIndex 열을 가져올 수 없으며 포함 된 데이터를 고려할 때 열 이름이 더 의미가 있습니다.


집계 및 문자열 목록 가져 오기

grp = df.groupby('A').agg(B_sum=('B','sum'),
                          C=('C', list)).reset_index()

print(grp)
   A     B_sum               C
0  1  1.615586  [This, string]
1  2  0.421821         [is, !]
2  3  0.463468             [a]
3  4  0.643961        [random]

문자열 집계 및 결합

grp = df.groupby('A').agg(B_sum=('B','sum'),
                          C=('C', ', '.join)).reset_index()

print(grp)
   A     B_sum             C
0  1  1.615586  This, string
1  2  0.421821         is, !
2  3  0.463468             a
3  4  0.643961        random


답변

데이터 프레임에서 B 열을 덮어 쓰려면 다음과 같이하면됩니다.

    df = df.groupby('A',as_index=False).agg(lambda x:'\n'.join(x))