Pandas 错误:__setitem__() 无法将字典值识别为列名列表

Kri*_*ler 8 python dictionary dataframe pandas keyerror

编辑:看起来这是 Pandas 中的一个潜在错误。查看@NicMoetsch 提出的这个 GitHub问题,注意到使用字典值分配的意外行为与框架__setitem__()__getitem__().


在我之前的代码中,我用字典重命名了一些列:

cols_dict = {
     'Long_column_Name': 'first_column',
     'Other_Long_Column_Name': 'second_column',
     'AnotherLongColName': 'third_column'
}
for key, val in cols_dict.items():
    df.rename(columns={key: val}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

(我知道这里不需要循环——在我的实际代码中,我必须在数据帧列表中搜索数据帧的列,并获得字典键的子字符串匹配。)

后来我做了一些清理applymap(),索引字典值,它工作正常

pibs[cols_dict.values()].applymap(
    lambda x: np.nan if ':' in str(x) else x
)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将切片分配回自身时,我收到一个关键错误(此处为完整错误消息)。

pibs[cols_dict.values()] = pibs[cols_dict.values()].applymap(
    lambda x: np.nan if ':' in str(x) else x
)
Run Code Online (Sandbox Code Playgroud)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/.local/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   3079             try:
-> 3080                 return self._engine.get_loc(casted_key)
   3081             except KeyError as err:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: dict_values(['first_column', 'second_column', 'third_column'])
Run Code Online (Sandbox Code Playgroud)

如果我将字典值转换为列表,代码运行良好

pibs[list(cols_dict.values())] = ...
Run Code Online (Sandbox Code Playgroud)

所以我想我只是想知道为什么我能够使用字典值进行切片并applymap()在其上运行,但是当我转身并尝试将结果分配回数据帧时,我无法使用字典值进行切片。

简单地说:为什么 Pandascols_dict.values()在用于索引时会识别为列名列表,而在用于索引分配时则不会?

ane*_*oid 1

不是直接回答你的问题为什么你能够通过dict.values()切片获取记录但不能用它设置 - 但是,它可能与索引有关:因为如果我使用loc,它工作得很好。

让我们来设置一下:

cols_dict = {
     'Long_column_Name': 'first_column',
     'Other_Long_Column_Name': 'second_column',
     'AnotherLongColName': 'third_column'
}

df = pd.DataFrame({'Long_column_Name': range(3),
                   'Other_Long_Column_Name': range(3, 6),
                   'AnotherLongColName': range(15, 10, -2),
})
df.rename(columns=cols_dict, inplace=True)
df
   first_column  second_column  third_column
0             0              3            15
1             1              4            13
2             2              5            11
Run Code Online (Sandbox Code Playgroud)

applymap使用方法:

df[cols_dict.values()].applymap(lambda x: -1 if x % 2 == 0 else x ** 2)
   first_column  second_column  third_column
0            -1              9           225
1             1             -1           169
2            -1             25           121
Run Code Online (Sandbox Code Playgroud)

此行抛出您得到的错误:

df[cols_dict.values()] = df[cols_dict.values()].applymap(lambda x: -1 if x % 2 == 0 else x ** 2)
# error thrown
Run Code Online (Sandbox Code Playgroud)

但这是有效的df.loc

df.loc[:, cols_dict.values()] = df[cols_dict.values()].applymap(lambda x: -1 if x % 2 == 0 else x ** 2)
df
   first_column  second_column  third_column
0            -1              9           225
1             1             -1           169
2            -1             25           121
Run Code Online (Sandbox Code Playgroud)

编辑,一些可能是错误的部分推论:顺便说一句,较长的错误显示了可能发生的其他情况:

KeyError: dict_values(['first_column', 'second_column', 'third_column'])

During handling of the above exception, another exception occurred:
# later:
ValueError: Wrong number of items passed 3, placement implies 1
Run Code Online (Sandbox Code Playgroud)

...它已经经历了 的一部分insertmake_block这让我认为它试图创建列并在那里失败了。该部分是为 setitem 调用的,但不是为 getitem 调用的 - 因此发生的查找没有相同的结果。相反,我本来期望出现“带有复制的设置”错误。