英文:
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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论