【问题标题】:Combine values from multiple columns into a list in each row using python使用python将来自多列的值组合到每行的列表中
【发布时间】:2021-09-02 21:20:32
【问题描述】:

我有以下数据框。

data = [[0, 0, 0, 0, 1], [0, 1, 0, 0, 1], [1, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
labels = ['cat', 'dog', 'duck', 'fish', 'horse']
df = pd.DataFrame(data, columns = labels)
df: 
    cat dog duck fish horse
0    0   0   0    0    1
1    0   1   0    0    1
2    1   1   0    0    0
3    0   1   0    0    0

我根据特定条件从另一个数据帧中获得了 0 和 1。 我想为对应于真值的值组合列名。即 1 放入列表中,并将其放入数据框末尾的新列中。

我希望我的结果看起来像这样。

   cat  dog  duck  fish horse   result
0   0    0    0     0    1     [horse]
1   0    1    0     0    1     [dog, horse]
2   1    1    0     0    0     [cat, dog]
3   0    1    0     0    0     [dog] 

我的原始数据框中有大约 108 列和大约 3500 行。 最好的方法是什么?

PS:我还没有成功找到方法。

谢谢

【问题讨论】:

    标签: python pandas list dataframe numpy


    【解决方案1】:

    如果1 在每行的值中过滤列名称:

    c = df.columns.to_numpy()
    df['result'] = df.apply(lambda x: list(c[x == 1]), axis=1)
    

    替代方案更快:

    c = df.columns.to_numpy()
    df['result'] = [c[x == 1] for x in df.to_numpy()]
    

    print (df)
       cat  dog  duck  fish  horse        result
    0    0    0     0     0      1       [horse]
    1    0    1     0     0      1  [dog, horse]
    2    1    1     0     0      0    [cat, dog]
    3    0    1     0     0      0         [dog]
    

    #[4000 rows x 100 columns]
    df = pd.concat([df] * 1000, ignore_index=True)
    df = pd.concat([df] * 20, ignore_index=True, axis=1).add_prefix('test')
        
    
    In [38]: %%timeit
        ...: c = df.columns.to_numpy()
        ...: df.apply(lambda x: list(c[x == 1]), axis=1)
        ...: 
        ...: 
    526 ms ± 33.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    
    In [62]: %%timeit
        ...: c = df.columns.to_numpy()
        ...: [c[x == 1] for x in df.to_numpy()]
        ...: 
        ...: 
    12.1 ms ± 1.6 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    其他解决方案:

    In [58]: %%timeit
        ...: df.dot(df.columns + ',').str.strip(',').str.split(',')
        ...: 
    50.7 ms ± 5.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [63]: %%timeit
        ...: df.mask(df.eq(0)).stack().reset_index(-1).groupby(level=0).agg({'level_1' : list }).values
        ...: 
        ...: 
    162 ms ± 6.54 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • dot 解决方案在没有timeit 的情况下也可以工作。也许是因为df['result'] = 因为它会添加new column 不太确定。如果你有什么想法,你能告诉我确切的原因吗​​?
    【解决方案2】:

    你可以试试:

    df['result'] = df.dot(df.columns + ',').str.strip(',').str.split(',')
    

    替代方案:

    df['result'] = df.mask(df.eq(0)).stack().reset_index(-1).groupby(level=0).agg({'level_1' : list }).values
    

    输出:

       cat  dog  duck  fish  horse        result
    0    0    0     0     0      1       [horse]
    1    0    1     0     0      1  [dog, horse]
    2    1    1     0     0      0    [cat, dog]
    3    0    1     0     0      0         [dog]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 2018-05-09
      相关资源
      最近更新 更多