pandas: рассчитать максимальный ряд категориальных столбцов - PullRequest
0 голосов
/ 18 марта 2020

У меня есть DataFrame, содержащий 2 столбца упорядоченных категориальных данных (из категории той же категории ). Я хочу построить еще один столбец, который содержит категориальный максимум первых 2 столбцов. Я настроил следующее.

import pandas as pd
from pandas.api.types import CategoricalDtype
import numpy as np

cats = CategoricalDtype(categories=['small', 'normal', 'large'], ordered=True)
data = {
    'A': ['normal', 'small', 'normal', 'large', np.nan],
    'B': ['small', 'normal', 'large', np.nan, 'small'],
    'desired max(A,B)': ['normal', 'normal', 'large', 'large', 'small']
}
df = pd.DataFrame(data).astype(cats)

Можно сравнивать столбцы, хотя элементы np.nan проблемные c, как показывает следующий код:

df['A'] > df['B']

Руководство предполагает, что max () работает с категориальными данными, поэтому я пытаюсь определить мой новый столбец следующим образом.

df[['A', 'B']].max(axis=1)

Это дает столбец NaN. Почему?

Ответы [ 2 ]

0 голосов
/ 23 марта 2020

Следующий код создает требуемый столбец, используя сопоставимость категориальных столбцов. Я до сих пор не знаю, почему здесь не работает max ().

dfA = df['A']
dfB = df['B']
conditions = [dfA.isna(), (dfB.isna() | (dfA >= dfB)), True]
cases = [dfB, dfA, dfB]
df['maxAB'] = np.select(conditions, cases)
0 голосов
/ 19 марта 2020

Столбцы A и B являются строковыми типами. Макс не может понять, что является самым большим среди [малых, средних, больших]. Поэтому сначала нужно присвоить целочисленные значения каждой из этих категорий.

# size string -> integer value mapping
size2int_map = {
    'small': 0, 
    'normal': 1, 
    'large': 2
}

# integer value -> size string mapping
int2size_map = {
    0: 'small', 
    1: 'normal', 
    2: 'large'
}

# create columns containing the integer value for each size string
for c in df:
    df['%s_int' % c] = df[c].map(size2int_map)

# apply the int2size map back to get the string sizes back
print(df[['A_int', 'B_int']].max(axis=1).map(int2size_map))

, и вы должны получить

0    normal
1    normal
2     large
3     large
4     small
dtype: object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...