데이터 프레임 팬더의 값 수를 기준으로 그룹화
저는 다음과 같은 데이터 프레임을 가지고 있습니다.
df = pd.DataFrame([
(1, 1, 'term1'),
(1, 2, 'term2'),
(1, 1, 'term1'),
(1, 1, 'term2'),
(2, 2, 'term3'),
(2, 3, 'term1'),
(2, 2, 'term1')
], columns=['id', 'group', 'term'])
나는 그것을 그룹화 하고 싶습니다.id
그리고.group
그리고 이 id, group pair에 대한 각 항의 개수를 계산합니다.
그래서 결국 저는 다음과 같은 것을 얻게 될 것입니다.
저는 모든 줄을 순환하면서 제가 원하는 것을 이룰 수 있었습니다.df.iterrows()
그리고 새로운 데이터 프레임을 만들었지만, 이것은 분명히 비효율적입니다. (도움이 된다면, 모든 용어의 목록을 미리 알고 있고 그 중 ~10개가 있습니다.)
그룹화해서 값을 세어봐야 할 것 같아요, 그래서 저는 그것을 해봤습니다.df.groupby(['id', 'group']).value_counts()
value_ counts가 데이터 프레임이 아닌 직렬별 그룹에서 작동하기 때문에 작동하지 않습니다.
어쨌든 나는 이것을 루프 없이 달성할 수 있습니까?
사용합니다.groupby
그리고.size
df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)
타이밍.
1,000행
df = pd.DataFrame(dict(id=np.random.choice(100, 1000000),
group=np.random.choice(20, 1000000),
term=np.random.choice(10, 1000000)))
pivot_table () 메서드 사용:
In [22]: df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
Out[22]:
term term1 term2 term3
id group
1 1 2 1 0
2 0 1 0
2 2 1 0 1
3 1 0 0
700K 행에 대한 타이밍 DF:
In [24]: df = pd.concat([df] * 10**5, ignore_index=True)
In [25]: df.shape
Out[25]: (700000, 3)
In [3]: %timeit df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)
1 loop, best of 3: 226 ms per loop
In [4]: %timeit df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
1 loop, best of 3: 236 ms per loop
In [5]: %timeit pd.crosstab([df.id, df.group], df.term)
1 loop, best of 3: 355 ms per loop
In [6]: %timeit df.groupby(['id','group','term'])['term'].size().unstack().fillna(0).astype(int)
1 loop, best of 3: 232 ms per loop
In [7]: %timeit df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)
1 loop, best of 3: 231 ms per loop
7M 행에 대한 타이밍 DF:
In [9]: df = pd.concat([df] * 10, ignore_index=True)
In [10]: df.shape
Out[10]: (7000000, 3)
In [11]: %timeit df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)
1 loop, best of 3: 2.27 s per loop
In [12]: %timeit df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
1 loop, best of 3: 2.3 s per loop
In [13]: %timeit pd.crosstab([df.id, df.group], df.term)
1 loop, best of 3: 3.37 s per loop
In [14]: %timeit df.groupby(['id','group','term'])['term'].size().unstack().fillna(0).astype(int)
1 loop, best of 3: 2.28 s per loop
In [15]: %timeit df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)
1 loop, best of 3: 1.89 s per loop
긴 해결책을 기억하는 대신, 팬더가 여러분을 위해 만든 해결책은 어떨까요?
df.groupby(['id', 'group', 'term']).count()
다음을 사용할 수 있습니다.
print (pd.crosstab([df.id, df.group], df.term))
term term1 term2 term3
id group
1 1 2 1 0
2 0 1 0
2 2 1 0 1
3 1 0 0
집계를 통해 다음과 같이 재구성할 수 있는 또 다른 솔루션:
df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)
term term1 term2 term3
id group
1 1 2 1 0
2 0 1 0
2 2 1 0 1
3 1 0 0
타이밍:
df = pd.concat([df]*10000).reset_index(drop=True)
In [48]: %timeit (df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0))
100 loops, best of 3: 12.4 ms per loop
In [49]: %timeit (df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0))
100 loops, best of 3: 12.2 ms per loop
사용하시려면value_counts
특정 시리즈에서 사용할 수 있으며, 다음을 사용할 수 있습니다.
df.groupby(["id", "group"])["term"].value_counts().unstack(fill_value=0)
또는 이와 동등한 방식으로, 사용..agg
방법:
df.groupby(["id", "group"]).agg({"term": "value_counts"}).unstack(fill_value=0)
다른 옵션은 직접 사용하는 것입니다.value_counts
DataFrame 자체에서 사용할 수 있습니다.groupby
:
df.value_counts().unstack(fill_value=0)
또 다른 대안:
df.assign(count=1).groupby(['id', 'group','term']).sum().unstack(fill_value=0).xs("count", 1)
term term1 term2 term3
id group
1 1 2 1 0
2 0 1 0
2 2 1 0 1
3 1 0 0
언급URL : https://stackoverflow.com/questions/39132742/groupby-value-counts-on-the-dataframe-pandas
'programing' 카테고리의 다른 글
Ubuntu 15에서 Mysql max-connections에 대해 max_open_files를 증가시킬 수 없음 (0) | 2023.09.23 |
---|---|
vvv.test를 실행할 때 로드되지 않음(또는 내 사이트 중 어느 것도) (0) | 2023.09.23 |
워드프레스의 'gmt_offset' 옵션에서 GMT Offset 가져오기 (0) | 2023.09.23 |
POSIX 실시간 신호를 사용하는 사람과 그 이유는? (0) | 2023.09.23 |
MySQL - 조건부 카운트(GROUP BY) (0) | 2023.09.23 |