Pandas透视到列值的有限列表

baubqpgj  于 2023-03-06  发布在  其他
关注(0)|答案(1)|浏览(113)

我有一个Pandas数据框
| 类型|姓名|
| - ------|- ------|
| 奶酪|莫萨雷拉|
| 奶酪|切达干酪|
| 奶酪|胡椒杰克|
| 面包|酸面团|
| 面包|黑麦|
| 胡椒|绿色|
我尝试按Type列分组,收集名称列表并将其拆分为最多2列,因此输出为:
| 类型|姓名_主要|名称_备选方案|
| - ------|- ------|- ------|
| 奶酪|莫萨雷拉|切达干酪|
| 面包|酸面团|黑麦|
| 胡椒|绿色||

  • 如果类型具有两个以上的名称,请为Name_primary和Name_alternative填充前两个名称
  • 如果类型只有一个名称,则Name_alternative将为空
  • 假设:第一个表没有重复项,并且已经以某种方式排序。

我已经到了收集列表df.groupby("Type").Name.apply(list).to_frame()df.pivot_table(index="Type", values="Name", aggfunc=list)的地步
我可以在一个用户函数上做一个lambda apply来检查长度,得到(val 1,val 2)或(val 1,None),然后创建Name_Primary和Name_Alternative列,但是有没有更简单的方法来做呢?

piwo6bdm

piwo6bdm1#

让我们按类型对 Dataframe 进行分组,并创建与解析中的前两个名称相对应的记录

c = ['Name_primary', 'Name_alternative']
df1 = pd.DataFrame({'Type': k, **dict(zip(c, g['Name']))} 
                   for k, g in df.groupby('type', sort=False))

或者,您可以在选择每种类型的前两行后使用透视重新调整 Dataframe

# create seq counter to identify unique rows per type
df['idx'] = df.groupby('type').cumcount()

# Filter rows where counter < 2 and pivot to reshape
df1 = df.query('idx < 2').pivot(index='type', columns='idx', values='Name')
df1.columns = ['Name_primary', 'Name_alternative']

结果

Type Name_primary Name_alternative
0  Cheese    Mozarella          Cheddar
1   Bread    Sourdough              Rye
2  Pepper        Green              NaN

相关问题