Python pandas-选择列名并将其转换为值

Python pandas-选择列名并将其转换为值,python,pandas,dataframe,Python,Pandas,Dataframe,从这个数据帧df开始: df = pd.DataFrame({'id':[1,2,3,4],'a':['on','on','off','off'], 'b':['on','off','on','off']}) a b id 0 on on 1 1 on off 2 2 off on 3 3 off off 4 我想要实现的是一个列result,其中包含列的“开”和“关”选择的结果。预期产出为: a b id resu

从这个数据帧df开始:

df = pd.DataFrame({'id':[1,2,3,4],'a':['on','on','off','off'], 'b':['on','off','on','off']})

     a    b  id
0   on   on   1
1   on  off   2
2  off   on   3
3  off  off   4
我想要实现的是一个列
result
,其中包含列的“开”和“关”选择的结果。预期产出为:

     a    b  id result
0   on   on   1 [a,b]
1   on  off   2 [a]
2  off   on   3 [b]
3  off  off   4 []
因此,基本上我必须选择列中的“on”值(id除外),然后将生成的列名保留在列表中。我的第一次尝试是使用透视表:

d = pd.pivot_table(df, index='id', columns=?, values=?)

但是我被困在如何将选择放入
值中,并将新列放入
列中
参数中。

对于我来说,创建嵌套的
列表
s,然后通过
str[0]选择列表的第一个值。

df['res'] = df[['a','b']].eq('on').apply(lambda x: [x.index.values[x]], axis=1).str[0]
print (df)
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2     [a]
2  off   on   3     [b]
3  off  off   4      []
或者先创建元组,然后转换到
list
s:

df['res'] = df[['a','b']].eq('on')
                         .apply(lambda x: tuple(x.index.values[x]), axis=1).apply(list)
print (df)
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2     [a]
2  off   on   3     [b]
3  off  off   4      []

对于me works,创建嵌套的
列表
s,然后通过
str[0]
选择列表的第一个值:

df['res'] = df[['a','b']].eq('on').apply(lambda x: [x.index.values[x]], axis=1).str[0]
print (df)
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2     [a]
2  off   on   3     [b]
3  off  off   4      []
或者先创建元组,然后转换到
list
s:

df['res'] = df[['a','b']].eq('on')
                         .apply(lambda x: tuple(x.index.values[x]), axis=1).apply(list)
print (df)
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2     [a]
2  off   on   3     [b]
3  off  off   4      []

也可以使用透视表代替透视表

df['result'] = df.iloc[:,0:2].eq('on').apply(lambda x: tuple(df.columns[0:2][x]), axis=1)
输出:

a b id result 0 on on 1 (a, b) 1 on off 2 (a,) 2 off on 3 (b,) 3 off off 4 () b id结果 1(a,b)上的0 1开2关(a,) 3(b)上的2关 三关四关()
也可以使用透视表代替透视表

df['result'] = df.iloc[:,0:2].eq('on').apply(lambda x: tuple(df.columns[0:2][x]), axis=1)
输出:

a b id result 0 on on 1 (a, b) 1 on off 2 (a,) 2 off on 3 (b,) 3 off off 4 () b id结果 1(a,b)上的0 1开2关(a,) 3(b)上的2关 三关四关() 试试这个:

import pandas as pd
df = pd.DataFrame({'id':[1,2,3,4],'a':['on','on','off','off'], 'b':['on','off','on','off']})
stringList = []
for i in range(0,df.shape[0]):
    if df['a'][i] == 'on' and df['b'][i] == 'on':
        stringList.append('[a,b]')
    elif df['a'][i] == 'on' and df['b'][i] == 'off':
        stringList.append('[a]')
    elif df['a'][i] == 'off' and df['b'][i] == 'on':
        stringList.append('[b]')
    else:
        stringList.append('[]')
df['result'] = stringList
print df
试试这个:

import pandas as pd
df = pd.DataFrame({'id':[1,2,3,4],'a':['on','on','off','off'], 'b':['on','off','on','off']})
stringList = []
for i in range(0,df.shape[0]):
    if df['a'][i] == 'on' and df['b'][i] == 'on':
        stringList.append('[a,b]')
    elif df['a'][i] == 'on' and df['b'][i] == 'off':
        stringList.append('[a]')
    elif df['a'][i] == 'off' and df['b'][i] == 'on':
        stringList.append('[b]')
    else:
        stringList.append('[]')
df['result'] = stringList
print df

或者您可以使用
eq
mul

df['res']=(df[['a','b']].eq('on').mul(['a','b'])).values.tolist()

Out[824]: 
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2   [a, ]
2  off   on   3   [, b]
3  off  off   4    [, ]

或者您可以使用
eq
mul

df['res']=(df[['a','b']].eq('on').mul(['a','b'])).values.tolist()

Out[824]: 
     a    b  id     res
0   on   on   1  [a, b]
1   on  off   2   [a, ]
2  off   on   3   [, b]
3  off  off   4    [, ]

为什么不
(df[[a',b']]=='on')。应用(lambda x:[x[x].index],axis=1)
?为什么不
(df[[a',b']]=='on')。应用(lambda x:[x[x].index],axis=1)
?在可以矢量化解决方案时,将
用于
循环不是一个好主意。一旦你得到了一个额外的on和off列,你就必须改变很多代码。实际上,当你可以矢量化解决方案时,使用
for
循环不是一个好主意。一旦你得到一个额外的on和off列,你就必须修改很多代码。