如何根据大熊猫另一栏中的条件计算记录的频率?

时间:2018-01-06 02:30:30

标签: python pandas

我有一张这样的表:

In [2]: df = pd.DataFrame({
   ...:     'donorID':[101,101,101,102,103,101,101,102,103],
   ...:     'recipientID':[11,11,21,21,31,11,21,31,31],
   ...:     'amount':[100,200,500,200,200,300,200,200,100],
   ...:     'year':[2014,2014,2014,2014,2014,2015,2015,2015,2015]
   ...: })

In [3]: df
Out[3]:
   amount  donorID  recipientID  year
0     100      101           11  2014
1     200      101           11  2014
2     500      101           21  2014
3     200      102           21  2014
4     200      103           31  2014
5     300      101           11  2015
6     200      101           21  2015
7     200      102           31  2015
8     100      103           31  2015

我想计算捐赠者的捐赠者 - 受者对的数量(同一捐赠者在n年内向同一个捐赠者捐赠,其中n可以是任何数字,但不一定是连续的,但是我在这里用2来保持简单)。在这种情况下,捐赠者101在2014年以及2015年捐赠给接收者11和21,101的计数是2. 102的数量是0,103的数量是1.结果表看起来像这样:

   donorID  num_donation_2_years
0      101                     2
1      102                     0
2      103                     1

我尝试过使用groupby和pivot_table,但没有设法得到正确的答案。大熊猫的任何建议都会受到赞赏吗?谢谢!

4 个答案:

答案 0 :(得分:3)

这样的东西
df1=df.groupby('donorID').apply(lambda x : x.groupby(x.recipientID).year.nunique().gt(1).sum())
df1
Out[102]: 
donorID
101    2
102    0
103    1
dtype: int64

获取数据框

df1.to_frame('num_donation_2_years').reset_index()
Out[104]: 
   donorID  num_donation_2_years
0      101                     2
1      102                     0
2      103                     1

由于暗示提及不使用apply

这是更新

df1=df.groupby(['donorID','recipientID']).year.nunique().gt(1).sum(level=0)
df1
Out[109]: 
donorID
101    2.0
102    0.0
103    1.0
Name: year, dtype: float64

df1.to_frame('num_donation_2_years').reset_index()
Out[104]: 
   donorID  num_donation_2_years
0      101                     2
1      102                     0
2      103                     1

答案 1 :(得分:3)

@ Wen的解决方案的改进,避免apply更快的速度,即

one = df.groupby(['donorID','recipientID'])['year'].nunique().gt(1)

two = one.groupby(level=0).sum().to_frame('no_of_donations_2_years').reset_index()

    donorID  no_of_donations_2_years
0      101                      2.0
1      102                      0.0
2      103                      1.0

答案 2 :(得分:1)

df_new = df.groupby(["donorID", "recipientID"])["year"].nunique().reset_index(name="year_count")
df_for_query = df_new.groupby(["donorID", "year_count"]).size().reset_index(name='numb_recipient')

    donorID year_count  numb_recipient
 0  101      2            2
 1  102      1            2
 2  103      2            1

第三栏是符合年度条件的患者数量。第0行表示,捐赠者101有2名患者,他/她在两年内捐献。这不完全是您的输出,但您可以从此df轻松查询。

如果你想找到一个捐赠者捐赠的患者数量,比如说2,那么

df_for_query.query("year_count == 2")

        donorID     year_count  numb_recipient
    0    101         2              2
    2    103         2              1

感谢Wen在使用nunique时的灵感!

答案 3 :(得分:0)

以下代码有效(解释为注释)(ol为outlist):

# count frequency of donor-recipient combination
ol = pd.value_counts(df.apply(lambda x: str(x.donorID)+str(x.recipientID), axis=1)) 
ol = ol[ol>=2]                                  # choose only those >= 2
ol.index = list(map(lambda x: x[:3], ol.index)) # get donorID name again 
print(pd.value_counts(ol.index))                # print desired frequency

输出:

101    2
103    1
dtype: int64