【问题标题】:Pivot dataframe without lose repeated values在不丢失重复值的情况下旋转数据框
【发布时间】:2022-10-23 14:05:26
【问题描述】:

我有这个条目

id   value  reps
1    333    1
1    332    4
1    335    1   
4    555    3
4    225    1
444  2      5

我想要这个,按列代表从少到多组织值

id   col1 col2 col3 col4 
1    333  335  332  nan 
4    225  555  nan  nan 
444  2    nan  nan  nan

我尝试使用数据透视表并得到了这个

dataframe = dataframe.pivot_table(index='id', columns='reps', values='value')
dataframe = dataframe.rename_axis(columns=None).reset_index()

id   1      3      4    5
1    334    nan    332  nan
4    225.5  555.5  nan  nan
444  nan    nan    nan  2

【问题讨论】:

  • 你有任何理由相信这对 (id, reps) 在每一行都会不同吗?

标签: python pandas dataframe group-by dataset


【解决方案1】:

您可以先按reps 对数据帧进行排序(如果是这种情况,也可以按id),然后将reps 更改为每个id 的累积计数。

然后您可以按照您的建议执行数据透视表。

df 
  .sort_values(['id','reps']) 
  .pipe(lambda df_: df_.assign(reps=df_.groupby(['id']).cumcount()+1)) 
  .pivot_table(index='id', columns='reps', values='value') 
  .add_prefix('col')

它不会在您的预期输出中返回带有NaN 的col4,但您可以稍后添加它。

【讨论】:

  • 正确的方法,你不需要pipe,你可以在assign.assign(reps=lambda d: d.groupby('id').cumcount().add(1)))中使用可调用的。
【解决方案2】:

按 "id" 分组并创建 ("value", "reps") 元组,并按 "reps" 排序:

df_grouped = df.groupby("id")[["value", "reps"]].apply(lambda x: sorted(list(zip(x.value, x.reps)), key=lambda x: x[1]))

[Out]:
id
1      [(333, 1), (335, 1), (332, 4)]
4                [(225, 1), (555, 3)]
444                          [(2, 5)]

使用“值”作为数据(位于索引0)从上面排序的元组创建结果数据框。

df_result = pd.DataFrame(data=[[y[0] for y in x] for x in df_grouped], index=df_grouped.index)

[Out]:
       0      1      2
id                    
1    333    335    332
4    225    555    NaN
444    2    NaN    NaN

pandas 填写以0 开头的默认列名。如果需要,您可以更改它:

df_result.columns = list(range(1, len(df_result.columns) + 1))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-15
    • 2021-05-28
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多