pandas数据框的新列根据其他列的值

时间:2015-06-03 18:45:56

标签: pandas

我的数据框中有一个包含字符串数据的列。我需要创建一个新的整数列,每个唯一的字符串一个。我将使用此列作为多索引的第二级。下面的代码可以解决问题,但我想知道Pandas中是否有更高效的解决方案呢?

import pandas as pd
df = pd.DataFrame({'c1':[1,2,3,4],
                   'c2':['a','a','b','b']})

for i,e in enumerate(df.c2.unique()):
    df.loc[df.c2 == e,'c3'] = i

1 个答案:

答案 0 :(得分:4)

for i,e in enumerate(df.c2.unique()):
    df.loc[df.c2 == e,'c3'] = i

可以替换为

df['c3'] = pd.Categorical(df['c2']).codes

即使对于这个小型DataFrame,使用Categorical也是(大约4倍)更快:

In [33]: %%timeit
...:     for i,e in enumerate(df.c2.unique()):
             df.loc[df.c2 == e,'c3'] = i
1000 loops, best of 3: 1.07 ms per loop

In [35]: %timeit pd.Categorical(df['c2']).codes
1000 loops, best of 3: 264 µs per loop

速度的提升会随着df['c2']中唯一元素的数量而增加,因为Python for-loop的相对低效率会随着迭代次数的增加而变得更加明显。

例如,如果

import string
import numpy as np
import pandas as pd

N = 10000
df = pd.DataFrame({'c1':np.arange(N),
                   'c2':np.random.choice(list(string.letters), size=N)})

然后使用Categorical(约56倍)更快:

In [53]: %%timeit
....:     for i,e in enumerate(df.c2.unique()):
              df.loc[df.c2 == e,'c3'] = i
10 loops, best of 3: 58.2 ms per loop

In [54]: %timeit df['c3'] = pd.Categorical(df['c2']).codes
1000 loops, best of 3: 1.04 ms per loop

上述基准测试采用IPython's%timeit"魔术功能"。