pandas:映射到新列,不包括某些代码

时间:2017-04-13 14:47:23

标签: python pandas

我有一个键和值的字典。我想在数据框列中“映射”数字,其中原始列是键,新列是值。

但是,字典中包含的的任何值都应编码为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以外的任何代码时,这是令人沮丧的。

3 个答案:

答案 0 :(得分:2)

使用mapdict.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。在这种情况下,它并不重要,因为列的dtypeobject

但是,如果是intmap会在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!