我正在玩大熊猫,我遇到了解决如何解决以下问题的问题。给定bookId和readerId的数据框,对于给定的A读者,我想得到读过A读过的任何一本书的其他读者的数量。
这是一个示例数据框
import pandas as pd
df = pd.DataFrame({'bookId': [1,1,2,2,3,3,3,4,4,4,4,4],
'readerId': [1,2,1,3,1,3,4,1,3,4,5,6]})
有人可以帮我解决这个问题,或者在使用熊猫时可能会给我解决问题的直觉吗? 具有readerId和count列的新数据帧将是输出。
更新
实际上,我想了解所有读过我读过的书的读者,而不是每本书的读者数量。因此,如果读者阅读了3本书,其他20本读了这些书,那么我真的希望得到20本作为答案,所有20位读者都是截然不同的,并不一定能阅读所有给定读者的书单。
答案 0 :(得分:2)
为了获得每个读者的计数,这样的事情应该有效:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'bookId': [1,1,2,2,3,3,3,4,4,4,4,4],
...: 'readerId': [1,2,1,3,1,3,4,1,3,4,5,6]})
In [3]: res = pd.DataFrame(np.unique(df.readerId)).reset_index(drop=True)
In [4]: def get_readers(reader, df=df):
...: return len(set(df.readerId[df.bookId.isin(df.bookId[
...: df.readerId==reader])]))-1
In [5]: res['Count'] = res.readerId.apply(get_readers)
In [6]: res
Out[6]:
readerId Count
0 1 5
1 2 1
2 3 4
3 4 4
4 5 4
5 6 4
In [7]: timeit get_readers(1)
1000 loops, best of 3: 387 us per loop
答案 1 :(得分:1)
应该有很多方法可以解决您的问题。这是我的,可能不是最好的一个:
In [99]: bookIds = df[df['readerId']==1]['bookId'].values
In [100]: bookIds
Out[100]: array([1, 2, 3, 4])
如果您熟悉SQL,可以将其视为:SELECT bookId FROM df WHERE readerId == 1
bookIds
数组中In [101]: df2 = df[df['readerId'] != 1 & df['bookId'].isin(bookIds)]
In [102]: df2
Out[102]:
bookId readerId
1 1 2
3 2 3
5 3 3
6 3 4
8 4 3
9 4 4
10 4 5
11 4 6
SQL:SELECT bookId, readerId FROM df WHERE readerId != 1 and bookId in bookIds
In [103]: df2.groupby('readerId').size()
Out[103]:
readerId
2 1
3 3
4 2
5 1
6 1
dtype: int64
SQL:SELECT COUNT(bookId) FROM df2 GROUP BY readerId
希望它可以帮助您更轻松地学习熊猫
In [114]: df2 = df.rename(columns={'readerId': 'otherReaderId'})
bookId
加入他们,然后按readerId
和otherReaderId
In [115]: pd.merge(df, df2, on='bookId').groupby(['readerId', 'otherReaderId']).size()
Out[115]:
readerId otherReaderId
1 1 4
2 1
3 3
4 2
5 1
6 1
2 1 1
2 1
3 1 3
3 3
4 2
5 1
6 1
4 1 2
3 2
4 2
5 1
6 1
5 1 1
3 1
4 1
5 1
6 1
6 1 1
3 1
4 1
5 1
6 1
dtype: int64