Python 计算DataFrameGroupBy对象列的频率(熊猫)

Python 计算DataFrameGroupBy对象列的频率(熊猫),python,pandas,Python,Pandas,对于以下数据集: Index ADR EF INF SS class type 1 1 1 0 0 SRI F 2 1 0 1 1 SRI h 3 0 1 0 0 NRI N 4 0 0 1 1 NRI u 5 1 0 1

对于以下数据集:

Index    ADR   EF   INF   SS    class   type
1         1     1    0     0     SRI     F
2         1     0    1     1     SRI     h
3         0     1    0     0     NRI     N
4         0     0    1     1     NRI     u
5         1     0    1     1     NRI     l
我需要首先根据列“class”(两组:SRI、NRI)中的值对数据进行分组,然后计算列ADR、EF、INF、SS的频率。这是我的代码:

 print (df.groupby("class").ADR.value_counts())
    print (df.groupby("class").EF.value_counts())
    print (df.groupby("class").INF.value_counts())
    print (df.groupby("class").SS.value_counts())

但我更喜欢把它写成函数。有什么建议吗?

这更具挑战性,因为您希望在数量可变的列上执行此操作

您可以先使用
df.groupby
,然后使用
df.agg

In [1085]: df.groupby('class').agg(lambda x: [np.bincount(x)]).applymap(lambda x: x[0])
Out[1085]: 
          ADR      EF     INF      SS
class                                
NRI    [2, 1]  [2, 1]  [1, 2]  [1, 2]
SRI    [0, 2]  [1, 1]  [1, 1]  [1, 1]
同样,对于选择性聚合,接受列列表的函数将执行以下操作:

def foo(df, type, columns):
    return df.groupby(type)[columns].agg(lambda x: [np.bincount(x)]).applymap(lambda x: x[0])

这更具挑战性,因为您希望对数量可变的列执行此操作

您可以先使用
df.groupby
,然后使用
df.agg

In [1085]: df.groupby('class').agg(lambda x: [np.bincount(x)]).applymap(lambda x: x[0])
Out[1085]: 
          ADR      EF     INF      SS
class                                
NRI    [2, 1]  [2, 1]  [1, 2]  [1, 2]
SRI    [0, 2]  [1, 1]  [1, 1]  [1, 1]
同样,对于选择性聚合,接受列列表的函数将执行以下操作:

def foo(df, type, columns):
    return df.groupby(type)[columns].agg(lambda x: [np.bincount(x)]).applymap(lambda x: x[0])

或者你可以试试这个

List=[]
List2=[]
for names,df1 in df.groupby('class'):
    print(df1)
    List.append(df1.drop(['class','type'],axis=1).apply(pd.value_counts, axis=0))
    List2.append(names)

pd.concat(List,keys=List2).fillna(0)

Out[110]: 
       ADR  EF  INF  SS
NRI 0  2.0   2    1   1
    1  1.0   1    2   2
SRI 0  0.0   1    1   1
    1  2.0   1    1   1

或者你可以试试这个

List=[]
List2=[]
for names,df1 in df.groupby('class'):
    print(df1)
    List.append(df1.drop(['class','type'],axis=1).apply(pd.value_counts, axis=0))
    List2.append(names)

pd.concat(List,keys=List2).fillna(0)

Out[110]: 
       ADR  EF  INF  SS
NRI 0  2.0   2    1   1
    1  1.0   1    2   2
SRI 0  0.0   1    1   1
    1  2.0   1    1   1
[135]中的
:df.drop(['Index','type',1)\
…:.groupby(“类”)\
…:.agg([lambda x:x.eq(0.sum(),'sum']))\
…:.rename(列={'':0,'sum':1})\
…:.重命名_轴(无)\
…:.stack()
出[135]:
ADR EF INF SS
NRI02211
1    1   1    2   2
斯里兰卡01 01
1    2   1    1   1
或作为多列DF:

In [125]: df.drop(['Index','type'],1) \
     ...:   .groupby("class") \
     ...:   .agg([lambda x: x.eq(0).sum(), 'sum']) \
     ...:   .rename(columns={'<lambda>':0,'sum':1}) \
     ...:   .rename_axis(None)
Out[125]:
    ADR    EF    INF    SS
      0  1  0  1   0  1  0  1
NRI   2  1  2  1   1  2  1  2
SRI   0  2  1  1   1  1  1  1
[125]中的
:df.drop(['Index','type',1)\
…:.groupby(“类”)\
…:.agg([lambda x:x.eq(0.sum(),'sum']))\
…:.rename(列={'':0,'sum':1})\
…:.重命名_轴(无)
出[125]:
ADR EF INF SS
0  1  0  1   0  1  0  1
NRI 2 1 2 1 2 1 2
斯里兰卡0 2 1 1 1
在[135]中:df.drop(['Index','type'],1)\
…:.groupby(“类”)\
…:.agg([lambda x:x.eq(0.sum(),'sum']))\
…:.rename(列={'':0,'sum':1})\
…:.重命名_轴(无)\
…:.stack()
出[135]:
ADR EF INF SS
NRI02211
1    1   1    2   2
斯里兰卡01 01
1    2   1    1   1
或作为多列DF:

In [125]: df.drop(['Index','type'],1) \
     ...:   .groupby("class") \
     ...:   .agg([lambda x: x.eq(0).sum(), 'sum']) \
     ...:   .rename(columns={'<lambda>':0,'sum':1}) \
     ...:   .rename_axis(None)
Out[125]:
    ADR    EF    INF    SS
      0  1  0  1   0  1  0  1
NRI   2  1  2  1   1  2  1  2
SRI   0  2  1  1   1  1  1  1
[125]中的
:df.drop(['Index','type',1)\
…:.groupby(“类”)\
…:.agg([lambda x:x.eq(0.sum(),'sum']))\
…:.rename(列={'':0,'sum':1})\
…:.重命名_轴(无)
出[125]:
ADR EF INF SS
0  1  0  1   0  1  0  1
NRI 2 1 2 1 2 1 2
斯里兰卡0 2 1 1 1

那么这里的类别是什么?对不起,我已经解决了。你说的“将其作为函数编写”是什么意思?函数是否应该打印内容、返回数据或其他内容。。?或者你是在问如何写函数?那么这里的类别是什么?对不起,我已经修好了。你说的“把它写成函数”是什么意思?函数是否应该打印内容、返回数据或其他内容。。?还是你在问如何编写函数?@COLDSPEED,谢谢。因此,无法将groupby的值(此处为“class”)作为函数的输入变量进行传递?@Mary编辑。您可以,但不确定它对其他列的工作方式。编辑了我的答案。@COLDSPEED,你能解释一下“np.bincount(x)”是如何工作的吗?@Mary计算0和1的频率:)示例:
np.bincount([0,1,0,1,0,0,0,0])
产生
数组([6,3])
@COLDSPEE,对不起。它有以下错误:“无法根据规则“safe”将数组数据从dtype('float64')强制转换为dtype('int64'),因此我需要将type设置为“int”。“是吗?”COLDSPEED,谢谢你。因此,无法将groupby的值(此处为“class”)作为函数的输入变量进行传递?@Mary编辑。您可以,但不确定它对其他列的工作方式。编辑了我的答案。@COLDSPEED,你能解释一下“np.bincount(x)”是如何工作的吗?@Mary计算0和1的频率:)示例:
np.bincount([0,1,0,1,0,0,0,0])
产生
数组([6,3])
@COLDSPEE,对不起。它有以下错误:“无法根据规则“safe”将数组数据从dtype('float64')强制转换为dtype('int64'),因此我需要将type设置为“int”。对