Я использую следующий код, чтобы получить строку из фрейма данных, а затем найти максимальное значение.

def find_max(a):
    return a.values.max()

row = df.iloc[0].astype(int)
max_value = find_max(a)

Это прекрасно работает. Однако, если я передам массив, например

ar = [1,2,3]
max_value = find_max(ar)

Это не работает, и я получаю AttributeError: 'list' object has no attribute 'values'. Как я могу использовать эту функцию для обоих типов?

1
mahmood 26 Янв 2022 в 16:20
Что-то вроде isinstance dataframe else max()?
 – 
Bharel
26 Янв 2022 в 16:24
2
Примечание. Python list обычно не называется массивом. Pandas строится на основе numpy, который имеет тип массива. Вы можете использовать numpy.max() и проверить, существует ли .values.
 – 
Martijn Pieters
26 Янв 2022 в 16:24

3 ответа

Лучший ответ
def find_max(a):
    if isinstance(a, list):
        return max(a)
    elif isinstance(a, pd.DataFrame):
        return a.values.max()
    else:
        print("No max method found for the input type")
3
Jafar Isbarov 26 Янв 2022 в 16:33
2
Я предположил, что DataFrame является типом ввода по умолчанию. Как бы вы его улучшили?
 – 
Jafar Isbarov
26 Янв 2022 в 16:30
1
Это нормально, поэтому редактирование и голосование - попробуйте: кроме: будет работать для любой последовательности, но это не нужно
 – 
Patrick Artner
26 Янв 2022 в 16:33
Спасибо. Как блок try-except сравнивается с моим текущим (отредактированным) решением? Было бы лучше?
 – 
Jafar Isbarov
26 Янв 2022 в 16:35

Вам нужно будет проверить тип или использовать обработку исключений для переключения подходов:

def find_max(a):
    if isinstance(a, list):
        return max(list)
    return a.values.max()

Или

def find_max(a):
    try:
        return a.values.max()
    except AttributeError:
        # assume a Python sequence
        return max(a)

Какой из них вы выберете, зависит от нескольких факторов:

  • Вам нужно поддерживать другие итерации, такие как кортежи, наборы или генераторы?
  • Что является более распространенным случаем; случай try...except выполняется быстрее, если большинство вызовов проходят в серии Pandas.

Другой вариант — использовать np.max(), который работает с любым типом:

import numpy as np

def find_max(a):
    return np.max(a)

Обратите внимание, что здесь нет необходимости использовать атрибут .values!

4
Martijn Pieters 26 Янв 2022 в 16:30
Я бы на самом деле проверил тип фрейма данных вместо списка, так как max «покрывает» все, кроме этого, но мне все равно больше нравится подход EAFP.
 – 
Bharel
26 Янв 2022 в 16:27
@Bharel: это зависит. Какие еще типы вы проходите?
 – 
Martijn Pieters
26 Янв 2022 в 16:28
Я не ОП, но учитывая, что .values.max() будет работать только для определенных типов, а max - для общих итераций, я бы выбрал первый частный случай.
 – 
Bharel
26 Янв 2022 в 16:29
1
@Bharel: я имел в виду общее «вы» больше, чем конкретное. :-)
 – 
Martijn Pieters
26 Янв 2022 в 16:30

Почему бы не попробовать интеграция numpy для этого?

import numpy as np

row = df.iloc[0].astype(int)
max_value = np.max(a.values)

ar = [1,2,3]
max_value = np.max(ar)

Таким образом, вам не нужно определять функцию. В общем, более питонично использовать уже существующую и хорошо протестированную функциональность из пакетов Python.

2
Robin 26 Янв 2022 в 16:33