【问题标题】:Make pandas df in wide format and unconcatenate values to different columns以宽格式制作 pandas df 并将值取消连接到不同的列
【发布时间】:2020-01-22 17:47:30
【问题描述】:

抱歉,我在标题中解释问题时有点麻烦

我们偶然将 Pandas 数据框转为以下内容:

df = pd.DataFrame(np.array([[1,1,2], [1,2,1], [2,1,2], [2,2,2],[3,1,3]]),columns=['id', '3s', 'score'])

id   3s  score
1    1   2
1    2   1
2    1   2             
2    2   2                 
3    1   3

但是我们需要取消堆叠,所以 df 看起来像这样(原始版本):“3s”列“unpivots”到由 3 个具有 0 和 1 的有序列按顺序相加的离散集。因此,如果我们有'3s'= 2'score'= 2,则对应的id['4','5','6'](第二组3s)中的值将是[1,1,0](3 个中的2 个)

df2 = pd.DataFrame(np.array([[1,1,1,0,1,0,0], [2,1,1,0,1,1,0], [3,1,1,1,np.nan,np.nan,np.nan] ]),columns=['id', '1', '2','3','4','5','6'])

id   1   2   3   4   5   6
1    1   1   0   1   0   0
2    1   1   0   1   1   0      
3    1   1   1 

非常感谢任何帮助! (请救救我)

【问题讨论】:

    标签: python pandas pivot unpivot


    【解决方案1】:

    用途:

    n = 3
    df2 = df.reindex(index = df.index.repeat(n))
    new_df = (df2.assign(score = df2['score'].gt(df2.groupby(['id','3s'])
                                                    .id
                                                    .cumcount())
                                             .astype(int),
                         columns = df2.groupby('id').cumcount().add(1))
                 .pivot_table(index = 'id',
                              values='score',
                              columns = 'columns',
                              fill_value = '')
                 .rename_axis(columns = None)
                 .reset_index())
    print(new_df)
    

    输出

       id    1    2    3  4  5  6
    0   1  1.0  1.0  0.0  1  0  0
    1   2  1.0  1.0  0.0  1  1  0
    2   3  1.0  1.0  1.0         
    

    如果您愿意,可以使用 fill_value = 0

       id  1  2  3  4  5  6
    0   1  1  1  0  1  0  0
    1   2  1  1  0  1  1  0
    2   3  1  1  1  0  0  0
    

    【讨论】:

    • 谢谢!快如闪电,但不知何故我得到了 400 列 :)
    【解决方案2】:

    这应该可以解决问题:

    for gr in df.groupby('3s').groups:
        for i in range(1,4):
            df[str(i+(gr-1)*3)]=np.where((df['3s'].eq(gr))&(df['score'].ge(i)), 1,0)
    df=df.drop(['3s', 'score'], axis=1).groupby('id').max().reset_index()
    

    输出:

       id  1  2  3  4  5  6
    0   1  1  1  0  1  0  0
    1   2  1  1  0  1  1  0
    2   3  1  1  1  0  0  0
    

    【讨论】:

    • 谢谢,更稳定的解决方案!
    猜你喜欢
    • 2020-06-02
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2014-01-27
    相关资源
    最近更新 更多