Pandas,对于一列中的每个唯一值,在另一列中获取唯一值

Posted

技术标签:

【中文标题】Pandas,对于一列中的每个唯一值,在另一列中获取唯一值【英文标题】:Pandas, for each unique value in one column, get unique values in another column 【发布时间】:2018-08-05 09:13:08 【问题描述】:

我有一个数据框,其中每一行都包含与单个 Reddit 评论相关的各种元数据(例如作者、subreddit、评论文本)。

我想做以下事情:对于每个作者,我想获取他们拥有 cmets 的所有 subreddits 的列表,并将这些数据转换为 pandas 数据框,其中每一行对应一个作者,以及所有的列表他们评论的独特子版块。

我目前正在尝试以下一些组合,但无法完成:

尝试 1:

group = df['subreddit'].groupby(df['author']).unique()
list(group) 

尝试 2:

from collections import defaultdict
subreddit_dict  = defaultdict(list)

for index, row in df.iterrows():
    author = row['author']
    subreddit = row['subreddit']
    subreddit_dict[author].append(subreddit)

for key, value in subreddit_dict.items():
    subreddit_dict[key] = set(value)

subreddit_df = pd.DataFrame.from_dict(subreddit_dict, 
                            orient = 'index')

【问题讨论】:

您能否提供一个示例 DF 和预期输出? 【参考方案1】:

这里有两种策略可以做到这一点。毫无疑问,还有其他方法。

假设您的数据框看起来像这样某种东西(显然有更多列):

df = pd.DataFrame('author':['a', 'a', 'b'], 'subreddit':['sr1', 'sr2', 'sr2'])

>>> df
  author subreddit
0      a       sr1
1      a       sr2
2      b       sr2
...

解决方案 1:分组

比解决方案 2 更简单,与您的第一次尝试类似:

group = df.groupby('author')

df2 = group.apply(lambda x: x['subreddit'].unique())

# Alternatively, same thing as a one liner:
# df2 = df.groupby('author').apply(lambda x: x['subreddit'].unique())

结果:

>>> df2
author
a    [sr1, sr2]
b         [sr2]

作者是索引,单列是所有子reddits的列表它们是活跃的(根据你的描述,这就是我如何解释你想要你的输出的方式)。

如果您希望将每个子版块放在单独的列中,这可能更有用,具体取决于您想用它做什么,您可以在之后执行此操作:

df2 = df2.apply(pd.Series)

结果:

>>> df2
          0    1
author          
a       sr1  sr2
b       sr2  NaN

解决方案 2:遍历数据框

您可以创建一个包含所有唯一作者的新数据框:

df2 = pd.DataFrame('author':df.author.unique())

然后只需获取他们处于活动状态的所有唯一子版块的列表,并将其分配给一个新列:

df2['subreddits'] = [list(set(df['subreddit'].loc[df['author'] == x['author']])) 
    for _, x in df2.iterrows()]

这给了你这个:

>>> df2
  author  subreddits
0      a  [sr2, sr1]
1      b       [sr2]

【讨论】:

在内部,这一行发生了什么:df2 = group.apply(lambda x: x['subreddit'].unique())“x”是否代表给定作者的数据框中的所有行? 这是一个匿名函数,应用于groupby 中的每个组:它获取每个组(即每个作者)的subreddit 列中的所有唯一值。 x 只是组,所以是的,本质上是给定作者的原始数据框的子集。 @sacuL 有没有办法获取subreddit 列中的所有值,而不仅仅是唯一值? @Python_newbieash, IIUC, group = df.groupby('author') df2 = group.apply(lambda x: list(x['subreddit'])) 将是一种快速而肮脏的方式 @sacuL 谢谢!这很有帮助!【参考方案2】:

通过使用sacul的样本数据

df['subreddit'].groupby(df['author']).unique().apply(pd.Series)
Out[370]: 
          0    1
author          
a       sr1  sr2
b       sr2  NaN

【讨论】:

【参考方案3】:

使用 groupby.agg() “聚合”函数:

*

DataFrameGroupBy.agg(arg, *args, **kwargs):使用一或聚合 在指定轴上进行更多操作。用于的功能 聚合数据。如果是函数,则必须在传递时工作 DataFrame 或传递给 DataFrame.apply 时

df = pd.DataFrame('numbers': [1, 2, 3, 6, 9], 'colors': ['red', 'white', 'blue', 'red', 'white'], columns=['numbers', 'colors'])


df.groupby('colors', as_index=True).agg('numbers' : "unique" : lambda x: set(x),
                                                      "nunique" : lambda x : len(set(x)))

【讨论】:

很棒的插图。你拯救了我的一天,谢谢!

以上是关于Pandas,对于一列中的每个唯一值,在另一列中获取唯一值的主要内容,如果未能解决你的问题,请参考以下文章

Pandas - 在两列中查找具有匹配值的行并在另一列中相乘

Pandas:根据字符串的一部分是不是在另一列中的任何位置创建新列

pandas 判断某一列数据是不是在另一列中

在 pandas 中创建一个条形图,x 轴为日期,另一列中的每个值一个条形图

PSQL - 查找所有值并根据另一列中的非唯一值使其唯一

MySQL - 如何根据另一列中的唯一值转置一列中的单元格?