У меня есть следующий набор данных:
df = pd.DataFrame(np.random.rand(50,2), columns=list('AB'))
данные графика
plt.scatter(x=df.A, y=df.B)
x = plt.axhline(y=0.4,c='k')
y = plt.axvline(x=0.4,c='k')
plt.plot([0.2, 0.3], [0, 0.4], c='k')
Я хочу выбрать точки в зеленых областях (см. график ниже). Точки во втором квадранте было легко выбрать, но не точки в зеленой области в третьем квадранте.
Вот как я выбрал точки во втором квадранте:
df[( df['A'] < 0.4) & (df['B'] > 0.4)]
после этого я застрял.
Учитывая, что условия могут стать сложными, например, иметь дело с кривыми линиями и т. д. Как лучше всего решить эту проблему?
Открыт для любых предложений.
Я бы попробовал что-то вроде df[( df['A'] < 0,4) & ((df['B'] > 0,4) | df['B'] < f(['A']))], тогда как f (['A']) будет функцией, определяющей ту кривую, которая у вас есть в третьем квадранте. В настоящее время у меня нет под рукой Python IDE - я дам правильный ответ, как только сделаю это.
@ knh190 это не функция, а визуализация того, что я хочу сделать. Я предпочитаю рассматривать оба метода, если это возможно, математически и применяя классификатор.
@sekky спасибо. Ждем вашего ответа :)
Я предлагаю вам использовать functools:
import numpy as np
import functools
cr1 = functools.reduce(np.logical_and, [df.B < 0.4, df.A < 0.2])
cr2 = functools.reduce(np.logical_and, [df.B < 0.4, df.A > 0.2, df.B > (df.A-0.2)*4])
df_filtered = df[functools.reduce(np.logical_or, [cr1,cr2])]
Спасибо, но мне пришлось изменить эти уравнения, чтобы получить желаемые результаты: , [ df.B < 0,4, df.B > (df.A-0,2)*4])'
Поскольку я обещал решение, вот одно из них без использования functools:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
np.random.seed(42)
df = pd.DataFrame(np.random.rand(50,2), columns=list('AB'))
plt.scatter(x=df.A, y=df.B)
x = plt.axhline(y=0.4,c='k')
y = plt.axvline(x=0.4,c='k')
plt.plot([0.2, 0.3], [0, 0.4], c='k')
# the next line is the one selecting all datapoints within
sub_df = df[(( df['A'] < 0.4) & (df['B'] > 0.4)) | (df['B'] < 0.4) & (df['A'] < (0.2 + 0.25*df['B']))]
plt.scatter(sub_df['A'], sub_df['B'], marker='x', color='red')
plt.xlabel('A')
plt.ylabel('B')
plt.show()
Предложение df['A'] < (0.2 + 0.25*df['B'])
просто описывает линейную функцию. Вы можете заменить это чем-нибудь другим (например, экспоненциальной функцией).
Результирующий график из приведенного выше кода:
Спасибо, functools тоже работал, но это проще и понятнее :)
Определена ли функция линии
[0.2, 0.3], [0, 0.4]
? А как бы вы хотели решить задачу, т.е. с помощью математической функции или применить классификатор?