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 的生成器?
之后我总是可以.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 的生成器?