그룹 별 총 팬더 비율


148

이것은 명백히 간단하지만, 새로운 초보자로서 나는 붙어 있습니다.

주, 사무실 ID 및 해당 사무실에 대한 3 개의 열이 포함 된 CSV 파일이 있습니다.

특정 주에서 사무실 당 판매 비율을 계산하려고합니다 (각 주에서 모든 백분율의 총계는 100 % 임).

df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
                   'office_id': range(1, 7) * 2,
                   'sales': [np.random.randint(100000, 999999)
                             for _ in range(12)]})

df.groupby(['state', 'office_id']).agg({'sales': 'sum'})

이것은 다음을 반환합니다.

                  sales
state office_id        
AZ    2          839507
      4          373917
      6          347225
CA    1          798585
      3          890850
      5          454423
CO    1          819975
      3          202969
      5          614011
WA    2          163942
      4          369858
      6          959285

나는에 "까지 도달"방법을 알아낼 수없는 것 state의 수준 groupby을 총 sales전체에 대한 state비율을 계산합니다.


3
df['sales'] / df.groupby('state')['sales'].transform('sum')가장 명확한 대답 인 것 같습니다.
Paul Rougieux

답변:


207

폴 H의 대답은 두 번째해야 할 것이다 것이 맞다 groupby객체를,하지만 당신은 간단한 방법으로 비율을 계산할 수 있습니다 - 다만 과 분열 의 합에 의해 열을. Paul H의 답변 시작 부분 복사 :groupbystate_officesales

# From Paul H
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
                   'office_id': list(range(1, 7)) * 2,
                   'sales': [np.random.randint(100000, 999999)
                             for _ in range(12)]})
state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
# Change: groupby state_office and divide by sum
state_pcts = state_office.groupby(level=0).apply(lambda x:
                                                 100 * x / float(x.sum()))

보고:

                     sales
state office_id           
AZ    2          16.981365
      4          19.250033
      6          63.768601
CA    1          19.331879
      3          33.858747
      5          46.809373
CO    1          36.851857
      3          19.874290
      5          43.273852
WA    2          34.707233
      4          35.511259
      6          29.781508

1
무슨 일이야? 내가 이해하는 것처럼 x일종의 테이블이므로 100 * x직관적으로 이해가되지 않습니다 (특히 일부 셀에 AZ, ... 과 같은 문자열이있는 경우).
dhardy 2019

5
@dhardy state_office는 다중 인덱스가있는 Series이므로 값이 모두 숫자 인 하나의 열입니다. groupby를 수행 한 후 각각 x은 해당 열의 하위 집합입니다. 말이 돼?
exp1orer

2
그것은 가능하지만 나에게는 효과가 없었습니다. Python 3의 팬더는 약간 다르게 작동합니까?
dhardy 2019

1
무슨 level=0뜻입니까?
van_d39

3
@Veenit은 열 중 하나가 아니라 인덱스의 첫 번째 수준으로 그룹화한다는 의미입니다.
exp1orer

54

상태별로 그룹화하는 두 번째 groupby 오브젝트를 작성하고 div메소드 를 사용해야합니다 .

import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
               'office_id': list(range(1, 7)) * 2,
               'sales': [np.random.randint(100000, 999999) for _ in range(12)]})

state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
state = df.groupby(['state']).agg({'sales': 'sum'})
state_office.div(state, level='state') * 100


                     sales
state office_id           
AZ    2          16.981365
      4          19.250033
      6          63.768601
CA    1          19.331879
      3          33.858747
      5          46.809373
CO    1          36.851857
      3          19.874290
      5          43.273852
WA    2          34.707233
      4          35.511259
      6          29.781508

level='state'에서 kwarg이 div방송에 팬더를 알려줍니다 /를의 값에 dataframes 기반을 결합 state인덱스의 수준.


4
인덱스가 3 개인 경우이 방법이 작동합니까? 먼저 3 열로 그룹별로 작업했습니다. 그런 다음 2에 대해서만 두 번째 그룹을 작성하고 합계를 계산했습니다. 그런 다음 사용하려고 div하지만 함께 level=["index1", "index2"]알려줍니다 Join on level between two MultiIndex objects is ambiguous.
Ger

@Ger 그것은 효과가 있지만, 당신이 그 설명에서 잘못하고있는 것을 신성하게 할 수있는 방법은 없습니다. 사이트에서 조금 더 검색하십시오. 아무것도 찾지 못하면 문제를 보여주는 재현 가능한 예를 사용하여 새 질문을 만드십시오. stackoverflow.com/questions/20109391/…
Paul H

34

간결성을 위해 SeriesGroupBy를 사용합니다.

In [11]: c = df.groupby(['state', 'office_id'])['sales'].sum().rename("count")

In [12]: c
Out[12]:
state  office_id
AZ     2            925105
       4            592852
       6            362198
CA     1            819164
       3            743055
       5            292885
CO     1            525994
       3            338378
       5            490335
WA     2            623380
       4            441560
       6            451428
Name: count, dtype: int64

In [13]: c / c.groupby(level=0).sum()
Out[13]:
state  office_id
AZ     2            0.492037
       4            0.315321
       6            0.192643
CA     1            0.441573
       3            0.400546
       5            0.157881
CO     1            0.388271
       3            0.249779
       5            0.361949
WA     2            0.411101
       4            0.291196
       6            0.297703
Name: count, dtype: float64

여러 그룹의 경우 Radical df 사용하여 변환을 사용해야합니다 .

In [21]: c =  df.groupby(["Group 1","Group 2","Final Group"])["Numbers I want as percents"].sum().rename("count")

In [22]: c / c.groupby(level=[0, 1]).transform("sum")
Out[22]:
Group 1  Group 2  Final Group
AAHQ     BOSC     OWON           0.331006
                  TLAM           0.668994
         MQVF     BWSI           0.288961
                  FXZM           0.711039
         ODWV     NFCH           0.262395
...
Name: count, dtype: float64

이것은 다른 답변보다 약간 더 성능이 좋은 것으로 보입니다 (Radiocal의 답변 속도의 두 배 미만, 나에게 ~ 0.08 초).


5
이것은 매우 빠릅니다. 나는 이것을 선호하는 팬더 접근법으로 권장합니다. numpy의 벡터화 및 팬더 색인 생성을 활용합니다.
Charles

여러 그룹과 함께 일하면서 이것은 나에게도 효과적이었습니다. 감사.
irene

27

벤치마킹이 필요하다고 생각합니다. OP의 원본 DataFrame을 사용하여

df = pd.DataFrame({
    'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
    'office_id': range(1, 7) * 2,
    'sales': [np.random.randint(100000, 999999) for _ in range(12)]
})

1 앤디 헤이든

그의 답변에 대해 언급 한 바와 같이 Andy는 벡터화 및 팬더 인덱싱을 최대한 활용합니다.

c = df.groupby(['state', 'office_id'])['sales'].sum().rename("count")
c / c.groupby(level=0).sum()

루프 당 3.42ms ± 16.7µs
(평균 7 번의 런, 평균 100 개의 루프)


둘째 폴 H

state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
state = df.groupby(['state']).agg({'sales': 'sum'})
state_office.div(state, level='state') * 100

4.66 MS ± 24.4 μs의 루프 당
(평균 ± 표준. DEV. 7 개 실행의 100 개 루프 각)


세 번째 exp1orer

이것은 레벨 0에서 x.sum()각각 x에 대해 계산할 때 가장 느린 답변 입니다.

나에게 이것은 현재 유용한 형식은 아니지만 여전히 유용한 대답입니다. 작은 데이터 세트에서 빠른 EDA apply를 수행하려면 메소드 체인 을 사용 하여이를 한 줄로 작성할 수 있습니다 . 따라서 변수 이름에 대한 결정이 필요하지 않습니다. 실제로 가장 귀중한 자원 (뇌)에 계산 비용이 많이 듭니다 .

여기 수정 사항이 있습니다.

(
    df.groupby(['state', 'office_id'])
    .agg({'sales': 'sum'})
    .groupby(level=0)
    .apply(lambda x: 100 * x / float(x.sum()))
)

10.6 MS ± 81.5 μs의 루프 당
(평균 ± 표준. DEV. 7 개 실행의 100 개 루프 각)


따라서 작은 데이터 세트에서 아무도 6ms를 신경 쓰지 않습니다. 그러나 이것은 3 배 빠른 속도이며 높은 카디널리티 그룹을 가진 더 큰 데이터 세트에서 큰 차이를 만들 것입니다.

위의 코드에 추가하여 14412 상태 범주와 600 office_ids로 모양 (12,000,000, 3)의 DataFrame을 만듭니다.

import string

import numpy as np
import pandas as pd
np.random.seed(0)

groups = [
    ''.join(i) for i in zip(
    np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
    np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
    np.random.choice(np.array([i for i in string.ascii_lowercase]), 30000),
                       )
]

df = pd.DataFrame({'state': groups * 400,
               'office_id': list(range(1, 601)) * 20000,
               'sales': [np.random.randint(100000, 999999)
                         for _ in range(12)] * 1000000
})

앤디를 사용하여

루프 당 2 초 ± 10.4ms
(평균 7 회 실행, 각 1 루프의 평균 ± 표준)

exp1orer

루프 당 19 초 ± 77.1ms
(평균 7 회 실행, 각 1 회 루프 평균 ± 표준)

이제 큰 카디널리티 데이터 세트에서 x10 속도가 향상되었습니다.


당신이 이것을 UV라면이 3 가지 대답을 UV로해라!


17

(이 솔루션은이 기사 https://pbpython.com/pandas_transform.html 에서 영감을 받았습니다 )

다음 솔루션을 사용하는 것이 가장 간단하고 아마도 가장 빠릅니다 transformation.

변환 : 집계는 축소 된 버전의 데이터를 반환해야하지만 변환은 전체 데이터의 일부 변환 된 버전을 다시 결합하여 반환 할 수 있습니다. 이러한 변환의 경우 출력은 입력과 동일한 모양입니다.

따라서를 사용 transformation하면 솔루션은 1 라이너입니다.

df['%'] = 100 * df['sales'] / df.groupby('state')['sales'].transform('sum')

그리고 당신이 인쇄하면 :

print(df.sort_values(['state', 'office_id']).reset_index(drop=True))

   state  office_id   sales          %
0     AZ          2  195197   9.844309
1     AZ          4  877890  44.274352
2     AZ          6  909754  45.881339
3     CA          1  614752  50.415708
4     CA          3  395340  32.421767
5     CA          5  209274  17.162525
6     CO          1  549430  42.659629
7     CO          3  457514  35.522956
8     CO          5  280995  21.817415
9     WA          2  828238  35.696929
10    WA          4  719366  31.004563
11    WA          6  772590  33.298509

3
@Cancer 이것은 df를 df로 유지하고 (series로 변환하지 않고) % 열을 추가하기 때문에 가장 좋아하는 대답입니다. 감사합니다
T.Fung

이 답변의 변형은 저에게 매우 효과적이었습니다transform('max')
Sheldore

11

나는 이것이 오래된 질문이라는 것을 알고 있지만 exp1orer의 대답은 많은 고유 그룹 (아마 람다 때문에)이있는 데이터 세트의 경우 매우 느립니다. 나는 그것들을 배열 계산으로 바꾸기 위해 그들의 답을 얻었으므로 이제는 매우 빠릅니다! 아래는 예제 코드입니다.

50,000 개의 고유 그룹으로 테스트 데이터 프레임 생성

import random
import string
import pandas as pd
import numpy as np
np.random.seed(0)

# This is the total number of groups to be created
NumberOfGroups = 50000

# Create a lot of groups (random strings of 4 letters)
Group1     = [''.join(random.choice(string.ascii_uppercase) for _ in range(4)) for x in range(NumberOfGroups/10)]*10
Group2     = [''.join(random.choice(string.ascii_uppercase) for _ in range(4)) for x in range(NumberOfGroups/2)]*2
FinalGroup = [''.join(random.choice(string.ascii_uppercase) for _ in range(4)) for x in range(NumberOfGroups)]

# Make the numbers
NumbersForPercents = [np.random.randint(100, 999) for _ in range(NumberOfGroups)]

# Make the dataframe
df = pd.DataFrame({'Group 1': Group1,
                   'Group 2': Group2,
                   'Final Group': FinalGroup,
                   'Numbers I want as percents': NumbersForPercents})

그룹화하면 다음과 같습니다.

                             Numbers I want as percents
Group 1 Group 2 Final Group                            
AAAH    AQYR    RMCH                                847
                XDCL                                182
        DQGO    ALVF                                132
                AVPH                                894
        OVGH    NVOO                                650
                VKQP                                857
        VNLY    HYFW                                884
                MOYH                                469
        XOOC    GIDS                                168
                HTOY                                544
AACE    HNXU    RAXK                                243
                YZNK                                750
        NOYI    NYGC                                399
                ZYCI                                614
        QKGK    CRLF                                520
                UXNA                                970
        TXAR    MLNB                                356
                NMFJ                                904
        VQYG    NPON                                504
                QPKQ                                948
...
[50000 rows x 1 columns]

백분율을 찾는 배열 방법 :

# Initial grouping (basically a sorted version of df)
PreGroupby_df = df.groupby(["Group 1","Group 2","Final Group"]).agg({'Numbers I want as percents': 'sum'}).reset_index()
# Get the sum of values for the "final group", append "_Sum" to it's column name, and change it into a dataframe (.reset_index)
SumGroup_df = df.groupby(["Group 1","Group 2"]).agg({'Numbers I want as percents': 'sum'}).add_suffix('_Sum').reset_index()
# Merge the two dataframes
Percents_df = pd.merge(PreGroupby_df, SumGroup_df)
# Divide the two columns
Percents_df["Percent of Final Group"] = Percents_df["Numbers I want as percents"] / Percents_df["Numbers I want as percents_Sum"] * 100
# Drop the extra _Sum column
Percents_df.drop(["Numbers I want as percents_Sum"], inplace=True, axis=1)

이 방법은 약 0.15 초가 소요됩니다

최고 답변 방법 (람다 함수 사용) :

state_office = df.groupby(['Group 1','Group 2','Final Group']).agg({'Numbers I want as percents': 'sum'})
state_pcts = state_office.groupby(level=['Group 1','Group 2']).apply(lambda x: 100 * x / float(x.sum()))

이 방법은 동일한 결과를 생성하는 데 약 21 초가 걸립니다.

결과:

      Group 1 Group 2 Final Group  Numbers I want as percents  Percent of Final Group
0        AAAH    AQYR        RMCH                         847               82.312925
1        AAAH    AQYR        XDCL                         182               17.687075
2        AAAH    DQGO        ALVF                         132               12.865497
3        AAAH    DQGO        AVPH                         894               87.134503
4        AAAH    OVGH        NVOO                         650               43.132050
5        AAAH    OVGH        VKQP                         857               56.867950
6        AAAH    VNLY        HYFW                         884               65.336290
7        AAAH    VNLY        MOYH                         469               34.663710
8        AAAH    XOOC        GIDS                         168               23.595506
9        AAAH    XOOC        HTOY                         544               76.404494

9

나는 이미 여기에 좋은 대답이 있다는 것을 알고 있습니다.

그럼에도 불구하고, 나는 이와 같이 초등하고 간단한 질문을 느끼기 때문에 내 자신을 기고하고 싶습니다. 한눈에 이해할 수있는 짧은 해결책이 있어야합니다.

또한 백분율을 새 열로 추가하여 나머지 데이터 프레임을 그대로 유지하는 방식으로 작동해야합니다. 마지막으로, 그룹화 수준이 둘 이상인 경우 (예 : 주가 아닌 주와 국가) 명백한 방식으로 일반화해야합니다.

다음 스 니펫은 이러한 기준을 충족합니다.

df['sales_ratio'] = df.groupby(['state'])['sales'].transform(lambda x: x/x.sum())

여전히 Python 2를 사용하는 경우 람다 항의 분모에서 x를 float (x)로 바꿔야합니다.


이것이 최고의 답변 IMO입니다. 추가 * 100하는 것은 백분율로 만드는 것입니다.
Bouncner 2016 년

1
@Bouncner : 예, 엄밀히 말하면 100을 곱하여 백분율을 얻거나 새 변수의 이름을 "sales_percentage"에서 "sales_ratio"로 바꾸어야합니다. 개인적으로 후자를 선호하고 그에 따라 답변을 편집했습니다. 언급 해 주셔서 감사합니다!
MightyCurious

2
여러 수준이있는 경우 작동하지 않습니다.
irene

@irene : 좋은 지적, 감사합니다! 이 경우 df.reset_index (). groupby ([ 'state']) [ 'sales']. transform (lambda x : x / x.sum ())이 작동합니다. 아니면 내가 간과하고 있습니까?
MightyCurious 2016 년

1
이 답변은 훌륭합니다. 임시 groupby객체를 생성하지 않고 매우 간결하며 논리적으로 왼쪽에서 오른쪽으로 읽습니다.
C. Braun

7

열이나 인덱스에서 백분율을 찾는 가장 우아한 방법은을 사용하는 것 pd.crosstab입니다.

샘플 데이터

df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
               'office_id': list(range(1, 7)) * 2,
               'sales': [np.random.randint(100000, 999999) for _ in range(12)]})

출력 데이터 프레임은 다음과 같습니다

print(df)

        state   office_id   sales
    0   CA  1   764505
    1   WA  2   313980
    2   CO  3   558645
    3   AZ  4   883433
    4   CA  5   301244
    5   WA  6   752009
    6   CO  1   457208
    7   AZ  2   259657
    8   CA  3   584471
    9   WA  4   122358
    10  CO  5   721845
    11  AZ  6   136928

인덱스, 열 및 집계 할 값을 지정하십시오. normalize 키워드는 컨텍스트에 따라 인덱스 또는 열에서 %를 계산합니다.

result = pd.crosstab(index=df['state'], 
                     columns=df['office_id'], 
                     values=df['sales'], 
                     aggfunc='sum', 
                     normalize='index').applymap('{:.2f}%'.format)




print(result)
office_id   1   2   3   4   5   6
state                       
AZ  0.00%   0.20%   0.00%   0.69%   0.00%   0.11%
CA  0.46%   0.00%   0.35%   0.00%   0.18%   0.00%
CO  0.26%   0.00%   0.32%   0.00%   0.42%   0.00%
WA  0.00%   0.26%   0.00%   0.10%   0.00%   0.63%

3

sum전체를 전체 DataFrame로 나눌 수 있습니다 state.

# Copying setup from Paul H answer
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
               'office_id': list(range(1, 7)) * 2,
               'sales': [np.random.randint(100000, 999999) for _ in range(12)]})
# Add a column with the sales divided by state total sales.
df['sales_ratio'] = (df / df.groupby(['state']).transform(sum))['sales']

df

보고

    office_id   sales state  sales_ratio
0           1  405711    CA     0.193319
1           2  535829    WA     0.347072
2           3  217952    CO     0.198743
3           4  252315    AZ     0.192500
4           5  982371    CA     0.468094
5           6  459783    WA     0.297815
6           1  404137    CO     0.368519
7           2  222579    AZ     0.169814
8           3  710581    CA     0.338587
9           4  548242    WA     0.355113
10          5  474564    CO     0.432739
11          6  835831    AZ     0.637686

그러나 이것은 state숫자 이외의 모든 열 이 전체 DataFrame의 합계를 가능하게 하기 때문에 작동합니다 . 예를 들어, office_id대신 문자 인 경우 오류가 발생합니다.

df.office_id = df.office_id.astype(str)
df['sales_ratio'] = (df / df.groupby(['state']).transform(sum))['sales']

TypeError : / : 'str'및 'str'에 대해 지원되지 않는 피연산자 유형


열을 제외한 모든 열 groupby이 숫자 인 경우에만 작동한다는 점에 유의하여 편집했습니다 . 그러나 그렇지 않으면 매우 우아합니다. 다른 str열과 함께 작동시키는 방법이 있습니까?
Max Ghenis


2

나는 이것이 한 줄로 트릭을 할 것이라고 생각합니다.

df.groupby(['state', 'office_id']).sum().transform(lambda x: x/np.sum(x)*100)

데이터 세트의 모든 열이 필요하다고 생각합니다. 이 경우에는 하나만 있습니다. 여러 개가 있고 단일 작업에서이 작업을 수행하려면 그룹 별 식 뒤에 지정하십시오. df.groupby ([ 'state', 'office_id']) [[YOUR COLUMN NAME HERE]]. etcetc 다른 열을 그대로 유지하려면 특정 열을 다시 할당하면됩니다.
louisD

@ louisD : 나는 그것을 짧게 유지하려는 당신의 접근 방식을 매우 좋아합니다. 불행히도, 제안한대로 열을 다시 할당하려고하면 두 가지 오류가 발생합니다. TypeError : 프레임 인덱스가있는 삽입 된 열의 호환되지 않는 인덱스 "내가 사용한 코드는 다음과 같습니다. df [ 'percent'] = df.groupby ([ 'state', 'office_id']). sum (). transform (lambda x : x / np.sum (x) * 100) 따라서이 문제를 해결하기 위해 별도의 답변을 게시하겠습니다.
MightyCurious

1

내가 사용한 간단한 방법은 2 그룹 바이가 간단한 나누기를 한 후에 병합하는 것입니다.

import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
               'office_id': list(range(1, 7)) * 2,
               'sales': [np.random.randint(100000, 999999) for _ in range(12)]})

state_office = df.groupby(['state', 'office_id'])['sales'].sum().reset_index()
state = df.groupby(['state'])['sales'].sum().reset_index()
state_office = state_office.merge(state, left_on='state', right_on ='state', how = 'left')
state_office['sales_ratio'] = 100*(state_office['sales_x']/state_office['sales_y'])

   state  office_id  sales_x  sales_y  sales_ratio
0     AZ          2   222579  1310725    16.981365
1     AZ          4   252315  1310725    19.250033
2     AZ          6   835831  1310725    63.768601
3     CA          1   405711  2098663    19.331879
4     CA          3   710581  2098663    33.858747
5     CA          5   982371  2098663    46.809373
6     CO          1   404137  1096653    36.851857
7     CO          3   217952  1096653    19.874290
8     CO          5   474564  1096653    43.273852
9     WA          2   535829  1543854    34.707233
10    WA          4   548242  1543854    35.511259
11    WA          6   459783  1543854    29.781508

1
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
               'office_id': list(range(1, 7)) * 2,
               'sales': [np.random.randint(100000, 999999)
                         for _ in range(12)]})

grouped = df.groupby(['state', 'office_id'])
100*grouped.sum()/df[["state","sales"]].groupby('state').sum()

보고:

sales
state   office_id   
AZ  2   54.587910
    4   33.009225
    6   12.402865
CA  1   32.046582
    3   44.937684
    5   23.015735
CO  1   21.099989
    3   31.848658
    5   47.051353
WA  2   43.882790
    4   10.265275
    6   45.851935

0

팬더를 배우는 사람으로서 팬더가 대부분의 작업을 배후에서 숨기므로 다른 답변이 약간 암시 적이라는 것을 알았습니다. 즉, 열과 색인 이름을 자동으로 일치시켜 작업이 작동하는 방식입니다. 이 코드는 @ exp1orer의 승인 된 답변의 단계별 버전과 동일해야합니다.

를 사용하여 df별명으로 호출합니다 state_office_sales.

                  sales
state office_id        
AZ    2          839507
      4          373917
      6          347225
CA    1          798585
      3          890850
      5          454423
CO    1          819975
      3          202969
      5          614011
WA    2          163942
      4          369858
      6          959285

state_total_sales되고 state_office_sales총 합계로 그룹화 index level 0(가장 왼쪽).

In:   state_total_sales = df.groupby(level=0).sum()
      state_total_sales

Out: 
       sales
state   
AZ     2448009
CA     2832270
CO     1495486
WA     595859

두 개의 데이터 프레임이 인덱스 이름을 공유하고 열 이름 팬더는 다음과 같은 공유 인덱스를 통해 적절한 위치를 찾습니다.

In:   state_office_sales / state_total_sales

Out:  

                   sales
state   office_id   
AZ      2          0.448640
        4          0.125865
        6          0.425496
CA      1          0.288022
        3          0.322169
        5          0.389809
CO      1          0.206684
        3          0.357891
        5          0.435425
WA      2          0.321689
        4          0.346325
        6          0.331986

이를 더 잘 설명하기 위해 여기에 해당하는 부분 합계가 XX있습니다. 팬더는 색인 및 열 이름을 기준으로 위치를 일치 시키며, 중복 팬더가 없으면 무시합니다.

In:   partial_total = pd.DataFrame(
                      data   =  {'sales' : [2448009, 595859, 99999]},
                      index  =             ['AZ',    'WA',   'XX' ]
                      )
      partial_total.index.name = 'state'


Out:  
         sales
state
AZ       2448009
WA       595859
XX       99999
In:   state_office_sales / partial_total

Out: 
                   sales
state   office_id   
AZ      2          0.448640
        4          0.125865
        6          0.425496
CA      1          NaN
        3          NaN
        5          NaN
CO      1          NaN
        3          NaN
        5          NaN
WA      2          0.321689
        4          0.346325
        6          0.331986

이것은 공유 인덱스 나 열이 없을 때 매우 분명해집니다. 여기 missing_index_totals같다 state_total_sales그것은 노의 인덱스 이름을 가진 것을 제외하고.

In:   missing_index_totals = state_total_sales.rename_axis("")
      missing_index_totals

Out:  
       sales
AZ     2448009
CA     2832270
CO     1495486
WA     595859
In:   state_office_sales / missing_index_totals 

Out:  ValueError: cannot join with no overlapping index names

-1

단선 솔루션 :

df.join(
    df.groupby('state').agg(state_total=('sales', 'sum')),
    on='state'
).eval('sales / state_total')

이렇게하면 일련의 사무실 별 비율이 반환됩니다. 자체적으로 사용하거나 원래 데이터 프레임에 할당 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.