使用pandas

时间:2017-12-20 12:36:21

标签: python pandas dataframe group-by pandas-groupby

我有一个pandas数据框,其中包含如下所示的数据:

ID  year_month_id   Class
1   201612          A
2   201612          D
3   201612          B
4   201612          Other
5   201612          Other
6   201612          Other
7   201612          A
8   201612          Other
9   201612          A
1   201701          B

因此,ID可以在特定月份的任何课程中,下个月他的课程可能会发生变化。 现在我要做的是为每个ID获取它在特定类下的月数以及它所属的最新类。如下所示:

ID  Class_A Class_B Class_D Other Latest_Class
1   2        3       4         0    B
2   12       0       0         0    D

我如何在python中实现这一目标。 有人可以帮我这个吗? 此外,由于真实数据集很大并且无法手动验证,我如何才能获得超过1类的ID列表?

4 个答案:

答案 0 :(得分:4)

我们可以使用数据透视表和concat,即

ndf = df.pivot_table(index=['ID'],columns=['Class'],aggfunc='count',fill_value=0)\
    .xs('year_month_id', axis=1, drop_level=True)

ndf['latest'] = df.sort_values('ID').groupby('ID')['Class'].tail(1).values

Class  A  B  D  Other latest
ID                          
1      1  1  0      0      B
2      0  0  1      0      D
3      0  1  0      0      B
4      0  0  0      1  Other
5      0  0  0      1  Other
6      0  0  0      1  Other
7      1  0  0      0      A
8      0  0  0      1  Other
9      1  0  0      0      A

答案 1 :(得分:3)

您可以按groupby计算累计count的计数,然后按unstack重新计算。上次使用drop_duplicates添加新列:

df1 = df.groupby(['ID','Class'])['year_month_id'].count().unstack(fill_value=0)
df1['Latest_Class'] = df.drop_duplicates('ID', keep='last').set_index('ID')['Class']
print (df1)
Class  A  B  D  Other Latest_Class
ID                                
1      1  1  0      0            B
2      0  0  1      0            D
3      0  1  0      0            B
4      0  0  0      1        Other
5      0  0  0      1        Other
6      0  0  0      1        Other
7      1  0  0      0            A
8      0  0  0      1        Other
9      1  0  0      0            A

答案 2 :(得分:3)

您可以使用HasPrinciplaKey + groupby + value_counts -

获取参加课程的人数
unstack

要获取最后一个班级,请使用g = df.groupby('ID') i = g.Class.value_counts().unstack(fill_value=0) + groupby -

last

连接以获得结果 -

j = g.Class.last()

要获取每行超过1个的ID列表,请使用pd.concat([i, j], 1).rename(columns={'Class': 'LastClass'}) A B D Other LastClass ID 1 1 1 0 0 B 2 0 0 1 0 D 3 0 1 0 0 B 4 0 0 0 1 Other 5 0 0 0 1 Other 6 0 0 0 1 Other 7 1 0 0 0 A 8 0 0 0 1 Other 9 1 0 0 0 A +掩码 -

sum

答案 3 :(得分:1)

如果只使用count作为aggfunc,只使用pd.crosstab作为 >> new_df = pd.crosstab(df.ID, df.Class) >> new_df Class A B D Other ID 1 1 1 0 0 2 0 0 1 0 3 0 1 0 0 4 0 0 0 1 5 0 0 0 1 6 0 0 0 1 7 1 0 0 0 8 0 0 0 1 9 1 0 0 0 ,使用零填充缺失的条目(正是这种情况),值得考虑使用>> df.groupby('ID').Class.last() ID 1 B 2 D 3 B 4 Other 5 Other 6 Other 7 A 8 Other 9 A

>> new_df = pd.concat([new_df, df.groupby('ID').Class.last()], 1)
    A  B  D  Other  Class
ID
1   1  1  0      0      B
2   0  0  1      0      D
3   0  1  0      0      B
4   0  0  0      1  Other
5   0  0  0      1  Other
6   0  0  0      1  Other
7   1  0  0      0      A
8   0  0  0      1  Other
9   1  0  0      0      A

从初始数据框中获取类的最后一个值,按ID分组并选择最后一个条目:

>> new_df = new_df.rename(columns={'Class':'LastClass'})
    A  B  D  Other LastClass
ID
1   1  1  0      0         B
2   0  0  1      0         D
3   0  1  0      0         B
4   0  0  0      1     Other
5   0  0  0      1     Other
6   0  0  0      1     Other
7   1  0  0      0         A
8   0  0  0      1     Other
9   1  0  0      0         A

然后你可以将它们连接在一起:

>> new_df = pd.concat([pd.crosstab(df.ID, df.Class),df.groupby('ID').Class.last()],1).rename(columns={'Class':'LastClass'})

>> new_df
    A  B  D  Other LastClass
ID
1   1  1  0      0         B
2   0  0  1      0         D
3   0  1  0      0         B
4   0  0  0      1     Other
5   0  0  0      1     Other
6   0  0  0      1     Other
7   1  0  0      0         A
8   0  0  0      1     Other
9   1  0  0      0         A

并按照您的意愿获得输出:

fa-

将所有人放在一起作为oneliner:

var str = '<i class="fa fa-edit"></i>',
    parser = new DOMParser(),
    doc = parser.parseFromString(str, "text/xml");

var x = doc.firstChild.className
          .split(" ")
          .filter(String)
          .filter(function(e) {
            return e.startsWith("fa-");
          });

console.log(x);