PANDAS用dict的键值对替换非空列值

时间:2017-06-22 05:51:53

标签: pandas dictionary dataframe match

假设我有一个数据帧: DF1:

       AC BC AK BJ  SDFG.... (1100 such columns)
Tom    0  0  1   0   0
Sally  1  0  1   1   0
Nick   0  1  0   0   1

我还有一个字典:

dict_1= {'AC':0.23,'BC':1.2, 'AK':0.45, 'BJ': 2.2, 'ABFK':4.5....}

没有必要dict1中的所有键都是df1的列,键值对的总数可能是10,000,而列只有1100.所以大量的键不是像#39那样的列; ABFK' df1中没有键 类似地,可能存在不是dict_1中的键的列名。例如,SDFG'列标题在dict中没有关联的键。

我想返回一个数据框,如果密钥作为列名存在,则dict1中的值已被替换: 例如,我想要回来的是

      AC    BC   AK    BJ    SDFG.... (1100 such columns) TOTAL
Tom    0    0    0.45   0     0                             0.45
Sally  0.23 0    0.45   2.2   0                             2.7
Nick   0    1.2  0      0     0.13                          1.33                        

所以所有(1s)都被基于字典的值替换。如果密钥不像SDFG那样存在,则将其更改为默认值0.13。最后,我希望有一个总列名称,该名称在该行中求和。

PANDAS的简易解决方案是什么? 非常感谢所有帮助新手的人。

2 个答案:

答案 0 :(得分:2)

选项1
您可以使用mask隐藏其中的内容,然后使用assign进行字典解压缩来填充这些屏蔽值。

首先,创建一个新的字典,我们填写默认值

d = {c: dict_1.get(c, .13) for c in df}
df.mask(df == 1, df.assign(**d))

         AC   BC    AK   BJ  SDFG
Tom    0.00  0.0  0.45  0.0  0.00
Sally  0.23  0.0  0.45  2.2  0.00
Nick   0.00  1.2  0.00  0.0  0.13

要包含Total

d = {c: dict_1.get(c, .13) for c in df}
d1 = df.mask(df == 1, df.assign(**d))
d1 = d1.assign(Total=d1.sum(1))
d1

         AC   BC    AK   BJ  SDFG  Total
Tom    0.00  0.0  0.45  0.0  0.00   0.45
Sally  0.23  0.0  0.45  2.2  0.00   2.88
Nick   0.00  1.2  0.00  0.0  0.13   1.33

选项2
或者,我们可以使用replace我们传递一个字典来定义该特定列的替换内容。

df.replace({c: {1: dict_1.get(c, .13)} for c in df})

         AC   BC    AK   BJ  SDFG
Tom    0.00  0.0  0.45  0.0  0.00
Sally  0.23  0.0  0.45  2.2  0.00
Nick   0.00  1.2  0.00  0.0  0.13

我们可以按照与上面相同的方式继续添加Total列。

选项3
我们可以使用pd.Series创建新的reindexdf.columns,然后fillna创建.13

# thanks @jezrael for fill_value reminder
df * pd.Series(dict_1).reindex(df.columns, fill_value=.13)

         AC   BC    AK   BJ  SDFG
Tom    0.00  0.0  0.45  0.0  0.00
Sally  0.23  0.0  0.45  2.2  0.00
Nick   0.00  1.2  0.00  0.0  0.13

我们可以按照与上面相同的方式添加Total

答案 1 :(得分:1)

您可以先更新dict,然后将mask用于由fillna替换的NaN

dict_1= {'AC':0.23,'BC':1.2, 'AK':0.45, 'BJ': 2.2, 'ABFK':4.5}

dict_2 = {x: 0.13 for x in df.columns if x not in dict_1}
dict_2.update(dict_1)

df = df.mask(df == 1).fillna(df.columns.to_series().replace(dict_2))
df['TOTAL'] = df.sum(axis=1)
print (df)
         AC   BC    AK   BJ  SDFG  TOTAL
Tom    0.00  0.0  0.45  0.0  0.00   0.45
Sally  0.23  0.0  0.45  2.2  0.00   2.88
Nick   0.00  1.2  0.00  0.0  0.13   1.33