Pandas:在 pandas 中转换并复制特定行

3

我有一个pandas数据框,格式如下(format_A):

record_id, f_1 , f_2, f_3, ... , f_n,        A,        B,        C
        1,  0.1, 0.2, 0.3, ... , 1.2,        1,        0,        1
        2,  0.3, 1.2, 0.5, ... , 2.1,        1,        0,        0
        3,  0.2, 3.2, 1.3, ... , 0.4,        1,        1,        0
        4,  1.1, 0.1, 0.7, ... , 0.5,        0,        0,        1
        5,  2.1, 0.5, 0.8, ... , 1.9,        0,        1,        1
        6,  0.5, 0.4, 0.2, ... , 0.8,        1,        1,        1
                     :
                     :

我希望将其转换为以下格式(格式B)。 基本上,如果一个record_id有多个输出,我们将复制该记录。 而权重基本上是 1 /(duplication后的总记录数)
record_id, f_1 , f_2, f_3, ... , f_n,    target   weight
        1,  0.1, 0.2, 0.3, ... , 1.2,         A     0.5
        1,  0.1, 0.2, 0.3, ... , 1.2,         C     0.5
        2,  0.3, 1.2, 0.5, ... , 2.1,         A     1.0
        3,  0.2, 3.2, 1.3, ... , 0.4,         A     0.5
        3,  0.2, 3.2, 1.3, ... , 0.4,         B     0.5
        4,  1.1, 0.1, 0.7, ... , 0.5,         C     1.0 
        5,  2.1, 0.5, 0.8, ... , 1.9,         B     0.5
        5,  2.1, 0.5, 0.8, ... , 1.9,         C     0.5
        6,  0.5, 0.4, 0.2, ... , 0.8,         A     0.333
        6,  0.5, 0.4, 0.2, ... , 0.8,         B     0.333
        6,  0.5, 0.4, 0.2, ... , 0.8,         C     0.333   
                         :
                         :

现在,我循环遍历原始数据框以检查每个记录,然后逐行将所需记录添加到新的数据框中。虽然这种方法有效,但我想知道是否有更优雅的方法?谢谢!

1个回答

2

IIUC wide_to_long

i=df.columns[
        df.columns 
          .str
          .contains('f_|record_id')
        ].tolist()

newdf=pd.wide_to_long(
        df,
        'output',
        i=i,
        j='Out',
        suffix='\w+')

newdf = (newdf
       .loc[lambda x : x['output']==1]
       .reset_index()
       .rename(columns={'output':'weight'}))

newdf.Out = 'output' + newdf.Out

newdf.weight /= (
       newdf
       .groupby('record_id')['record_id']
       .transform('count'))

newdf
Out[265]: 
    record_id  f_1  f_2  f_3  f_n       Out    weight
0           1  0.1  0.2  0.3  1.2  output_A  0.500000
1           1  0.1  0.2  0.3  1.2  output_C  0.500000
2           2  0.3  1.2  0.5  2.1  output_A  1.000000
3           3  0.2  3.2  1.3  0.4  output_A  0.500000
4           3  0.2  3.2  1.3  0.4  output_B  0.500000
5           4  1.1  0.1  0.7  0.5  output_C  1.000000
6           5  2.1  0.5  0.8  1.9  output_B  0.500000
7           5  2.1  0.5  0.8  1.9  output_C  0.500000
8           6  0.5  0.4  0.2  0.8  output_A  0.333333
9           6  0.5  0.4  0.2  0.8  output_B  0.333333
10          6  0.5  0.4  0.2  0.8  output_C  0.333333

自从您编辑了

newdf=df.set_index(df.columns[df.columns.str.contains('f_|record_id')].tolist())
newdf=newdf.stack().reset_index()

newdf=newdf.loc[lambda x : x[0]==1].rename(columns={'level_5':'target',0:'weight'})

所有其他步骤应与上述步骤相同。

谢谢!我想知道如果我的原始输出列是A、B、C而不是output_A、output_B、output_C,这种方法是否可行?(请参见上面修改后的问题)。谢谢! - Edamame
@Edamame,那你需要设置索引和堆栈,或者检查熔解状态。 - BENY
1
强烈推荐查看此链接:https://www.python.org/dev/peps/pep-0008/,这是Python的风格指南。尝试看看是否可以让你的答案更整洁一些。例如,如果我必须滚动才能阅读答案,那么它就可以改进。只是友好的建议 :) - cs95
@coldspeed 当然,我会修改它。 - BENY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接