2016-11-14 3 views
3

У меня есть «поиск» таблицы в формате, например:значение Lookup в словаре между панд диапазона

Min | Max | Val 
    1 | 99 | "Principal" 
100 | 199 | "Partner" 
... | ... | ... 

Существует ряд CURRENT_POINTS в моей dataframe, что между Min или Max (включительно).

Вопрос: как создать столбец VAL, основанный на приведенной выше таблице поиска? Моя первоначальная мысль состояла в том, чтобы использовать df.lookup, но есть строки в 800K в df, поэтому обе таблицы не одинакового размера.

Заранее благодарим за вашу помощь!

Любые мысли?

ответ

3

Я бы использовал cut() способ.

Если у вас есть следующие ДФХ:

In [187]: lkp 
Out[187]: 
    Min Max Val 
0 1 99 AAA 
1 100 199 BBB 
2 200 299 CCC 
3 300 399 DDD 

In [188]: df 
Out[188]: 
    CURRENT_POINTS 
0    55 
1    10 
2    20 
3    144 
4    194 
5    143 
6    397 
7    233 
8    128 
9    215 

Использование cut() метода мы можем создать новый столбец category DTYPE, который может сэкономить много памяти:

In [189]: df['Val'] = pd.cut(df.CURRENT_POINTS, 
    ...:     bins=[0] + lkp[['Min','Max']].stack()[1::2].tolist(), 
    ...:     labels=lkp.Val.tolist()) 
    ...: 

In [190]: df 
Out[190]: 
    CURRENT_POINTS Val 
0    55 AAA 
1    10 AAA 
2    20 AAA 
3    144 BBB 
4    194 BBB 
5    143 BBB 
6    397 DDD 
7    233 CCC 
8    128 BBB 
9    215 CCC 

In [191]: df.dtypes 
Out[191]: 
CURRENT_POINTS  int32 
Val    category 
dtype: object 

Категория DTYPE может сэкономить много памяти:

In [192]: big = pd.concat([df] * 10**5, ignore_index=True) 

In [193]: big.shape 
Out[193]: (1000000, 2) 

In [194]: big['str_col'] = 'AAA' 

In [198]: big.dtypes 
Out[198]: 
CURRENT_POINTS  int32 
Val    category 
str_col    object 
dtype: object 

In [195]: big.memory_usage() 
Out[195]: 
Index     80 
CURRENT_POINTS 4000000 
Val    1000032  # <--- `category` column takes 1 byte per row (plus 32 bytes overhead) 
str_col   8000000 

In [197]: big.head() 
Out[197]: 
    CURRENT_POINTS Val str_col 
0    55 AAA  AAA 
1    10 AAA  AAA 
2    20 AAA  AAA 
3    144 BBB  AAA 
4    194 BBB  AAA 

ПРИМЕЧАНИЕ: обратить внимание на использование памяти для category колонки Val и для str_col колонки (DTYPE: object)

Пояснение:

закромах:

In [199]: lkp[['Min','Max']] 
Out[199]: 
    Min Max 
0 1 99 
1 100 199 
2 200 299 
3 300 399 

In [200]: lkp[['Min','Max']].stack() 
Out[200]: 
0 Min  1 
    Max  99 
1 Min 100 
    Max 199 
2 Min 200 
    Max 299 
3 Min 300 
    Max 399 
dtype: int64 

In [201]: lkp[['Min','Max']].stack()[1::2].tolist() 
Out[201]: [99, 199, 299, 399] 

In [202]: [0] + lkp[['Min','Max']].stack()[1::2].tolist() 
Out[202]: [0, 99, 199, 299, 399] 

этикетки:

In [203]: lkp.Val.tolist() 
Out[203]: ['AAA', 'BBB', 'CCC', 'DDD'] 

ПРИМЕЧАНИЕ: lkp необходимо отсортировать по ['Min', 'Max'] перед тем, как использовать его для bins и labels.

Вот небольшой демо для сортировки:

In [2]: lkp 
Out[2]: 
    Min Max Val 
0 300 399 DDD 
1 100 199 BBB 
2 1 99 AAA 
3 200 299 CCC 

In [4]: lkp = lkp.sort_values(['Min','Max']) 

In [5]: lkp 
Out[5]: 
    Min Max Val 
2 1 99 AAA 
1 100 199 BBB 
3 200 299 CCC 
0 300 399 DDD 
+0

Большое спасибо за ответ! Я бы тогда просто «as.type (str)» в столбце «Val», созданном выше, чтобы уменьшить нагрузку на память? – user791411

+1

@ пользователь791411, добро пожаловать! Нет, вы хотите сохранить его как 'category' - это всего лишь« настроенная »строка dtype. Я добавил 'str_col', чтобы показать разницу в использовании памяти – MaxU

+0

OK спасибо! ** Вопрос **: Я получил сообщение об ошибке «ЗначениеError: бины должны увеличиваться монотонно». «Как мне изменить код? – user791411

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