ยกเลิกการนับและส่งคืนค่านับสำหรับแต่ละตัวแปรหรือไม่


19

ฉันมีกรอบข้อมูลที่บันทึกการตอบสนองการเลือกภาษาของคนจำนวน 19717 โปรแกรมผ่านคำถามแบบปรนัย แน่นอนว่าคอลัมน์แรกนั้นเป็นเพศของผู้ตอบขณะที่ส่วนที่เหลือเป็นตัวเลือกที่พวกเขาเลือก และด้วยเหตุนี้ถ้าฉันเลือก Python การตอบสนองของฉันจะถูกบันทึกในคอลัมน์ Python ไม่ใช่การทุบตีและในทางกลับกัน

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ระเบียน ดังนั้นหากผู้ชาย 5,000 คนเขียนรหัสใน Python และผู้หญิง 3,000 คนใน 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

และไม่ใช่สิ่งที่จำเป็นตามที่อธิบายไว้ข้างต้น สิ่งนี้สามารถทำได้ในแพนด้าหรือไม่?

คำตอบ:


7

แนวคิดอีกประการหนึ่งก็คือค่าต่างๆตามแกน 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

7

คุณสามารถตั้งค่า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

ด้วยเหตุผลบางอย่างนี่จะคืนค่า 0s ทั้งหมดสำหรับทุกGenderดัชนี
Shiv_90

4

สมมติว่าคุณnanคือNaN(เช่นไม่ใช่สตริง) เราอาจใช้ประโยชน์จาก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

3

คุณสามารถ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

2

ให้เรากดหนึ่งบรรทัด

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.