Фильтровать Pandas DataFrame другим DataFrame, используя указанный допуск - PullRequest
0 голосов
/ 23 февраля 2020

Я довольно новичок в python и пытаюсь отфильтровать значения из фрейма данных по двум столбцам, используя значения, указанные в отдельном фрейме данных +, используя допуск, чтобы указать значения "достаточно близко", чтобы быть равными. Я хотел бы отфильтровать данные путем индексации по дате, а затем по заданным c глубинам, выбранным для строки.

Мои данные CTD настроены так (фактические данные имеют несколько параметров, кроме Temperature (deg C), но для простоты):

           Date  Depth (m)  Temperature (deg C)
0    2016-09-20       0.11                14.29
1    2016-09-20       0.15                14.29
2    2016-09-20       0.29                14.30
3    2016-09-20       0.44                14.32
4    2016-09-20       0.55                14.33
        ...        ...                  ...
1546 2017-04-27      23.89                 8.50
1547 2017-04-27      24.31                 8.49
1548 2017-04-27      24.56                 8.50
1549 2017-04-27      24.61                 8.55
1550 2017-04-27      24.71                 8.57

С индексным фреймом данных (value_ind) для фильтрации данных по:

          Date  Depth (m)
476 2016-09-20        1.0
477 2016-09-20        2.7
478 2016-09-20        9.7
479 2016-09-20       21.0
480 2016-10-04        1.0
..         ...        ...
552 2017-08-09       30.0
553 2017-09-30        0.0
554 2017-09-30        1.0
555 2017-09-30        4.0
556 2017-09-30        8.0

Я прочитал несколько постов с похожими проблемы и моя первоначальная попытка последовали за решением, предложенным здесь:
pandas - фильтровать кадр данных другим кадром данных по элементам строки

# Convert dates to integers to be recognizable by indexing
value_ind['Date'] = value_ind['Date'].values.astype('float64') 
CTD['Date'] = CTD['Date'].values.astype('float64')

keys = list(CTD.columns.values)
keys = keys[0:2] # limits to date/depth to index by
ind1 = CTD.set_index(keys).index
ind2 = value_ind.set_index(keys).index

# Find CTD values corresponding to sampling dates, depths:
CTD_values = CTD[ind1.isin(ind2)]

Это дает почти те результаты, которые мне нужны; тем не менее, я понял, что pandas.DataFrame.isin() не имеет аргумента допуска и оценивает значения только как равные (==) друг другу, а поскольку столбцы Depth (m) в двух моих данных имеют разную точность с плавающей точкой, некоторые значения заканчиваются до исключен.

numpy.isclose() кажется следующим лучшим решением, но до сих пор я пытался:

CTD_values = CTD[np.isclose(ind1, ind2, atol=0.1).any(1)]

Чтобы исправить мою предыдущую попытку, но это не удалось (я думаю, из-за того, что ind переменные являются кортежами). Я также попытался сгруппировать сначала по Date, а затем запустить условный аргумент для фильтрации по Depth (m) по направлениям:

CTD_values = CTD[CTD.groupby(['Date', np.isclose(CTD['Depth (m)'].values[:, None], list(value_ind['Depth (m)']),atol=0.1).any(1)])]

Но все же не повезло.

Я пытался использовать значение допуска 0,1, но в идеале я хотел бы использовать решение, которое могло бы указать допуск, определяющий минимальную разницу между двумя кадрами данных вдоль строк:

x = np.min(np.abs(ind1-ind2))

Чтобы отфильтровать случаи, когда значения Depth (m) слишком близки для дифференциации, в результате чего 2 и более значения параметра будут найдены при одном и том же значении Depth (m). Я не уверен, что вместо этого лучше использовать циклы for, но любые предложения будут с благодарностью приняты!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...