Hapus dan kembalikan nilai nilai untuk setiap variabel?

19

Saya memiliki kerangka data yang mencatat respons dari pilihan bahasa pemrograman 19717 orang melalui pertanyaan pilihan ganda. Kolom pertama tentu saja jenis kelamin responden sementara sisanya adalah pilihan yang mereka pilih. Dan karenanya jika saya memilih Python maka respons saya akan dicatat dalam kolom Python dan bukan bash dan sebaliknya.

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

Yang saya inginkan adalah tabel yang mengembalikan jumlah instance dari masing-masing kategori di bawah Gendercatatan. Oleh karena itu jika 5000 pria berkode Python dan 3000 wanita di JS, maka saya harus mendapatkan ini:

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

Saya sudah mencoba beberapa opsi:

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

Dan bukan itu yang diperlukan seperti dijelaskan di atas. Bisakah ini dilakukan dalam panda?

Shiv_90
sumber

Jawaban:

7

Gagasan lain adalah nilai di sepanjang sumbu 1, lalu :apply joinget_dummiesgroupby

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

[di luar]

                   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
Chris A
sumber
7

Anda dapat menetapkan Gendersebagai indeks dan jumlah:

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

Keluaran:

                   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
Quang Hoang
sumber
Untuk beberapa alasan ini mengembalikan semua 0s untuk setiap Genderindeks.
Shiv_90
4

Asumsikan Anda nanyaitu NaN(yaitu tidak string), kita dapat mengambil keuntungan dari countkarena mengabaikan NaNuntuk mendapatkan output yang diinginkan

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
Andy L.
sumber
3

Anda bisa meltdan menggunakannyacrosstab

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
Datanovice
sumber
2

Mari kita dorong ke satu baris

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
YOBEN_S
sumber