如何分组并计入大熊猫

时间:2017-03-12 16:56:51

标签: pandas

我在pandas中有以下数据框。

 ID            Names               Class
 ABC       [James,Jack,Bob]          A
 DES       [Michel,Sara]             B
 ERT       [Jack,Mike]               A

我想计算每个班级的名字

期望的输出

 Class      Names        Count
  A         James          1
            Jack           2 
            Bob            1
            Mike           1

  B         Michel         1  
            Sara           1

我正在使用以下代码,但它似乎不起作用。

rows = []
_ = df.apply(lambda row: [rows.append([row['Class'], nn]) 
                     for nn in row.Names], axis=1)
df_new = pd.DataFrame(rows, columns=df.columns).set_index(['Class'])

3 个答案:

答案 0 :(得分:1)

<强>解决方案:

In [69]: lst_col = 'Names'
    ...: pd.DataFrame({
    ...:     col:np.repeat(df[col].values, df[lst_col].str.len())
    ...:     for col in df.columns.difference([lst_col])
    ...: }).assign(**{lst_col:np.concatenate(df[lst_col].values)}) \
    ...:   .groupby(['Class','Names']).size()
    ...:
Out[69]:
Class  Names
A      Bob       1
       Jack      2
       James     1
       Mike      1
B      Michel    1
       Sara      1
dtype: int64

<强>解释

In [70]: pd.DataFrame({
    ...:     col:np.repeat(df[col].values, df[lst_col].str.len())
    ...:     for col in df.columns.difference([lst_col])
    ...: })
Out[70]:
  Class   ID
0     A  ABC
1     A  ABC
2     A  ABC
3     B  DES
4     B  DES
5     A  ERT
6     A  ERT

In [71]: pd.DataFrame({
    ...:     col:np.repeat(df[col].values, df[lst_col].str.len())
    ...:     for col in df.columns.difference([lst_col])
    ...: }).assign(**{lst_col:np.concatenate(df[lst_col].values)})
Out[71]:
  Class   ID   Names
0     A  ABC   James
1     A  ABC    Jack
2     A  ABC     Bob
3     B  DES  Michel
4     B  DES    Sara
5     A  ERT    Jack
6     A  ERT    Mike

答案 1 :(得分:1)

我认为您可以numpy.repeat使用str.len来表示重复值,groupby可以使用嵌套lists的平面值chain。两列的最后size并获得sort_values

from  itertools import chain

df1 = pd.DataFrame({
        "Class": np.repeat(df.Class.values, df.Names.str.len()),
        "Names": list(chain.from_iterable(df.Names))})

print (df1)
  Class   Names
0     A   James
1     A    Jack
2     A     Bob
3     B  Michel
4     B    Sara
5     A    Jack
6     A    Mike

print (df1.groupby(['Class','Names']).size())
Class  Names 
A      Bob       1
       Jack      2
       James     1
       Mike      1
B      Michel    1
       Sara      1
dtype: int64

我认为你需要json formater & validator

df2 = df1.groupby(['Class','Names']).size().reset_index(name='Count')
print (df2)
  Class   Names  Count
0     A     Bob      1
1     A    Jack      2
2     A   James      1
3     A    Mike      1
4     B  Michel      1
5     B    Sara      1

print (df2.sort_values(['Class','Names'], ascending=[True, False]))
  Class   Names  Count
3     A    Mike      1
2     A   James      1
1     A    Jack      2
0     A     Bob      1
5     B    Sara      1
4     B  Michel      1
    
print (df2.sort_values(['Class','Count'], ascending=[True, False]))

  Class   Names  Count
1     A    Jack      2
0     A     Bob      1
2     A   James      1
3     A    Mike      1
4     B  Michel      1
5     B    Sara      1

答案 2 :(得分:0)

这应该可以解决问题

df.groupby(['col1', 'col2', .., 'coln']).size()