数据框低于
uid,col1,col2,flag
1001,a,b,{'a':True,'b':False}
1002,a,b,{'a':False,'b':True}
出
a
b
通过检查标志,如果a为true
,则在a
列上打印out
,如果b
标志为true
,则打印{{1 }}在b
列
答案 0 :(得分:4)
IIUC,您可以在dot
构造函数之后使用DataFrame
:
m=pd.DataFrame(df['flag'].tolist()).fillna(False)
final=df.assign(New=m.dot(m.columns))
print(final)
uid col1 col2 flag New
0 1001 a b {'a': True} a
1 1002 a b {'b': True} b
答案 1 :(得分:3)
如果您只想评估flags
列(并且根据您的问题不会以任何方式使用col1
和col2
),则只需获取第一个标志dict中的键,其中值是True
:
df.flag.apply(lambda x: next((k for k,v in x.items() if v), ''))
(对于dict中没有一个值是''
的情况,您当然可以提供True
的其他值)
示例:
import pandas as pd
import io
import ast
s = '''uid,col1,col2,flag
1001,a,b,"{'a':True,'b':False}"
1002,a,b,"{'a':False,'b':True}"
1003,a,b,"{'a':True,'b':True}"
1004,a,b,"{'a':False,'b':False}"'''
df = pd.read_csv(io.StringIO(s))
df.flag = df.flag.map(ast.literal_eval)
df['out'] = df.flag.apply(lambda x: next((k for k,v in x.items() if v), ''))
结果
uid col1 col2 flag out
0 1001 a b {'a': True, 'b': False} a
1 1002 a b {'a': False, 'b': True} b
2 1003 a b {'a': True, 'b': True} a
3 1004 a b {'a': False, 'b': False}
答案 2 :(得分:2)
方法1
我们也可以使用Series.apply
将该字典转换为序列,然后使用boolean indexing
+ DataFrame.stack
删除伪造的字典,并使用Index.get_level_values
从索引中选择a或b:
s = df['flag'].apply(pd.Series)
df['new']=s[s].stack().index.get_level_values(1)
#df['new']=np.dot(s,s.columns) #or this
print(df)
方法2:
我们还可以使用Series.apply
检查项目,如果值是True,则将密钥保存在列表中。
最后,如果我们要删除列表,则使用Series.explode
。
df['new']=df['flag'].apply(lambda x: [k for k,v in x.items() if v])
df = df.explode('new')
print(df)
或没有apply
:
df=df.assign(new=[[k for k,v in d.items() if v] for d in df['flag']]).explode('new')
print(df)
输出
uid col1 col2 flag new
0 1001 a b {'a': True, 'b': False} a
1 1002 a b {'a': False, 'b': True} b