我有一张这样的表:
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,但没有设法得到正确的答案。大熊猫的任何建议都会受到赞赏吗?谢谢!
答案 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