2

我正在玩熊猫,并且在弄清楚如何解决以下问题时遇到了问题。给定一个 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 个读者都是不同的,并且不一定阅读所有给定读者的书单。

4

2 回答 2

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
于 2013-05-31T03:45:31.243 回答
1

应该有很多方法可以解决您的问题。这是我的,可能不是最好的:

首先,获取 reader1 的 bookIds

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

其次,选择那些 readerId == 1 并且 bookId 在上面的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

最后,按 readerId 分组并计数

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
于 2013-05-31T03:42:22.633 回答