pandas Series.replace() 未从 defaultdict 生成默认值

pandas Series.replace() not generating default value from defaultdict

之后我总是可以.fillna()。但我正在尝试将“其他”的值作为重新编码字典的一部分。我认为 defaultdict 可能很合适,但它似乎表现得像一个生成器,并且 pandas Series.replace() 似乎不会为代码中前面未请求的键生成结果。

示例代码:

import pandas as pd
from collections import defaultdict

recode = defaultdict(lambda:"Unknown", {
    1 : "Yes",
    2 : "No"
})

print("key 0:", recode[0]) # Will generate a key-value for the key "0"

df = pd.DataFrame(pd.Series([0,1,2,5]), columns = ["code"])
df['answer'] = df['code'].replace(recode)
print(df)

将生成此输出:

key 0: Unknown
   code   answer
0     0  Unknown
1     1      Yes
2     2       No
3     5        5

因此,由于我们在 recode[0] 上调用了 print(),因此它会生成,并且可以由 pd.Series.replace() 使用,但 recode[5] 仅由 pd.[= 搜索35=]() 因此没有像我预期的那样被“未知”取代。

建议? (关于如何在重新编码数据结构中包含“OTHER”)

已接受答案

基于 Anurag Dabas 的回答,您可以只使用地图...

recode = defaultdict(lambda:"Unknown", {
    1 : "Yes",
    2 : "No",
    None: "Ah shit"
})
df['answer'] = df['code'].map(recode)

输出:

    code    answer
0   0   Unknown
1   1   Yes
2   2   No
3   5   Unknown

当你这样做时:

print("key 0:", recode[0])

由于记录中不存在键 0,因此它会生成一个值为 'Unknown' 的键 0,因为您在 defaultdict

中创建键 0 时未分配任何值

所以现在重新编码变成:

print(record)
defaultdict(<function __main__.<lambda>()>, {1: 'Yes', 2: 'No', 0: 'Unknown'})

所以现在如果你这样做:

df['answer'] = df['code'].replace(recode)

0 被替换为 'Unknown' 因为 defaultdict 重新编码中存在 0 值,即 'Unknown' 并且默认字典中不存在 5 值,因此它保持不变,您可以通过以下方式检查:

print('keys: ',recode.keys(),'\nvalues: ',recode.values())

keys:  dict_keys([1, 2, 0]) 
values:  dict_values(['Yes', 'No', 'Unknown'])

更新:

你可以使用简单的字典或 defaultdict map()+fillna():

df['answer'] = df['code'].map({1:'Yes',2:'No'}).fillna('Other')

df的输出:

    code    answer
0   0       Other
1   1       Yes
2   2       No
3   5       Other

好像是 pandas.core _replace_columnwise checks if the keys are in the mapping before replacing.

所以在上面的示例代码运行之后,您可以通过逻辑检查哪些将被替换或不被替换。

print(0 in recode)
print(5 in recode)

输出:

True
False

所以我想这是要问 pandas 开发人员,他们是否可以在替换函数中支持类似 dict 的生成器?