Pandas的groupby从多个列创建数值列表

huangapple go评论49阅读模式
英文:

Pandas groupby create a list of values from several columns

问题

我有一个数据框

    df = ID  C1  C2  C3  C4
         1   a   b   r    q
         1   b   e   g    h
         2   p   a   z    p
         1   r   a   n    m

我想要按ID获取C1和C2中的数值列表
所以我会得到

    out = ID  l 
          1  [a,b,r,e]
          2  

最好的方法是什么

英文:

I have a dataframe

df = ID  C1  C2  C3  C4
     1   a   b   r    q
     1   b   e   g    h
     2   p   a   z    p
     1   r   a   n    m

I want to get list of values in C1, C2 per ID.
So I will have:

out = ID  l 
      1  [a,b,r,e]
      2  

What is the best way to do so?

答案1

得分: 2

你可以将数据框展平,然后按ID分组,最后获取唯一的数值:

df.melt('ID', value_name='l').groupby('ID', as_index=False)['l'].unique()

   ID             l
0   1  [a, b, r, e]
1   2        

更新

如果你想要为C1和C2各有一个单独的列:

(df.melt('ID', var_name='col', value_name='l')
   .groupby(['ID', 'col'], as_index=False)['l']
   .apply(lambda x: np.unique(x).tolist())
   .pivot(index='ID', columns='col', values='l')
   .rename_axis(columns=None).reset_index())

   ID         C1         C2
0   1  [a, b, r]  [b, e, a]
1   2        

[a]

英文:

You can flatten your dataframe then group by ID and finally get unique values:

>>> df.melt('ID', value_name='l').groupby('ID', as_index=False)['l'].unique()

   ID             l
0   1  [a, b, r, e]
1   2        

Update

> And if I want a seperate column for C1 and C2

>>> (df.melt('ID', var_name='col', value_name='l')
       .groupby(['ID', 'col'], as_index=False)['l']
       .apply(lambda x: np.unique(x).tolist())
       .pivot(index='ID', columns='col', values='l')
       .rename_axis(columns=None).reset_index())

   ID         C1         C2
0   1  [a, b, r]  [b, e, a]
1   2        

[a]

答案2

得分: 0

使用lambda函数与numpy.unique - 输出已排序:

df1 = (df.groupby('ID')[['C1','C2']].apply(lambda x: np.unique(x).tolist())
        .reset_index(name='l'))
print (df1)
   ID             l
0   1  [a, b, e, r]
1   2        [a, p]

或者使用unique - 输出与原始顺序一致:

df1 = (df.groupby('ID')[['C1','C2']].apply(lambda x: pd.unique(np.ravel(x)).tolist())
        .reset_index(name='l'))
print (df1)
   ID             l
0   1  [a, b, e, r]
1   2        

另一种方法是删除缺失值和重复项:

df1 = (df.melt(id_vars='ID', value_vars=['C1','C2'], value_name='l')
         .drop_duplicates(['ID','l'])
         .dropna(subset=['l'])
         .groupby('ID')['l']
         .agg(list)
         .reset_index())
print (df1)
   ID             l
0   1  [a, b, r, e]
1   2        

编辑: 要分别处理列,请使用GroupBy.agg:

df2 = df.groupby('ID')[['C1','C2']].agg(lambda x: np.unique(x).tolist()).reset_index()
print (df2)
   ID         C1         C2
0   1  [a, b, r]  [a, b, e]
1   2        

[a]

英文:

Use lambda function with numpy.unique - output is sorted:

df1 = (df.groupby('ID')[['C1','C2']].apply(lambda x: np.unique(x).tolist())
        .reset_index(name='l'))
print (df1)
   ID             l
0   1  [a, b, e, r]
1   2        [a, p]

Or with unique - output is with original order:

df1 = (df.groupby('ID')[['C1','C2']].apply(lambda x: pd.unique(np.ravel(x)).tolist())
        .reset_index(name='l'))
print (df1)
   ID             l
0   1  [a, b, e, r]
1   2        

Another idea with remove missing values and duplicates:

df1 = (df.melt(id_vars='ID', value_vars=['C1','C2'], value_name='l')
         .drop_duplicates(['ID','l'])
         .dropna(subset=['l'])
         .groupby('ID')['l']
         .agg(list)
         .reset_index())
print (df1)
   ID             l
0   1  [a, b, r, e]
1   2        

EDIT: For separate columns use GroupBy.agg:

df2 = df.groupby('ID')[['C1','C2']].agg(lambda x: np.unique(x).tolist()).reset_index()
print (df2)
   ID         C1         C2
0   1  [a, b, r]  [a, b, e]
1   2        

[a]

huangapple
  • 本文由 发表于 2023年2月14日 20:42:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447996.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定