如何通过检查标志查找值

时间:2019-12-21 18:56:58

标签: pandas

数据框低于

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

3 个答案:

答案 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列(并且根据您的问题不会以任何方式使用col1col2),则只需获取第一个标志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