Pandas Groupby选择列中具有多个唯一值的组

8ljdwjyq  于 2023-06-28  发布在  其他
关注(0)|答案(5)|浏览(69)

我有一个关于一些艺术家,他们的专辑和他们的曲目的一些信息的数据框架。

df = pd.DataFrame({'Artist': ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'E'], 'AlbumId': [201, 201, 451, 390, 390, 272, 272, 698, 698, 235, 312], 'TrackId': [1022, 3472, 9866, 6078, 2634, 3411, 8673, 2543, 5837, 9874, 1089]})

艺术家A有2张专辑(201和451),其中一张专辑有2首曲目(1022和3472),另一张专辑有1首曲目(9866)。
艺术家B有1张专辑(390)和2首曲目(6078和2634)。
艺术家C有2张专辑(272和698),每张专辑有2首曲目。
艺术家D有1张专辑(235)和1首曲目(9874)。
艺术家E有1张专辑(312)和1首曲目(1089)。
我想找到拥有超过1张专辑的艺术家,并相应地获得这些艺术家的行。我想要的输出如下所示:

我试过:

groupedArtists = data.groupby(['ArtistId', 'AlbumId']).filter(lambda group: (group.AlbumId.nunique() > 1))

但它似乎并不像预期的那样工作。
有人能帮帮我吗?我很感激!

omhiaaxx

omhiaaxx1#

您希望仅按ArtistId而不是AlbumId分组:

groupedArtists = data.groupby(['Artist']).filter(lambda x: x['AlbumId'].nunique() > 1)

输出:

>>> groupedArtists
  Artist  AlbumId  TrackId
0      A      201     1022
1      A      201     3472
2      A      451     9866
5      C      375     1022
6      C      412     9866
7      C      375     3472
...
x33g5p2x

x33g5p2x2#

分组应单独由 * 艺术家 * 进行。
然后,对于每个组,检查它包含多少(不同的)相册,并仅选取具有1个以上相册的组。
所以正确的解决方案是:

data.groupby('Artist').filter(lambda grp: grp.AlbumId.nunique() > 1)
fnx2tebb

fnx2tebb3#

这是我找到的解决方案,它有点冗长,但可能更容易理解:

counted = df.groupby(['Artist']).size().reset_index(name='counts')
df[df['Artist'].isin(counted[counted.counts > 1].Artist)]
h9vpoimq

h9vpoimq4#

一个迟来的响应,但其他解决方案的替代方案如下:

groupedArtists = data[data.groupby('Artist')['AlbumId'].transform('nunique').ne(1)]

与其他方法一样,该方法按艺术家分组,但不应用过滤函数,而是为每个组返回pd.Series数量的唯一专辑,并仅返回nunique不等于1的那些行。
在运行时间的比较中,这稍微快一点:

# my solution
%timeit groupedArtists = data[data.groupby('Artist')['AlbumId'].transform('nunique').ne(1)]
1.08 ms ± 85.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# solution by @Valdi_Bo and @user17242583
%timeit groupedArtists = data.groupby(['Artist']).filter(lambda x: x['AlbumId'].nunique() > 1)
1.81 ms ± 141 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# solution by @Shay Nehmad
%%timeit
counted = df.groupby(['Artist']).size().reset_index(name='counts')
groupedArtists df[df['Artist'].isin(counted[counted.counts > 1].Artist)]
2.03 ms ± 32.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
jgwigjjp

jgwigjjp5#

您可以根据相册的计数创建聚合 Dataframe ,然后根据所需相册的数量进行筛选

stats = df.groupby(['Artist'])['AlbumId'].count().reset_index()
morethan1 = stats.loc[stats['AlbumId'] >1]

相关问题