查找数据框中所有分类列中每个值的频率
Finding frequency of each value in all categorical columns across a dataframe
我有一个如下所示的数据框
df = pd.DataFrame(
{'sub_code' : ['CSE01', 'CSE01', 'CSE01',
'CSE02', 'CSE03', 'CSE04',
'CSE05', 'CSE06'],
'stud_level' : [101, 101, 101, 101,
101, 101, 101, 101],
'grade' : ['STA','STA','PSA','STA','STA','SSA','PSA','QSA']})
我想做以下事情
a) 获取数据框所有分类列中每个唯一值的频率
我尝试了下面的方法,但它既不高效也不优雅
df['sub_code'].value_counts() # need to key in column name manually
df['grade'].value_counts() # need to key in column name manually
df.select_dtypes(include='object').value_counts() #produces incorrect output
由于我的真实数据有200多列和100k行,有没有有效的方法来做到这一点?
我希望我的输出如下所示。如果有任何其他更好的方式来显示以下输出,我也欢迎。我不知道如何以简洁的方式捕获这些信息。所以,请分享您的建议
使用melt
和value_counts
:
out = (df.select_dtypes(object)
.melt(var_name="Column", value_name="Value")
.value_counts(dropna=False)
.reset_index(name="Frequency")
.sort_values(by=['Column','Frequency','Variable'], ascending=[True,False,True])
.reset_index(drop=True))
输出:
Column Variable Frequency
0 grade STA 4
1 grade PSA 2
2 grade QSA 1
3 grade SSA 1
4 sub_code CSE01 3
5 sub_code CSE02 1
6 sub_code CSE03 1
7 sub_code CSE04 1
8 sub_code CSE05 1
9 sub_code CSE06 1
另一种方法是使用,get_dummies
s=pd.get_dummies(df.drop(columns=['stud_level'])).sum(0).to_frame('Freq').reset_index()
s=s['index'].str.split('\_(?=[A-Z0-9]+$)', expand=True).join(s.iloc[:,-1]).rename(columns={0:'Column',1:'Value'})
结果
Column Value Freq
0 sub_code CSE01 3
1 sub_code CSE02 1
2 sub_code CSE03 1
3 sub_code CSE04 1
4 sub_code CSE05 1
5 sub_code CSE06 1
6 grade PSA 2
7 grade QSA 1
8 grade SSA 1
9 grade STA 4
我有一个如下所示的数据框
df = pd.DataFrame(
{'sub_code' : ['CSE01', 'CSE01', 'CSE01',
'CSE02', 'CSE03', 'CSE04',
'CSE05', 'CSE06'],
'stud_level' : [101, 101, 101, 101,
101, 101, 101, 101],
'grade' : ['STA','STA','PSA','STA','STA','SSA','PSA','QSA']})
我想做以下事情
a) 获取数据框所有分类列中每个唯一值的频率
我尝试了下面的方法,但它既不高效也不优雅
df['sub_code'].value_counts() # need to key in column name manually
df['grade'].value_counts() # need to key in column name manually
df.select_dtypes(include='object').value_counts() #produces incorrect output
由于我的真实数据有200多列和100k行,有没有有效的方法来做到这一点?
我希望我的输出如下所示。如果有任何其他更好的方式来显示以下输出,我也欢迎。我不知道如何以简洁的方式捕获这些信息。所以,请分享您的建议
使用melt
和value_counts
:
out = (df.select_dtypes(object)
.melt(var_name="Column", value_name="Value")
.value_counts(dropna=False)
.reset_index(name="Frequency")
.sort_values(by=['Column','Frequency','Variable'], ascending=[True,False,True])
.reset_index(drop=True))
输出:
Column Variable Frequency
0 grade STA 4
1 grade PSA 2
2 grade QSA 1
3 grade SSA 1
4 sub_code CSE01 3
5 sub_code CSE02 1
6 sub_code CSE03 1
7 sub_code CSE04 1
8 sub_code CSE05 1
9 sub_code CSE06 1
另一种方法是使用,get_dummies
s=pd.get_dummies(df.drop(columns=['stud_level'])).sum(0).to_frame('Freq').reset_index()
s=s['index'].str.split('\_(?=[A-Z0-9]+$)', expand=True).join(s.iloc[:,-1]).rename(columns={0:'Column',1:'Value'})
结果
Column Value Freq
0 sub_code CSE01 3
1 sub_code CSE02 1
2 sub_code CSE03 1
3 sub_code CSE04 1
4 sub_code CSE05 1
5 sub_code CSE06 1
6 grade PSA 2
7 grade QSA 1
8 grade SSA 1
9 grade STA 4