您好我正在使用pandas / python,并且在以下行中有一个数据框:
21627 red
21627 green
21627 red
21627 blue
21627 purple
21628 yellow
21628 red
21628 green
21629 red
21629 red
我想减少到:
21627 red, green, blue, purple
21628 yellow, red, green
21629 red
这样做的最佳方式是什么(并将列表中的所有值折叠为唯一值)?
另外,如果我想保留冗余:
21627 red, green, red, blue, purple
21628 yellow, red, green
21629 red, red
实现这一目标的最佳方式是什么?
提前感谢您的帮助。
答案 0 :(得分:7)
如果真的想要这样做,你可以使用groupby apply:
In [11]: df.groupby('id').apply(lambda x: list(set(x['colours'])))
Out[11]:
id
21627 [blue, purple, green, red]
21628 [green, red, yellow]
21629 [red]
dtype: object
In [12]: df.groupby('id').apply(lambda x: list(x['colours']))
Out[12]:
id
21627 [red, green, red, blue, purple]
21628 [yellow, red, green]
21629 [red, red]
dtype: object
但是,包含列表的DataFrames效率不高。
Pivot table为您提供更实用的DataFrame:
In [21]: df.pivot_table(rows='id', cols='colours', aggfunc=len, fill_value=0)
Out[21]:
colours blue green purple red yellow
id
21627 1 1 1 2 0
21628 0 1 0 1 1
21629 0 0 0 2 0
我最喜欢的功能get_dummies
可以让你这样做,但不是那么优雅或有效(但我保留这个原创,如果是疯狂的,建议):
In [22]: pd.get_dummies(df.set_index('id')['colours']).reset_index().groupby('id').sum()
Out[22]:
blue green purple red yellow
id
21627 1 1 1 2 0
21628 0 1 0 1 1
21629 0 0 0 2 0
答案 1 :(得分:2)
这是另一种方式;通过@Andy更直观一些
In [24]: df.groupby('id').apply(
lambda x: x['color'].value_counts()).unstack().fillna(0)
Out[24]:
blue green purple red yellow
id
21627 1 1 1 2 0
21628 0 1 0 1 1
21629 0 0 0 2 0