Python Pandas :比较沿一列的两个数据帧和 return 两个数据帧的行在另一个数据帧中的内容
Python Pandas : compare two data-frames along one column and return content of rows of both data frames in another data frame
- 我正在处理两个 csv 文件并导入为数据框 df1 和 df2
- df1 有 50000 行,df2 有 150000 行。
- 我想比较(遍历每一行)df2 的 'time' 与
df1,找出时间差和return所有列的值
对应相似行,保存在df3(时间同步)
- 例如,35427949712(df1 中 'time' 的)最接近或等于
35427949712(在 df2 中 'time'),所以我想 return
内容到 df1('velocity_x' 和 'yaw')和 df2('velocity' 和
'yawrate') 并保存在 df3
- 为此,我使用了两种技术,如代码所示。
- 代码 1 需要很长时间才能执行 72 小时,这不是实践,因为我有很多 csv 文件
- 代码 2 给了我 "memory error" 并且内核死了。
如果考虑到计算时间、内存和功率(Intel Core i7-6700HQ,8 GB Ram),如果我能得到更强大的解决方案,那就太好了
这里是示例数据,
import pandas as pd
df1 = pd.DataFrame({'time': [35427889701, 35427909854, 35427929709,35427949712, 35428009860],
'velocity_x':[12.5451, 12.5401,12.5351,12.5401,12.5251],
'yaw' : [-0.0787806, -0.0784749, -0.0794889,-0.0795915,-0.0795472]})
df2 = pd.DataFrame({'time': [35427929709, 35427949712, 35427009860,35427029728, 35427049705],
'velocity':[12.6583, 12.6556,12.6556,12.6556,12.6444],
'yawrate' : [-0.0750492, -0.0750492, -0.074351,-0.074351,-0.074351]})
df3 = pd.DataFrame(columns=['time','velocity_x','yaw','velocity','yawrate'])
代码1
for index, row in df1.iterrows():
min=100000
for indexer, rows in df2.iterrows():
if abs(float(row['time'])-float(rows['time']))<min:
min = abs(float(row['time'])-float(rows['time']))
#storing the position
pos = indexer
df3.loc[index,'time'] = df1['time'][pos]
df3.loc[index,'velocity_x'] = df1['velocity_x'][pos]
df3.loc[index,'yaw'] = df1['yaw'][pos]
df3.loc[index,'velocity'] = df2['velocity'][pos]
df3.loc[index,'yawrate'] = df2['yawrate'][pos]
代码2
df1['key'] = 1
df2['key'] = 1
df1.rename(index=str, columns ={'time' : 'time_x'}, inplace=True)
df = df2.merge(df1, on='key', how ='left').reset_index()
df['diff'] = df.apply(lambda x: abs(x['time'] - x['time_x']), axis=1)
df.sort_values(by=['time', 'diff'], inplace=True)
df=df.groupby(['time']).first().reset_index()[['time', 'velocity_x', 'yaw', 'velocity', 'yawrate']]
您正在寻找 pandas.merge_asof
。它允许您在一个键上组合 2 DataFrame
s,在本例中为 time
,而不要求它们完全匹配。您可以选择 direction
来确定匹配的优先级,但在这种情况下,很明显您需要 nearest
A “nearest” search selects the row in the right DataFrame whose ‘on’ key is closest in absolute distance to the left’s key.
需要注意的是,您需要对事物进行排序才能使 merge_asof
正常工作。
import pandas as pd
pd.merge_asof(df2.sort_values('time'), df1.sort_values('time'), on='time', direction='nearest')
# time velocity yawrate velocity_x yaw
#0 35427009860 12.6556 -0.074351 12.5451 -0.078781
#1 35427029728 12.6556 -0.074351 12.5451 -0.078781
#2 35427049705 12.6444 -0.074351 12.5451 -0.078781
#3 35427929709 12.6583 -0.075049 12.5351 -0.079489
#4 35427949712 12.6556 -0.075049 12.5401 -0.079591
请注意您选择哪个 DataFrame
作为左框架或右框架,因为这会改变结果。在这种情况下,我选择 df1
中的 time
,它在绝对距离上最接近 df2
中的 time
。
如果你在右边有重复的on
键,你也需要小心df
因为对于精确匹配,merge_asof
只合并右边最后排序的行df
到左侧 df
,而不是为每个完全匹配创建多个条目。如果这是一个问题,您可以先合并确切的键以获得所有组合,然后将其余部分与 asof 合并。
只是一个旁注(不是答案)
min_delta=100000
for indexer, rows in df2.iterrows():
if abs(float(row['time'])-float(rows['time']))<min_delta:
min_delta = abs(float(row['time'])-float(rows['time']))
#storing the position
pos = indexer
可以写成
diff = np.abs(row['time'] - df2['time'])
pos = np.argmin(diff)
(始终避免 for 循环)
并且不要使用内置名称调用您的变量 (min
)
- 我正在处理两个 csv 文件并导入为数据框 df1 和 df2
- df1 有 50000 行,df2 有 150000 行。
- 我想比较(遍历每一行)df2 的 'time' 与 df1,找出时间差和return所有列的值 对应相似行,保存在df3(时间同步)
- 例如,35427949712(df1 中 'time' 的)最接近或等于 35427949712(在 df2 中 'time'),所以我想 return 内容到 df1('velocity_x' 和 'yaw')和 df2('velocity' 和 'yawrate') 并保存在 df3
- 为此,我使用了两种技术,如代码所示。
- 代码 1 需要很长时间才能执行 72 小时,这不是实践,因为我有很多 csv 文件
- 代码 2 给了我 "memory error" 并且内核死了。
如果考虑到计算时间、内存和功率(Intel Core i7-6700HQ,8 GB Ram),如果我能得到更强大的解决方案,那就太好了
这里是示例数据,
import pandas as pd
df1 = pd.DataFrame({'time': [35427889701, 35427909854, 35427929709,35427949712, 35428009860],
'velocity_x':[12.5451, 12.5401,12.5351,12.5401,12.5251],
'yaw' : [-0.0787806, -0.0784749, -0.0794889,-0.0795915,-0.0795472]})
df2 = pd.DataFrame({'time': [35427929709, 35427949712, 35427009860,35427029728, 35427049705],
'velocity':[12.6583, 12.6556,12.6556,12.6556,12.6444],
'yawrate' : [-0.0750492, -0.0750492, -0.074351,-0.074351,-0.074351]})
df3 = pd.DataFrame(columns=['time','velocity_x','yaw','velocity','yawrate'])
代码1
for index, row in df1.iterrows():
min=100000
for indexer, rows in df2.iterrows():
if abs(float(row['time'])-float(rows['time']))<min:
min = abs(float(row['time'])-float(rows['time']))
#storing the position
pos = indexer
df3.loc[index,'time'] = df1['time'][pos]
df3.loc[index,'velocity_x'] = df1['velocity_x'][pos]
df3.loc[index,'yaw'] = df1['yaw'][pos]
df3.loc[index,'velocity'] = df2['velocity'][pos]
df3.loc[index,'yawrate'] = df2['yawrate'][pos]
代码2
df1['key'] = 1
df2['key'] = 1
df1.rename(index=str, columns ={'time' : 'time_x'}, inplace=True)
df = df2.merge(df1, on='key', how ='left').reset_index()
df['diff'] = df.apply(lambda x: abs(x['time'] - x['time_x']), axis=1)
df.sort_values(by=['time', 'diff'], inplace=True)
df=df.groupby(['time']).first().reset_index()[['time', 'velocity_x', 'yaw', 'velocity', 'yawrate']]
您正在寻找 pandas.merge_asof
。它允许您在一个键上组合 2 DataFrame
s,在本例中为 time
,而不要求它们完全匹配。您可以选择 direction
来确定匹配的优先级,但在这种情况下,很明显您需要 nearest
A “nearest” search selects the row in the right DataFrame whose ‘on’ key is closest in absolute distance to the left’s key.
需要注意的是,您需要对事物进行排序才能使 merge_asof
正常工作。
import pandas as pd
pd.merge_asof(df2.sort_values('time'), df1.sort_values('time'), on='time', direction='nearest')
# time velocity yawrate velocity_x yaw
#0 35427009860 12.6556 -0.074351 12.5451 -0.078781
#1 35427029728 12.6556 -0.074351 12.5451 -0.078781
#2 35427049705 12.6444 -0.074351 12.5451 -0.078781
#3 35427929709 12.6583 -0.075049 12.5351 -0.079489
#4 35427949712 12.6556 -0.075049 12.5401 -0.079591
请注意您选择哪个 DataFrame
作为左框架或右框架,因为这会改变结果。在这种情况下,我选择 df1
中的 time
,它在绝对距离上最接近 df2
中的 time
。
如果你在右边有重复的on
键,你也需要小心df
因为对于精确匹配,merge_asof
只合并右边最后排序的行df
到左侧 df
,而不是为每个完全匹配创建多个条目。如果这是一个问题,您可以先合并确切的键以获得所有组合,然后将其余部分与 asof 合并。
只是一个旁注(不是答案)
min_delta=100000
for indexer, rows in df2.iterrows():
if abs(float(row['time'])-float(rows['time']))<min_delta:
min_delta = abs(float(row['time'])-float(rows['time']))
#storing the position
pos = indexer
可以写成
diff = np.abs(row['time'] - df2['time'])
pos = np.argmin(diff)
(始终避免 for 循环)
并且不要使用内置名称调用您的变量 (min
)