Решено ниже
Проблема: Невозможно выполнить сортировку по .groupby()
, поскольку единственным значением является объект типа string
. Значение Index 5
, ColA 10
для Data In
является проблемой. Значение Index 5
для ColA
, 10
, является строковым объектом. pd.to_numeric()
правильно сортирует столбец, если он отсортирован только по этому столбцу.
Вопрос: Можно ли преобразовать одно значение в ColA
?
Метод:
ind = pd.to_numeric(df['ColA'], errors='coerce').fillna(999).astype(int).argsort()
df = df.reindex(ind)
df = df.groupby(df.ColA).apply(pd.DataFrame.sort_values, 'ColB')
df = df.reset_index(drop=True)
Данные в:
Index ColA ColB ColC
0 2 14-5 MumboJumbo
1 4 18-2 MumboJumbo2
2 2 24-5 MumboJumbo3
3 3 23-8 MumboJumbo4
4 2 13-6 MumboJumbo5
5 10 86-1 MumboJumbo6
6 10 42-1 MumboJumbo7
7 2 35-6 MumboJumbo8
8 Load NaN MumboJumbo9
Желаемый результат:
Index ColA ColB ColC
0 2 13-6 MumboJumbo5
1 2 14-5 MumboJumbo
2 2 24-5 MumboJumbo3
3 2 35-6 MumboJumbo8
4 3 23-8 MumboJumbo4
5 4 18-2 MumboJumbo2
6 10 42-1 MumboJumbo7
7 10 86-1 MumboJumbo6
8 Load NaN MumboJumbo9
Спасибо!
Вроде нормально. Нет проблем при сортировке ColB
с помощью .groupby()
Я действительно не понимаю проблему в вопросе, но вы можете выбрать конкретные значения в DataFrame
, используя iloc
(позиционный индекс) или loc
(индекс метки). Поскольку вы просите заменить значение в пятой строке первого столбца вашего набора данных, мы используем iloc
.
df.iloc[from_row:to_row,column_position]
Чтобы преобразовать значение '10'
в ColA
в строке 5 в int('10')
, вы просто выбираете его, а затем обновляете.
df.iloc[5:6,0] = 10
Если вы не знаете, где находится значение, которое нужно преобразовать, то iloc
и loc
вам не помогут.
Есть несколько способов преобразовать все значения в столбце в конкретный dtype
. Один из способов - использовать функцию lambda
.
df[column_name].apply(lambda x: int(x))
lambda
выше сломается, потому что ваши данные также содержат строку Load
, и вы не можете преобразовать ее в int
. Один из способов решить эту проблему - добавить условия в ваш lambda
.
df[column_name].apply(lambda x: int(x) if something else something)
Учитывая данные в вашем вопросе, самым простым способом было бы проверить, не является ли x
'Load'
:
df[column_name].apply(lambda x: int(x) if x != 'Load' else x)
Это становится проблемой, если в вашем столбце много фактических строк. Если вы хотите использовать lambda
, вы можете составить список реальных струн. А затем проверьте, есть ли x
в списке.
list_of_strings = ['Load', 'Road', 'Toad']
df[column_name].apply(lambda x: int(x) if x not in list_of_strings else x)
Другой способ - написать отдельную функцию для управления преобразованием с использованием блоков try / catch.
Как бы вы изменили iloc
, чтобы учесть это плохое значение, перемещающееся в столбце? Это не всегда может быть Индекс 5.
Нужно ли вам хранить 'Load'
в ColA
, и если да, то всегда ли за 'Load'
следует NaN
в ColB
?
Да, Load
должен оставаться в ColA
, потому что это идентификатор в A. База данных настроена не так, как я бы предпочел, но способ получения информации требует, чтобы она была в этом столбце. Да, за ним всегда будет следовать NaN в ColB. Load
может присутствовать не всегда, и это может быть набор из 3-4 разных струн. Я думаю, что ваше решение lamba ближе всего к работе. Я могу очень легко составить этот список, я думаю, что максимум может быть 4 варианта. Сейчас попробую.
df['ColA'] = df['ColA'].apply(lambda x: int(x) if x not in list_of_strings else x)
работает!
Большая проблема здесь не в строке в
ColA
, а в строках вColB
, которые необходимо отсортировать по числам, которые они содержат.