2017-02-15 4 views
1

у меня есть dataframe, как это, с 10М строками:как добавить новый категориальный столбец в панд

     probe 
time      
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 1 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 4 
2016-01-01 00:05:00 2 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 6 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 4 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 2 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 5 
Name: probe, dtype: uint8 

Я хочу, чтобы добавить столбец categoricat на основе значения probe

def categorize_R(x): 
    return "inner" if x['probe'] in (1, 4) else "outer" 

data['category_R'] = pandas.Categorical(data.apply(categorize_R, axis=1)) 

этой ужасно медленно. На самом деле вычисления маски, как это:

mask_inner = (x['probe'] == 1) | (x['probe'] == 4) 

довольно быстро, но тогда я не знаю, как добавить столбец типа категоричной.

ответ

1

Я думаю, что вам нужно numpy.where с маской, созданной between:

mask = data.probe.between(1,4) 
data['category_R'] = pd.Categorical(np.where(mask, 'inner', 'outer')) 
print (data) 
        probe category_R 
time         
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  1  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  4  inner 
2016-01-01 00:05:00  2  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  6  outer 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  4  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  2  inner 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  5  outer 

Другим решением является использование Categorical.from_codes, проверьте также object creation - In [28]::

mask = (data['probe']==1) | (data['probe']==3) | (data['probe']==4) 

mask = (data['probe']==1) | (data['probe']==3) | (data['probe']==4) 
data['category_R'] = pd.Categorical(np.where(mask, 'inner', 'outer')) 
data['category_R1'] = pd.Categorical.from_codes(mask, ['outer','inner']) 
print (data) 
        probe category_R category_R1 
time            
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  1  inner  inner 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  4  inner  inner 
2016-01-01 00:05:00  2  outer  outer 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  6  outer  outer 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  4  inner  inner 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  2  outer  outer 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  5  outer  outer 

Timings:

In [181]: %timeit pd.Categorical(np.where(mask, 'inner', 'outer')) 
1000 loops, best of 3: 196 µs per loop 

In [182]: %timeit pd.Categorical.from_codes(mask, ['outer','inner']) 
10000 loops, best of 3: 139 µs per loop 
+0

мы близки. Дело в том, что мне нужно сделать что-то более сложное, как '(x [probe] == 1) | (x [зонд] == 3) | (x [probe] == 4) ' –

+0

Кроме того: было бы неплохо избежать создания промежуточной серии со строками и создать непосредственно ту, которая имеет категории –

+0

' numpy.where' очень быстрая, а вывод - массив numpy , также вы можете изменить маску, как вам нужно - проверить последнее изменение. – jezrael

Смежные вопросы