판다의 집합
- 팬더와 함께 집계를 수행하려면 어떻게 해야 합니까?
- 집계 후 데이터 프레임 없음!무슨 일입니까?
- 주로 문자열 열을 집계하려면 어떻게 해야 합니까?
list
s,tuple
s,strings with separator
)? - 카운트를 집계하려면 어떻게 해야 합니까?
- 집계된 값으로 채워진 새 열을 만들려면 어떻게 해야 합니까?
저는 팬더의 다양한 얼굴에 대해 질문하는 이 반복되는 질문들을 보았습니다.오늘날 집계 및 다양한 사용 사례와 관련된 대부분의 정보는 검색할 수 없는 잘못된 단어로 표현된 수십 개의 게시물에 걸쳐 단편화되어 있습니다.여기서의 목적은 후세를 위해 더 중요한 점들을 수집하는 것입니다.
이 Q&A는 다음과 같은 유용한 사용자 가이드의 다음 회차입니다.
이 게시물은 집계 및 그룹별 관련 문서를 대체하기 위한 것이 아님을 유의하시기 바랍니다.
질문1
팬더와 함께 집계를 수행하려면 어떻게 해야 합니까?
집계 문서를 확장했습니다.
집합 함수는 반환되는 객체의 치수를 감소시키는 함수입니다.즉, 출력 Series/DataFrame의 행 수가 원래와 같거나 적음을 의미합니다.
몇 가지 일반적인 집계 기능은 아래 표와 같습니다.
함수 설명평균() 그룹 평균 계산sum() 그룹 값의 합을 계산합니다.size() 그룹 크기 계산count() 그룹수 계산std() 그룹 표준편차var() 그룹 분산 계산sem() 그룹 평균의 표준 오차description() 기술 통계량을 생성합니다.첫 번째() 그룹 값 중 첫 번째 값을 계산합니다.마지막() 계산그룹 값 중 마지막 값nth() n번째 값 또는 n이 목록인 경우 부분 집합min() 그룹 값의 min 계산max() 그룹 값의 max 계산
np.random.seed(123)
df = pd.DataFrame({'A' : ['foo', 'foo', 'bar', 'foo', 'bar', 'foo'],
'B' : ['one', 'two', 'three','two', 'two', 'one'],
'C' : np.random.randint(5, size=6),
'D' : np.random.randint(5, size=6),
'E' : np.random.randint(5, size=6)})
print (df)
A B C D E
0 foo one 2 3 0
1 foo two 4 1 0
2 bar three 2 1 1
3 foo two 1 0 3
4 bar two 3 1 4
5 foo one 2 1 0
필터링된 열 및 Cython 구현 기능별 집계:
df1 = df.groupby(['A', 'B'], as_index=False)['C'].sum()
print (df1)
A B C
0 bar three 2
1 bar two 3
2 foo one 4
3 foo two 5
집계 함수는 에 지정되지 않고 모든 열에 대해 사용됩니다.groupby
함수, 여기에A, B
열:
df2 = df.groupby(['A', 'B'], as_index=False).sum()
print (df2)
A B C D E
0 bar three 2 1 1
1 bar two 3 1 4
2 foo one 4 4 0
3 foo two 5 1 3
다음 목록에서 집계에 사용되는 일부 열만 지정할 수도 있습니다.groupby
함수:
df3 = df.groupby(['A', 'B'], as_index=False)['C','D'].sum()
print (df3)
A B C D
0 bar three 2 1
1 bar two 3 1
2 foo one 4 4
3 foo two 5 1
함수를 사용하여 동일한 결과:
df1 = df.groupby(['A', 'B'], as_index=False)['C'].agg('sum')
print (df1)
A B C
0 bar three 2
1 bar two 3
2 foo one 4
3 foo two 5
df2 = df.groupby(['A', 'B'], as_index=False).agg('sum')
print (df2)
A B C D E
0 bar three 2 1 1
1 bar two 3 1 4
2 foo one 4 4 0
3 foo two 5 1 3
하나의 열에 적용되는 여러 함수의 경우 다음 목록을 사용합니다.tuple
- 새 열 및 s - :
df4 = (df.groupby(['A', 'B'])['C']
.agg([('average','mean'),('total','sum')])
.reset_index())
print (df4)
A B average total
0 bar three 2.0 2
1 bar two 3.0 3
2 foo one 2.0 4
3 foo two 2.5 5
여러 기능을 통과하려면 통과해야 합니다.list
tuple
s:
df5 = (df.groupby(['A', 'B'])
.agg([('average','mean'),('total','sum')]))
print (df5)
C D E
average total average total average total
A B
bar three 2.0 2 1.0 1 1.0 1
two 3.0 3 1.0 1 4.0 4
foo one 2.0 4 2.0 4 0.0 0
two 2.5 5 0.5 1 1.5 3
그럼 구하라구요.MultiIndex
위:
print (df5.columns)
MultiIndex(levels=[['C', 'D', 'E'], ['average', 'total']],
labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])
그리고 열로 변환하기 위해, 평탄화하기.MultiIndex
사용하다map
와 함께join
:
df5.columns = df5.columns.map('_'.join)
df5 = df5.reset_index()
print (df5)
A B C_average C_total D_average D_total E_average E_total
0 bar three 2.0 2 1.0 1 1.0 1
1 bar two 3.0 3 1.0 1 4.0 4
2 foo one 2.0 4 2.0 4 0.0 0
3 foo two 2.5 5 0.5 1 1.5 3
또 다른 해결책은 집합 함수 목록을 통과한 다음 평탄화하는 것입니다.MultiIndex
다른 열 이름에는 다음을 사용합니다.
df5 = df.groupby(['A', 'B']).agg(['mean','sum'])
df5.columns = (df5.columns.map('_'.join)
.str.replace('sum','total')
.str.replace('mean','average'))
df5 = df5.reset_index()
print (df5)
A B C_average C_total D_average D_total E_average E_total
0 bar three 2.0 2 1.0 1 1.0 1
1 bar two 3.0 3 1.0 1 4.0 4
2 foo one 2.0 4 2.0 4 0.0 0
3 foo two 2.5 5 0.5 1 1.5 3
원하는 경우 집계 기능이 있는 각 열을 별도로 통과합니다.dictionary
:
df6 = (df.groupby(['A', 'B'], as_index=False)
.agg({'C':'sum','D':'mean'})
.rename(columns={'C':'C_total', 'D':'D_average'}))
print (df6)
A B C_total D_average
0 bar three 2 1.0
1 bar two 3 1.0
2 foo one 4 2.0
3 foo two 5 0.5
사용자 지정 기능도 전달할 수 있습니다.
def func(x):
return x.iat[0] + x.iat[-1]
df7 = (df.groupby(['A', 'B'], as_index=False)
.agg({'C':'sum','D': func})
.rename(columns={'C':'C_total', 'D':'D_sum_first_and_last'}))
print (df7)
A B C_total D_sum_first_and_last
0 bar three 2 2
1 bar two 3 2
2 foo one 4 4
3 foo two 5 1
질문2
집계 후 데이터 프레임 없음!무슨 일입니까?
두 개 이상의 열로 집계:
df1 = df.groupby(['A', 'B'])['C'].sum()
print (df1)
A B
bar three 2
two 3
foo one 4
two 5
Name: C, dtype: int32
먼저 확인합니다.Index
그리고.type
팬더 개체에 대한 설명:
print (df1.index)
MultiIndex(levels=[['bar', 'foo'], ['one', 'three', 'two']],
labels=[[0, 0, 1, 1], [1, 2, 0, 2]],
names=['A', 'B'])
print (type(df1))
<class 'pandas.core.series.Series'>
다음과 같은 두 가지 해결책이 있습니다.MultiIndex Series
열에 연결:
- 매개변수 추가
as_index=False
df1 = df.groupby(['A', 'B'], as_index=False)['C'].sum()
print (df1)
A B C
0 bar three 2
1 bar two 3
2 foo one 4
3 foo two 5
- 사용:
df1 = df.groupby(['A', 'B'])['C'].sum().reset_index()
print (df1)
A B C
0 bar three 2
1 bar two 3
2 foo one 4
3 foo two 5
열을 하나씩 그룹화하는 경우:
df2 = df.groupby('A')['C'].sum()
print (df2)
A
bar 5
foo 9
Name: C, dtype: int32
...얻다Series
와 함께Index
:
print (df2.index)
Index(['bar', 'foo'], dtype='object', name='A')
print (type(df2))
<class 'pandas.core.series.Series'>
그리고 그 해결책은 그것과 같습니다.MultiIndex Series
:
df2 = df.groupby('A', as_index=False)['C'].sum()
print (df2)
A C
0 bar 5
1 foo 9
df2 = df.groupby('A')['C'].sum().reset_index()
print (df2)
A C
0 bar 5
1 foo 9
질문3
주로 문자열 열을 집계하려면 어떻게 해야 합니까?list
s,tuple
s,strings with separator
)?
df = pd.DataFrame({'A' : ['a', 'c', 'b', 'b', 'a', 'c', 'b'],
'B' : ['one', 'two', 'three','two', 'two', 'one', 'three'],
'C' : ['three', 'one', 'two', 'two', 'three','two', 'one'],
'D' : [1,2,3,2,3,1,2]})
print (df)
A B C D
0 a one three 1
1 c two one 2
2 b three two 3
3 b two two 2
4 a two three 3
5 c one two 1
6 b three one 2
집계함수 대신 통과가 가능합니다.list
,tuple
,set
열을 변환하는 경우:
df1 = df.groupby('A')['B'].agg(list).reset_index()
print (df1)
A B
0 a [one, two]
1 b [three, two, three]
2 c [two, one]
다른 방법으로는 다음을 사용할 수 있습니다.
df1 = df.groupby('A')['B'].apply(list).reset_index()
print (df1)
A B
0 a [one, two]
1 b [three, two, three]
2 c [two, one]
구분 기호가 있는 문자열로 변환할 경우.join
문자열 열인 경우에만:
df2 = df.groupby('A')['B'].agg(','.join).reset_index()
print (df2)
A B
0 a one,two
1 b three,two,three
2 c two,one
숫자 열인 경우 다음 값으로 변환하기 위한 람다 함수를 사용합니다.string
s:
df3 = (df.groupby('A')['D']
.agg(lambda x: ','.join(x.astype(str)))
.reset_index())
print (df3)
A D
0 a 1,3
1 b 3,2,2
2 c 2,1
다른 해결책은 이전에 문자열로 변환하는 것입니다.groupby
:
df3 = (df.assign(D = df['D'].astype(str))
.groupby('A')['D']
.agg(','.join).reset_index())
print (df3)
A D
0 a 1,3
1 b 3,2,2
2 c 2,1
모든 열을 변환할 경우 다음 열 목록을 전달하지 않습니다.groupby
. 열이 없습니다.D
, nuisance' 열을 자동으로 제외하기 때문입니다.이는 모든 숫자 열이 제외됨을 의미합니다.
df4 = df.groupby('A').agg(','.join).reset_index()
print (df4)
A B C
0 a one,two three,three
1 b three,two,three two,two,one
2 c two,one one,two
따라서 모든 열을 문자열로 변환한 다음 모든 열을 얻어야 합니다.
df5 = (df.groupby('A')
.agg(lambda x: ','.join(x.astype(str)))
.reset_index())
print (df5)
A B C D
0 a one,two three,three 1,3
1 b three,two,three two,two,one 3,2,2
2 c two,one one,two 2,1
질문4
카운트를 집계하려면 어떻게 해야 합니까?
df = pd.DataFrame({'A' : ['a', 'c', 'b', 'b', 'a', 'c', 'b'],
'B' : ['one', 'two', 'three','two', 'two', 'one', 'three'],
'C' : ['three', np.nan, np.nan, 'two', 'three','two', 'one'],
'D' : [np.nan,2,3,2,3,np.nan,2]})
print (df)
A B C D
0 a one three NaN
1 c two NaN 2.0
2 b three NaN 3.0
3 b two two 2.0
4 a two three 3.0
5 c one two NaN
6 b three one 2.0
함수size
각 그룹별:
df1 = df.groupby('A').size().reset_index(name='COUNT')
print (df1)
A COUNT
0 a 2
1 b 3
2 c 2
결측값 제외 함수:
df2 = df.groupby('A')['C'].count().reset_index(name='COUNT')
print (df2)
A COUNT
0 a 2
1 b 2
2 c 1
이 함수는 결측치가 아닌 값을 계산할 때 여러 열에 사용해야 합니다.
df3 = df.groupby('A').count().add_suffix('_COUNT').reset_index()
print (df3)
A B_COUNT C_COUNT D_COUNT
0 a 2 2 1
1 b 3 2 3
2 c 2 1 1
이와 관련된 함수는 다음과 같습니다.고유 값의 카운트를 내림차순으로 포함하는 개체의 크기를 반환하므로 첫 번째 요소가 가장 자주 발생하는 요소가 됩니다.제외됩니다.NaN
s 값은 기본값입니다.
df4 = (df['A'].value_counts()
.rename_axis('A')
.reset_index(name='COUNT'))
print (df4)
A COUNT
0 b 3
1 a 2
2 c 2
함수를 사용하는 것과 같은 출력을 원하는 경우groupby
+size
, 추가:
df5 = (df['A'].value_counts()
.sort_index()
.rename_axis('A')
.reset_index(name='COUNT'))
print (df5)
A COUNT
0 a 2
1 b 3
2 c 2
질문5
집계된 값으로 채워진 새 열을 만들려면 어떻게 해야 합니까?
메서드는 그룹화 중인 개체와 동일한 크기(동일한 크기)로 인덱싱된 개체를 반환합니다.
자세한 내용은 Pandas 설명서를 참조하십시오.
np.random.seed(123)
df = pd.DataFrame({'A' : ['foo', 'foo', 'bar', 'foo', 'bar', 'foo'],
'B' : ['one', 'two', 'three','two', 'two', 'one'],
'C' : np.random.randint(5, size=6),
'D' : np.random.randint(5, size=6)})
print (df)
A B C D
0 foo one 2 3
1 foo two 4 1
2 bar three 2 1
3 foo two 1 0
4 bar two 3 1
5 foo one 2 1
df['C1'] = df.groupby('A')['C'].transform('sum')
df['C2'] = df.groupby(['A','B'])['C'].transform('sum')
df[['C3','D3']] = df.groupby('A')['C','D'].transform('sum')
df[['C4','D4']] = df.groupby(['A','B'])['C','D'].transform('sum')
print (df)
A B C D C1 C2 C3 D3 C4 D4
0 foo one 2 3 9 4 9 5 4 4
1 foo two 4 1 9 5 9 5 5 1
2 bar three 2 1 5 2 5 2 2 1
3 foo two 1 0 9 5 9 5 5 1
4 bar two 3 1 5 3 5 2 3 1
5 foo one 2 1 9 4 9 5 4 4
R 또는 SQL 배경 출신인 경우, 이미 익숙한 방식으로 Aggregation을 수행하는 데 필요한 모든 것을 배울 수 있는 세 가지 예를 제시합니다.
팬더 데이터 프레임을 먼저 만들어 보겠습니다.
import pandas as pd
df = pd.DataFrame({'key1' : ['a','a','a','b','a'],
'key2' : ['c','c','d','d','e'],
'value1' : [1,2,2,3,3],
'value2' : [9,8,7,6,5]})
df.head(5)
우리가 만든 테이블의 모양은 다음과 같습니다.
key1 | key2 | value1 | value2 |
---|---|---|---|
a | c | 1 | 9 |
a | c | 2 | 8 |
a | d | 2 | 7 |
b | d | 3 | 6 |
a | e | 3 | 5 |
1. SQL과 유사한 행 감소를 통한 집계Group By
1.1 If Pandas 버전>=0.25
를 실행하여 Pandas 버전을 확인print(pd.__version__)
. Pandas 버전이 0.25 이상이면 다음 코드가 작동합니다.
df_agg = df.groupby(['key1','key2']).agg(mean_of_value_1=('value1', 'mean'),
sum_of_value_2=('value2', 'sum'),
count_of_value1=('value1','size')
).reset_index()
df_agg.head(5)
결과 데이터 테이블은 다음과 같습니다.
key1 | key2 | 평균_값 1 | sum_of_value2 | count_of_value1 |
---|---|---|---|---|
a | c | 1.5 | 17 | 2 |
a | d | 2.0 | 7 | 1 |
a | e | 3.0 | 5 | 1 |
b | d | 3.0 | 6 | 1 |
이와 동등한 SQL은 다음과 같습니다.
SELECT
key1
,key2
,AVG(value1) AS mean_of_value_1
,SUM(value2) AS sum_of_value_2
,COUNT(*) AS count_of_value1
FROM
df
GROUP BY
key1
,key2
1.2 If Pandas 버전<0.25
Pandas 버전이 0.25보다 오래된 경우 위 코드를 실행하면 다음 오류가 발생합니다.
TypeError: aggregate()에 필요한 위치 인수 'arg'가 1개 누락되었습니다.
이제 두 가지 모두에 대해 집계를 수행합니다.value1
그리고.value2
, 다음 코드를 실행합니다.
df_agg = df.groupby(['key1','key2'],as_index=False).agg({'value1':['mean','count'],'value2':'sum'})
df_agg.columns = ['_'.join(col).strip() for col in df_agg.columns.values]
df_agg.head(5)
결과 테이블은 다음과 같습니다.
key1 | key2 | value1_ | value1_count | value2_sum |
---|---|---|---|---|
a | c | 1.5 | 2 | 17 |
a | d | 2.0 | 1 | 7 |
a | e | 3.0 | 1 | 5 |
b | d | 3.0 | 1 | 6 |
다음 코드를 사용하여 열 이름을 별도로 변경해야 합니다.
df_agg.rename(columns={"value1_mean" : "mean_of_value1",
"value1_count" : "count_of_value1",
"value2_sum" : "sum_of_value2"
}, inplace=True)
2. 행 축소 없이 열 작성(EXCEL - SUMIF, COUNTIF
)
행이 줄어들지 않는 엑셀에서 하는 것처럼 SUMIF, COUNDIF 등을 하려면 대신 해야 합니다.
df['Total_of_value1_by_key1'] = df.groupby('key1')['value1'].transform('sum')
df.head(5)
결과 데이터 프레임은 원본과 동일한 수의 행으로 다음과 같이 나타납니다.
key1 | key2 | value1 | value2 | Total_of_value1_by_key1 |
---|---|---|---|---|
a | c | 1 | 9 | 8 |
a | c | 2 | 8 | 8 |
a | d | 2 | 7 | 8 |
b | d | 3 | 6 | 3 |
a | e | 3 | 5 | 8 |
열 3. RANK ROW_NUMBER() OVER (PARTITION BY ORDER BY)
마지막으로 다음과 같은 SQL에 해당하는 순위 열을 생성하는 경우가 있을 수 있습니다.ROW_NUMBER() OVER (PARTITION BY key1 ORDER BY value1 DESC, value2 ASC)
.
이렇게 하는 거예요.
df['RN'] = df.sort_values(['value1','value2'], ascending=[False,True]) \
.groupby(['key1']) \
.cumcount() + 1
df.head(5)
참고: 코드는 다음을 추가하여 멀티 라인으로 만듭니다.\
각 행의 끝에
결과 데이터 프레임의 모양은 다음과 같습니다.
key1 | key2 | value1 | value2 | RN |
---|---|---|---|---|
a | c | 1 | 9 | 4 |
a | c | 2 | 8 | 3 |
a | d | 2 | 7 | 2 |
b | d | 3 | 6 | 1 |
a | e | 3 | 5 | 1 |
위의 모든 예에서 최종 데이터 테이블은 테이블 구조를 가지며 다른 구문에서 얻을 수 있는 피벗 구조를 가지지 않습니다.
기타 집계 연산자:
mean()
그룹 평균 계산
sum()
그룹 값의 합을 계산합니다.
size()
그룹 크기 계산
count()
그룹수계산
std()
군 표준편차
var()
그룹 분산 계산
sem()
그룹 평균의 표준 오차
describe()
기술 통계량을 생성합니다.
first()
그룹 값 중 첫 번째 값을 계산합니다.
last()
그룹 값 중 마지막 값 계산
nth()
n이 목록인 경우 tenth 값 또는 부분 집합
min()
그룹 값 최소값 계산
max()
그룹 값의 최대값 계산
언급URL : https://stackoverflow.com/questions/53781634/aggregation-in-pandas
'programing' 카테고리의 다른 글
아티팩트 com.oracle:ojdbc14:jar:10.2.0.1.0 누락 (0) | 2023.10.29 |
---|---|
독트린2 - 한 발에 여러 번 삽입 (0) | 2023.10.29 |
SQL 데이터베이스에서 데이터를 끌어오려고 할 때 dplyr가 잘못된 테이블 이름을 ON 절에 사용하지 않도록 하는 방법은 무엇입니까? (0) | 2023.10.29 |
바탕색으로 버튼에 효과적인 소재감 (0) | 2023.10.29 |
왼쪽에서 오른쪽으로 Ionic 리스트 아이템을 스와이프하는 방법? (0) | 2023.10.29 |