我有一个键和值的字典。我想在数据框列中“映射”数字,其中原始列是键,新列是值。
但是,字典中包含的不的任何值都应编码为999.
原始数据框:
Col1
0 02
1 03
2 02
3 02
4 04
5 88
6 77
字典:
codes = {'01':'05',
'02':'06',
'03':'07',
'04':'08'}
预期产出:
>>> df['ColNew'] = df['Col1'].map(codes)
ColNew
0 06
1 07
2 06
3 06
4 08
5 999
6 999
我不知道如何做到这一点,除了首先在字典中包含999代码。当涉及超过一百个代码并且只有少数代码需要999以外的任何代码时,这是令人沮丧的。
答案 0 :(得分:2)
使用map
和dict.get
dict.get
允许您在key
不存在的情况下传递默认值。
df['ColNew'] = df['Col1'].map(lambda x: codes.get(x, 999))
df
Col1 ColNew
0 02 06
1 03 07
2 02 06
3 02 06
4 04 08
5 88 999
6 77 999
这也将保留dtypes
。在这种情况下,它并不重要,因为列的dtype
为object
。
但是,如果是int
,map
会在float
回来时将其变为NaN
。通过使用默认值,我们可以避免类型转换。
答案 1 :(得分:1)
注意:由于类型转换,这是对piRSquared的一个较差的答案:
之后您可以简单地填写NaN。
df['ColNew'] = df.Col1.map(codes).fillna('999')
结果:
ColNew
0 06
1 07
2 06
3 06
4 05
5 999
6 999
有一件有趣的事情是,Series.map
的na_action
参数不是用作默认的映射参数,因为我最初想要思考。
其目的实际上是控制NaN值是否受映射函数的影响 - 如果您没有以任何方式映射它们,您可以通过设置na_action='ignore'
来看到潜在的性能提升。
答案 2 :(得分:0)
Just another way to skin this cat:
new_codes = {k: codes[k] if k in codes else '999' for k in set(df['Col1'])}
df['ColNew'] = df['Col1'].map(new_codes)
df
Out[126]:
Col1 ColNew
0 02 06
1 03 07
2 02 06
3 02 06
4 04 08
5 88 999
6 77 999
Some timings:
%timeit df['Col1'].map({k: codes[k] if k in codes else '999' for k in set(df['Col1'])})
1000 loops, best of 3: 373 µs per loop
%timeit df['Col1'].map(lambda x: codes.get(x, 999))
10000 loops, best of 3: 133 µs per loop
%timeit df.Col1.map(codes).fillna('999')
The slowest run took 92.77 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 575 µs per loop
Looks like piRSquared's answer is about 64% faster than mine!