Python 将虚拟值列合并到一列(pd.get\u虚拟反转)

Python 将虚拟值列合并到一列(pd.get\u虚拟反转),python,pandas,numpy,Python,Pandas,Numpy,我有这样一个熊猫数据框: id Apple Apricot Banana Climentine Orange Pear Pineapple 01 1 1 0 0 0 0 0 02 0 0 1 1 1 1 0 03 0

我有这样一个熊猫数据框:

id     Apple   Apricot   Banana    Climentine   Orange    Pear    Pineapple
01       1        1         0          0          0         0         0    
02       0        0         1          1          1         1         0 
03       0        0         0          0          1         0         1
如何生成这样的新数据帧

id     fruits
01     Apple, Apricot
02     Banana, Clementine, Orange, Pear
03     Orange, Pineapple
使用
过滤每个组的
1
和上次连接值:

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})

df = (df.melt('id', var_name='fruits').query('value == 1')
       .groupby('id')['fruits']
       .apply(', '.join)
       .reset_index())

print (df)

#   id                            fruits
#0   1                    Apple, Apricot
#1   2  Banana, Climentine, Orange, Pear
#2   3                 Orange, Pineapple
为了获得更好的性能,使用
进行矩阵乘法:

df = df.set_index('id')
df = df.dot(df.columns + ', ').str.rstrip(', ').reset_index(name='fruit')
print (df)
   id                             fruit
0  01                    Apple, Apricot
1  02  Banana, Climentine, Orange, Pear
2  03                 Orange, Pineapple
使用
过滤每个组的
1
和上次连接值:

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})

df = (df.melt('id', var_name='fruits').query('value == 1')
       .groupby('id')['fruits']
       .apply(', '.join)
       .reset_index())

print (df)

#   id                            fruits
#0   1                    Apple, Apricot
#1   2  Banana, Climentine, Orange, Pear
#2   3                 Orange, Pineapple
为了获得更好的性能,使用
进行矩阵乘法:

df = df.set_index('id')
df = df.dot(df.columns + ', ').str.rstrip(', ').reset_index(name='fruit')
print (df)
   id                             fruit
0  01                    Apple, Apricot
1  02  Banana, Climentine, Orange, Pear
2  03                 Orange, Pineapple

好的,我在这里搜索了一下,发现:

这里的等价物就是理解内部的
0
计算为
False

import pandas as pd

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})


df = (df.set_index('id')
       .apply(lambda row: ', '.join([col for col, b in zip(df.columns, row) if b]), 
              axis=1)
       .reset_index())
时间比较 小套(如上)

使用(
df=pd.concat([df]*1000)
)模拟较大的集合:

36.9 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.dot
39.8 ms ± 369 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.melt
84.5 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # list comprehension

好的,我在这里搜索了一下,发现:

这里的等价物就是理解内部的
0
计算为
False

import pandas as pd

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})


df = (df.set_index('id')
       .apply(lambda row: ', '.join([col for col, b in zip(df.columns, row) if b]), 
              axis=1)
       .reset_index())
时间比较 小套(如上)

使用(
df=pd.concat([df]*1000)
)模拟较大的集合:

36.9 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.dot
39.8 ms ± 369 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.melt
84.5 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # list comprehension


我感谢你的帮助。如果我有第二个数据帧,有可能得到第一个吗?谢谢。我更新了我的问题。我知道你不接受答案,你能检查一下它是如何工作的吗?谢谢你的提示,我会做的。我是stackoverflow的新手,很高兴能得到这么多的帮助。不客气!天气真好!我感谢你的帮助。如果我有第二个数据帧,有可能得到第一个吗?谢谢。我更新了我的问题。我知道你不接受答案,你能检查一下它是如何工作的吗?谢谢你的提示,我会做的。我是stackoverflow的新手,很高兴能得到这么多的帮助。不客气!天气真好!你能为计时添加新的解决方案吗?@jezrael ofc second@jezrael点版是“最好的”。但我认为熔化版是最容易理解的understand@jezrael大概但它真的很聪明:)抱歉,但只能向上投票一次。你能为计时添加新的解决方案吗?@jezrael of c second@jezrael点版是“最好的”。但我认为熔化版是最容易理解的understand@jezrael大概但它真的很聪明:)对不起,但只能投票一次。