簡體   English   中英

從Python中的子組獲取基本統計信息

[英]Get basic statistics from subgroups in Python

我正在使用Python 3.6,正在嘗試從數據集的子組獲取統計信息。 例如,主要分組因子是Uniyear 在這里,我希望獲得其他分組的一些基本統計數據,例如,參加科學課程的女性人數,人數或學生人數及其比例。

直接進行計數的風險是可能會有一些重復計數。 我已經解決了重復計算的問題,但是考慮到有成千上萬的學生以及更多的大學和年份,代碼似乎太長了,第一次分組花費的時間確實很長。 我希望那里還有其他更有效的答案。

df1 = pd.DataFrame([('USC', 2009, 'A', 'X', 'Science', 'F', 50),
               ('USC', 2009, 'A', 'Y', 'Science', 'F', 50),
               ('USC', 2009, 'A', 'Z', 'Arts', 'F', 500),
               ('USC', 2009, 'A', 'W', 'Arts', 'F', 50),
               ('USC', 2009, 'B', 'W', 'Arts', 'M', 500),
               ('USC', 2009, 'B', 'Z', 'Arts', 'M', 50),
               ('USC', 2009, 'C', 'X', 'Science', 'F', 50),
               ('USC', 2009, 'C', 'Y', 'Science', 'F', 500),
               ('USC', 2009, 'C', 'W', 'Arts', 'F', 50),
               ('USC', 2010, 'D', 'X', 'Science', 'M', 50),
               ('USC', 2010, 'D', 'Y', 'Science', 'M', 500),
               ('USC', 2010, 'D', 'W', 'Arts', 'M', 50),
               ('USC', 2010, 'E', 'X', 'Science', 'M', 50),
               ('USC', 2010, 'E', 'Y', 'Science', 'M', 500),
               ('USC', 2010, 'E', 'W', 'Arts', 'M', 50)],
               columns=('Uni', 'year', 'student','course','faculty','gender', 'fee'))

用於編譯最終數據的復雜代碼為:

# first grouping - eliminating duplicities
data_tmp = df1.groupby(['Uni', 'year','student'])
data_gds = data_tmp.agg({'fee': 'sum'})
data_prc = (data_gds
 .join(data_tmp['gender'].apply(lambda x: 1 if (x[x == 'F'].count()>0) else 0))
 .join(data_tmp['faculty'].apply(lambda x: 1 if (x[x == 'Science'].count()>0) else 0 ))
 .reset_index()
)
# second grouping - eliminating students
data_tmp = data_prc.groupby(['Uni', 'year'])
data_gds = data_tmp['student'].apply(lambda x: x.unique().shape[0]).to_frame('Num_student')
data_prc = (data_gds
 .join(data_tmp.agg({'fee': 'sum'}))
 .join(data_tmp.agg({'gender': 'sum'}).rename(columns={'gender': 'gender_female'}) ) 
 .join(data_tmp.agg({'faculty':'sum'}).rename(columns={'faculty': 'faculty_Science'}))              
 .reset_index()
)
# adding percetages here
data_prc['Prc_Female']  = data_prc['gender_female']/data_prc['Num_student']
data_prc['Prc_Science'] = data_prc['faculty_Science']/data_prc['Num_student']

另外,我實際上並不需要使用費用總和,但是似乎使用聚合允許我使用聯接。 似乎聯接語句是花費較長時間的語句,我希望有一種避免使用它們(或使其變得更好)的方法。

上面的答案看起來像這樣: 在此處輸入圖片說明

我們可以大大簡化您當前的代碼,也不需要lambdas

def make_stats(df):
    base = df.groupby(['Uni', 'year'], as_index=False) \
             .agg({'student': pd.Series.nunique, 'fee': sum}) \
             .rename(columns={'student': 'num_student'})

    females = df[df.gender == 'F'].groupby(['Uni', 'year'], as_index=False) \
                                  .agg({'student': pd.Series.nunique}) \
                                  .rename(columns={'student': 'gender_female'})

    science = df[df.faculty == 'Science'].groupby(['Uni', 'year'], as_index=False) \
                                         .agg({'course': pd.Series.nunique}) \
                                         .rename(columns={'course': 'faculty_science'})

    kwargs = {'how': 'left', 
              'left_on': ['Uni', 'year'], 
              'right_on': ['Uni', 'year']}

    step_1 = pd.merge(base, females, **kwargs)
    step_2 = pd.merge(step_1, science, **kwargs).fillna(0)

    step_2['prc_female'] = step_2['gender_female'] / step_2['num_student']
    step_2['prc_science'] = step_2['faculty_science'] / step_2['num_student']

    return step_2

output = make_stats(df1)

print(output)

   Uni  year  num_student   fee  gender_female  faculty_science  prc_female  prc_science
0  USC  2009            3  1800            2.0                2    0.666667     0.666667
1  USC  2010            2  1200            0.0                2    0.000000     1.000000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM