[python] 각 변수에 대해 스택 및 반환 값 카운트?

객관식 질문을 통해 19717 명이 선택한 프로그래밍 언어의 응답을 기록하는 데이터 프레임이 있습니다. 첫 번째 열은 물론 응답자의 성별이며 나머지는 그들이 선택한 선택입니다. 따라서 Python을 선택하면 내 응답이 Python 열에 기록되고 bash가 아니며 그 반대도 마찬가지입니다.

ID     Gender              Python    Bash    R    JavaScript    C++
0      Male                Python    nan     nan  JavaScript    nan
1      Female              nan       nan     R    JavaScript    C++
2      Prefer not to say   Python    Bash    nan  nan           nan
3      Male                nan       nan     nan  nan           nan

내가 원하는 것은 Gender레코드 아래의 각 범주의 인스턴스 수를 반환하는 테이블입니다 . 따라서 5000 명의 남성이 Python으로 코딩하고 3000 명의 여성이 JS로 코딩하면 다음과 같이해야합니다.

Gender              Python    Bash    R    JavaScript    C++
Male                5000      1000    800  1500          1000
Female              4000      500     1500 3000          800
Prefer Not To Say   2000      ...   ...    ...           860

몇 가지 옵션을 시도했습니다.

df.iloc[:, [*range(0, 13)]].stack().value_counts()

Male                       16138
Python                     12841
SQL                         6532
R                           4588
Female                      3212
Java                        2267
C++                         2256
Javascript                  2174
Bash                        2037
C                           1672
MATLAB                      1516
Other                       1148
TypeScript                   389
Prefer not to say            318
None                          83
Prefer to self-describe       49
dtype: int64

그리고 위에서 설명한대로 필요한 것은 아닙니다. 이것은 판다에서 할 수 있습니까?



답변

또 다른 아이디어는하는 것 , 축 (1)에 따라 값 다음 :apply joinget_dummiesgroupby

(df.loc[:, 'Python':]
 .apply(lambda x: '|'.join(x.dropna()), axis=1)
 .str.get_dummies('|')
 .groupby(df['Gender']).sum())

[밖]

                   Bash  C++  JavaScript  Python  R
Gender
Female                0    1           1       0  1
Male                  0    0           1       1  0
Prefer not to say     1    0           0       1  0


답변

Gender인덱스 및 합계로 설정할 수 있습니다 .

s = df.set_index('Gender').iloc[:, 1:]
s.eq(s.columns).astype(int).sum(level=0)

산출:

                   Python  Bash  R  JavaScript  C++
Gender
Male                    1     0  0           1    0
Female                  0     0  1           1    1
Prefer not to say       1     1  0           0    0


답변

당신 nanNaN(즉 문자열이 아니라고) 가정 하면, 우리는 원하는 출력을 얻는 count것을 무시 NaN하기 때문에 활용할 수 있습니다

df_out = df.iloc[:,2:].groupby(df.Gender, sort=False).count()

Out[175]:
                   Python  Bash  R  JavaScript  C++
Gender
Male                    1     0  0           1    0
Female                  0     0  1           1    1
Prefer not to say       1     1  0           0    0


답변

당신은 melt사용할 수 있습니다crosstab

df1 = pd.melt(df,id_vars=['ID','Gender'],var_name='Language',value_name='Choice')
df1['Choice'] = np.where(df1['Choice'] == df1['Language'],1,0)
final= pd.crosstab(df1['Gender'],df1['Language'],values=df1['Choice'],aggfunc='sum')

print(final)
Language              Bash  C++  JavaScript  Python  R
Gender
Female                  0    1           1       0  1
Male                    0    0           1       1  0
Prefer not to say       1    0           0       1  0


답변

한 줄로 밀자

df.drop('ID',1).melt('Gender').\
    query('variable==value').\
      groupby(['Gender','variable']).size().unstack(fill_value=0)
Out[120]:
variable        Bash  C++  JavaScript  Python  R
Gender
Female             0    1           1       0  1
Male               0    0           1       1  0
Prefernottosay     1    0           0       1  0


답변