Pandas中不带列合并

3

我有两个时间戳数据的数据框。我想选择所有值,其中两个数据帧的时间戳差异小于某个阈值。

例如,数据帧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   

假定阈值为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))

这样做非常快,并且给我想要的输出,但是创建一个“填充”列然后再删除它感觉很愚蠢。我想知道是否有更明显的解决方案我错过了。

在“关键字”列上合并不能给我想要的结果,只有在时间完全相同且没有时间差阈值的情况下才会产生完整数据的数据框。


1
请提供一个小例子,说明你有哪些数据以及你想让它们看起来如何。 - firelynx
我已经添加了一些示例数据框(使用相同的数据,真实的数据框具有不同的值) - Catherine Holloway
感觉给列命名为“head1”和“head2”是个问题。也许如果您告诉我们之后想要对这些列做什么,那么就更容易给您提供更好的解决方案。我有一种感觉,您实际上想要将数据框连接起来,然后将它们缩减为稳定的第二个观察结果。 - firelynx
1个回答

0
你可以使用 np.where 来将你的 df2clock 列数据更改为与 df1 匹配的数据,如果它在模糊匹配的阈值内。
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'] == 6df2['clock'] == 7(超出0.99阈值),您将得到两个更多的行,一个带有clock == 6和所有_y都是NaN,另一个带有clock == 7和所有_x's都是NaNs。


这个不起作用,它假设df1和df2具有相同的大小并且已排序。我将更新我的示例数据以反映这一点。 - Catherine Holloway
@CatherineHolloway 您的样本数据不再有意义,因为结果框架中的“clock”值与任何内容都不对应。 - Adam Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接