如何使用groupby和.loc顺序过滤数据帧

时间:2019-08-18 19:05:55

标签: python pandas-groupby

我有一个很大的数据框,其中包含有关食品的信息。例如:

     Year    Journal    Subscription    Known_author
0    2014       A            1               1
1    2014       A            1               0 
2    2014       B            0               1
3    2014       C            1               0
4    2015       A            1               1
5    2015       B            1               1
6    2015       C            0               1
7    2015       D            0               0

我希望能够按年份分组并创建一个表,该表包含(1)每年的唯一期刊数,(2)订阅的唯一期刊数和(3)可以订阅的唯一期刊数有订阅和一位知名作者。

这是我在这种情况下要查找的表:

Year   (1) Column         (2) Column      (3) Column
2014       3                   2               1
2015       4                   2               2 

我用过:

(1)df.groupby('Pub_Date_Year')['Journal'].agg('nunique')用于第一列

(2)df.loc[(df['Subscription']==1)&(df['Year']==2014),'Journal'].agg(['nunique']).values[0]

(3)df.loc[(df['Subscription']==1)&(df['Known_author']==1)&(df['Year']==2014),'Journal'].agg(['nunique']).values[0]

但是,我希望一次性创建该表,我假设使用groupby,aggregate和某种lambda函数。最终的想法是随着我们获得更多数据而使此过程自动化,而不必依靠手动更改df.loc代码中的年份。

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:0)

您猜到了,您需要在自定义函数中使用groupbyapply

def grouping(x):
    journal_uniq = x['Journal'].nunique()
    journal_subs = x.groupby('Journal').apply(lambda d : d['Subscription'].sum() > 0).sum()
    journal_author = x.groupby('Journal').apply(lambda d : ((((d['Subscription'] == 1) & (d['Known_author'] == 1)).sum()) > 0)).sum()
    return pd.Series([journal_uniq, journal_subs, journal_author])

ddf = df.groupby('Year').apply(grouping)

使用示例输入,将返回:

      0  1  2
Year         
2014  3  2  1
2015  4  2  2

该功能的更多详细信息:

  • journal_uniq是第一列中的值。它使用'Journal'计算nunique列中的唯一值,您已经完成了此步骤。
  • journal_subs是第二列中的值。由于您需要唯一的日记帐,因此您也需要对'Journal'进行分组,并检查'Subscription'的总和是否大于零。第二个sum函数将True个值的数量相加(True强制转换为1,False强制转换为0)。
  • journal_author是第三列中的值。第二列的逻辑相同,但更为复杂,因为您需要检查'Subscription''Known_author'列在同一行上均等于1。
  • 返回的pandas.Series是最终数据帧的一行。