首页 > 解决方案 > 使用嵌套字典作为数据帧的查找表时返回错误

问题描述

我有一个嵌套字典,用作查找表以将值分配给数据框字段。代码运行时返回如下错误:

TypeError: ("'Series' 对象是可变的,因此它们不能被散列", '发生在索引 0')

我尝试使用 get() 函数,但收到相同的错误消息。

词典:

AdjFact= {
        'Good':
            {0: 0, 2010: 2.566, 2011: 1.77, 2012: 0.9658515212},
        'Bad':
            {0: 0, 2010: 3.222, 2011: 1.0423, 2012: 0.3534},
        'Avg':
            {0: 0, 2010: 1.30, 2011: 4.2, 2012: 1.01}
            }

在字典中查找值的代码使用硬编码值作为第一个字典值,使用数据帧结构中的值作为第二个字典值。它将从嵌套字典中检索到的值(使用数据框中行中的年份值)保存到数据框的行中,作为一个名为 AdjustedResult 的变量。

def lookup(row,lval):


    df= df_dict[[row['A'],row['B']]

    df['AdjustedResult'] = AdjFact[lval][df['Year']]


    . . . . . . . (more code deleted)
    return Total, Diff

newdf[['TotalGood' , 'DiffGood']] = newdf.apply(lookup, lval='Good', axis=1).apply(pd.Series)
newdf[['TotalBad' , 'DiffBad']] = newdf.apply(lookup, lval='Bad', axis=1).apply(pd.Series)
newdf[['TotalAvg' , 'DiffAvg']] = newdf.apply(lookup, lval='Avg', axis=1).apply(pd.Series)


如果可以使用不同的查找表(数据框等),我不必特别使用 AdjFact 字典。

编辑:在下面添加代码 - 仅用于测试目的

我在下面的许多值和虚拟数据帧中进行了硬编码,以便可以测试代码的逻辑(即查找函数)

import pandas as pd

new_df = pd.DataFrame({"RowNum": [1,2,3,4,5,6],"A": ['Test1','Test2','Test2','Test1','Test1','Test2'],
                       "B":['D','D','MO','D','D','D'],"Year": [2020,2008,2010,2008,2010,2011]})

df_dict_temp = {('Test1','D'): pd.DataFrame({"Col1":[3,2,4,5,2], "Year":[0,0,2010,2010,2011]}),
            ('Test2','D'):pd.DataFrame(),
            ('Test2','MO'):pd.DataFrame({"Col1":[3,2,4,5,2], "Year":[0,0,2010,2010,2011]})
            }

AdjFact= {
        'Good':
            {0: 0, 2010: 2.566, 2011: 1.77, 2012: 0.9658515212},
        'Bad':
            {0: 0, 2010: 3.222, 2011: 1.0423, 2012: 0.3534},
        'Avg':
            {0: 0, 2010: 1.30, 2011: 4.2, 2012: 1.01}
            }


def lookup(row,lval):


    m_df= df_dict_temp[row['A'],row['B']]

    m_df['AdjustedResult'] = AdjFact[lval][m_df['Year']]

    Total = 0
    #df['Discount'].sum()

    Diff = 0
    #df['Value'] - df['Discount']
    return Total, Diff

new_df[['TotalGood' , 'DiffGood']] = new_df.apply(lookup, lval='Good', axis=1).apply(pd.Series)

标签: pythonpandasdictionary

解决方案


df['Year']是一个系列(它不能被散列,因此你不能在字典中查找它)。我怀疑你的意思是row['Year'],那一排的年份?

那是,

df['AdjustedResult'] = AdjFact[lval][df['Year']]

应该读:

df['AdjustedResult'] = AdjFact[lval][row['Year']]

--

更新:对于您的最新示例,您似乎想要查找每一行的值(我在第一个示例中错过了):

ipdb> m_df['Year'].map(AdjFact[lval])
0    0.000
1    0.000
2    2.566
3    2.566
4    1.770
Name: Year, dtype: float64

所以你应该使用:

m_df['AdjustedResult'] = m_df['Year'].map(AdjFact[lval])

推荐阅读