2015-07-24 4 views
3

У меня есть два кадра данных с временными данными. Я хочу выбрать все значения, в которых оба фрейма имеют временную метку с разницей меньше определенного порога.Слияние без столбца в Pandas

Например, dataframes 1 и 2 вид, как это, за исключением разных, непредсказуемых значений тактовой частоты:

clock  head  px  py  pz  qw   
0  0.000000 -0.316579 0.119198 0.149585 0.271688 0.987492 -0.002514 
1  0.200000 -0.316642 0.119212 0.149593 0.271678 0.987487 -0.002522 
2  1.200000 -0.316546 0.119199 0.149585 0.271669 0.987495 -0.002507 


    clock  head  px  py  pz  qw   
0  0.010000 -0.316579 0.119198 0.149585 0.271688 0.987492 -0.002514 
1  1.1040000 -0.316642 0.119212 0.149593 0.271678 0.987487 -0.002522 
2  2.4030000 -0.316546 0.119199 0.149585 0.271669 0.987495 -0.002507 

В результате dataframe выглядит при условии, порог 0,1:

clock  head1  head2  px1  px2  ...   
0  0.000000 -0.316579 -0.316579 0.119198 0.119198 ... 
1  1.200000 -0.316546 -0.316642 0.119199 0.119212 ... 

Мой текущий методология: создать идентичный столбец «наполнитель» в обоих кадрах данных, объединить в этот столбец (создавая информационный фрейм длиной len (dataframe1) * len (dataframe2)), а затем фильтровать по столбцам, которые я хочу:

#rename the dataframe keys so that they are different 
dataframe1.columns = [i+str(1) for i in dataframe1.columns.values] 
dataframe1['filler'] = 0 
dataframe2.columns = [i+str(2) for i in dataframe2.columns.values] 
dataframe2['filler'] = 0 
# merge requires a column to merge on, so merge on the filler 
df_merged = dataframe1.merge(dataframe2,on='filler',how='left') 
#pick out only the rows with the time differences within the threshold 
mask = (df_merged[keyword+str(1)]<= df_merged[keyword+str(2)]+threshold) & (df_merged[keyword+str(1)]> df_merged[keyword+str(2)]-threshold) 
df_merged = df_merged[mask] 
#delete the filler column 
del df_merged['filler'] 
#reindex the dataframe 
df_merged.index = arange(0, len(df_merged)) 

Это очень быстро и дает мне результат, который я хочу, однако, глупо создавать столбец «filler», который я должен удалить. Мне интересно, было ли более очевидное решение, которое я пропустил.

Слияние с столбцом «keyword» не дает мне то, что я хочу, это создает только данные с полными данными, только если время точно такое же, без порога по разнице во времени.

+1

Пожалуйста, добавьте небольшой пример того, что данные, которые вы имеете, и как ты хотите, чтобы он смотрел потом. – firelynx

+0

Я добавил несколько образцов данных (с теми же данными, реальные данные имеют разные значения) –

+0

Похоже на имена столбцов '' head1 "', а '' head2 "' является проблемой. Возможно, если вы сообщите нам, что вы хотите делать с колонками впоследствии, вам будет легче дать вам лучшее решение. У меня есть чувство, что вы действительно хотите согласовать данные, а затем свести их к твердым вторым наблюдениям. – firelynx

ответ

0

Вы можете использовать np.where изменить «clock данных столбца с, чтобы соответствовать df1» ваших df2 S, если оно находится в пределах порога до нечеткого матча.

import pandas as pd 
import numpy as np 

# THE TEST DATA YOU GAVE US ------------------------- 
columns = ['clock', 'head', 'px', 'py', 'pz', 'qw'] 

series1 = [(0.0, 0.1, 0.5), 
      (-0.316579, -0.316642, -0.316546), 
      (0.119198, 0.119212, 0.119199), 
      (0.149585, 0.149593, 0.149585), 
      (0.271688, 0.271678, 0.271669), 
      (0.987492, 0.987487, 0.987495), 
      (-0.002514, -0.002522, -0.002507)] 

series2 = [(0.01, 0.104, 0.403), 
      (-0.316579, -0.316642, -0.316546), 
      (0.119198, 0.119212, 0.119199), 
      (0.149585, 0.149593, 0.149585), 
      (0.271688, 0.271678, 0.271669), 
      (0.987492, 0.987487, 0.987495), 
      (-0.002514, -0.002522, -0.002507)] 
# THE TEST DATA YOU GAVE US ------------------------- 

df1 = pd.DataFrame(dict(zip(columns, series1))) 
df2 = pd.DataFrame(dict(zip(columns, series2))) 

threshold = 0.99 

df2['clock'] = np.where(
    abs(df1['clock'] - df2['clock']) < threshold, df1['clock'], df2['clock']) 

merged_df = df1.merge(df2, on='clock', how='outer') 
print(merged_df) 

    clock head_x  px_x  py_x  pz_x  qw_x head_y  px_y  py_y  pz_y  qw_y 
0 0.0 -0.316579 0.119198 0.149585 0.271688 0.987492 -0.316579 0 0.119198 0.149585 0.271688 0.987492 
1 0.1 -0.316642 0.119212 0.149593 0.271678 0.987487 -0.316642 1 0.119212 0.149593 0.271678 0.987487 
2 0.5 -0.316546 0.119199 0.149585 0.271669 0.987495 -0.316546 2 0.119199 0.149585 0.271669 0.987495 

Это имеет преимущество не сливаясь ни одной строки, которые не соответствуют порог, так что если у вас DataFrames, которые также имели ряды данных с df1['clock'] == 6 и df2['clock'] == 7 (за пределами 0.99 порога), вы будете в конечном итоге с еще двумя рядами, одна с clock == 6 и все _y «s полный NaN с, и один с clock == 7 и все _x's полный NaN сек

+0

Это не работает, предполагается, что df1 и df2 имеют одинаковый размер и сортируются. Я буду обновлять свои образцы данных, чтобы отразить это. –

+0

@CatherineHolloway Ваши данные образца больше не имеют смысла, так как значения результата 'clock' не соответствуют ни с чем –

+0

oops. Я обновил рамку результата. –

Смежные вопросы