Лучший способ присоединиться / объединиться в пандах

Я часто использую pandas для merge (join), используя условие диапазона.

Например, если имеется 2 кадра данных:

A (A_id, A_value)

B (B_id, B_low, B_high, B_name)

которые являются большими и примерно одинакового размера (скажем, 2M записей каждый).

Я хотел бы сделать внутреннее соединение между A и B, поэтому A_value будет находиться между B_low и B_high.

Используя синтаксис SQL, который будет:

SELECT * FROM A,B WHERE A_value between B_low and B_high 

и это было бы очень просто, коротко и эффективно.

Между тем в пандах единственный способ (который не использует петли, которые я нашел) – это создать фиктивный столбец в обеих таблицах, присоединиться к нему (эквивалентно перекрестному объединению), а затем отфильтровать ненужные строки. Это звучит тяжело и сложно:

 A['dummy'] = 1 B['dummy'] = 1 Temp = pd.merge(A,B,on='dummy') Result = Temp[Temp.A_value.between(Temp.B_low,Temp.B_high)] 

Еще одно решение, которое я использовал, – это применить к каждому из значений A функцию поиска на B с помощью B[(x>=B.B_low) & (x<=B.B_high)] , но она также неэффективна и может требуют оптимизации индекса.

Есть ли более элегантный и / или эффективный способ выполнения этого действия?

5 Solutions collect form web for “Лучший способ присоединиться / объединиться в пандах”

Настроить
Рассмотрим кадры данных A и B

 A = pd.DataFrame(dict( A_id=range(10), A_value=range(5, 105, 10) )) B = pd.DataFrame(dict( B_id=range(5), B_low=[0, 30, 30, 46, 84], B_high=[10, 40, 50, 54, 84] )) A A_id A_value 0 0 5 1 1 15 2 2 25 3 3 35 4 4 45 5 5 55 6 6 65 7 7 75 8 8 85 9 9 95 B B_high B_id B_low 0 10 0 0 1 40 1 30 2 50 2 30 3 54 3 46 4 84 4 84 

numpy
Самый простой способ – использовать numpy вещание.
Мы ищем каждый экземпляр A_value который больше или равен B_low , в то время как A_value меньше или равно B_high .

 a = A.A_value.values bh = B.B_high.values bl = B.B_low.values i, j = np.where((a[:, None] >= bl) & (a[:, None] <= bh)) pd.DataFrame( np.column_stack([A.values[i], B.values[j]]), columns=A.columns.append(B.columns) ) A_id A_value B_high B_id B_low 0 0 5 10 0 0 1 3 35 40 1 30 2 3 35 50 2 30 3 4 45 50 2 30 

Я не знаю, насколько он эффективен, но кто-то написал обертку, которая позволяет использовать синтаксис SQL с объектами pandas. Это называется пандаск . В документации явно указано, что соединения поддерживаются. Это может быть, по крайней мере, легче читать, поскольку синтаксис SQL очень читабельен.

Не уверен, что это более эффективно, однако вы можете напрямую использовать sql (например, из модуля sqlite3) с помощью pandas (вдохновленный этим вопросом ), например:

 conn = sqlite3.connect(":memory") df2 = pd.DataFrame(np.random.randn(10, 5), columns=["col1", "col2", "col3", "col4", "col5"]) df1 = pd.DataFrame(np.random.randn(10, 5), columns=["col1", "col2", "col3", "col4", "col5"]) df1.to_sql("df1", conn, index=False) df2.to_sql("df2", conn, index=False) qry = "SELECT * FROM df1, df2 WHERE df1.col1 > 0 and df1.col1<0.5" tt = pd.read_sql_query(qry,conn) 

Вы можете адаптировать запрос по мере необходимости в своем приложении

давайте рассмотрим простой пример:

 df=pd.DataFrame([2,3,4,5,6],columns=['A']) 

возвращается

  A 0 2 1 3 2 4 3 5 4 6 

теперь позволяет определить второй блок данных

 df2=pd.DataFrame([1,6,2,3,5],columns=['B_low']) df2['B_high']=[2,8,4,6,6] 

приводит к

  B_low B_high 0 1 2 1 6 8 2 2 4 3 3 6 4 5 6 

вот так; и мы хотим, чтобы результат был индексом 3 и значением 5

 df.where(df['A']>=df2['B_low']).where(df['A']<df2['B_high']).dropna() 

приводит к

  A 3 5.0 

Учтите, что ваш информационный кадр A

 A = pd.DataFrame([[0,2],[1,3],[2,4],[3,5],[4,6]],columns=['A_id', 'A_value']) 

и B –

 B = pd.DataFrame([[0,1,2,'a'],[1,4,9,'b'],[2,2,5,'c'],[3,6,7,'d'],[4,8,9,'e']],columns=['B_id', 'B_low', 'B_high', 'B_name']) 

используя это ниже, вы получите желаемый результат

 A = A[(A['A_value']>=B['B_low'])&(A['A_value']<=B['B_high'])] 
  • Экспорт таблицы LaTeX из pandas DataFrame
  • Установить значение для конкретной ячейки в pandas DataFrame
  • Вставьте диаграмму pandas в файл Excel с помощью XlsxWriter
  • Более эффективный способ округления до метки времени с использованием панд
  • Импортировать файл netCDF в базу данных Pandas
  • Добавление двух кадров данных pandas
  • Эффективный способ заменить значение каждой ячейки в кадре данных pandas
  • Пандас Тимедельта в днях
  • Как превратить блок данных в ряд списков?
  • панды: считать вещи
  • Добавить столбец из одного фрейма данных в кадр данных группы в python
  • Python - лучший язык программирования в мире.