当前位置: 首页 > 知识库问答 >
问题:

熊猫基于函数返回单独的数据帧值

罗心思
2023-03-14

我有两个数据帧,df1是位置的位置,df2是站点的位置。我正试图找到一种更有效的方法来应用距离函数来查找在特定范围内的站点并返回站点名称。如果距离函数是纬度差/-1,这是我的预期结果:

# df1
   Lat  Long 
0   30    31    
1   37    48    
2   54    62    
3   67    63     

# df2
   Station_Lat  Station_Long Station
0           30            32     ABC    
1           43            48     DEF    
2           84            87     GHI    
3           67            62     JKL    

# ....Some Code that compares df1 and df2....

# result
   Lat  Long  Station_Lat  Station_Long Station
    30    31           30            32     ABC
    67    63           67            62     JKL

我有一个解决方案,使用笛卡尔产品/交叉连接在单个数据帧上应用一个函数。这个解决方案是可行的,但是我在一个真正的数据集中有数百万行,这使得笛卡尔产品非常慢。

import pandas as pd
df1 = pd.DataFrame({'Lat' : [30, 37, 54, 67],
                    'Long' : [31, 48, 62, 63]})

df2 = pd.DataFrame({'Station_Lat' : [30, 43, 84, 67],
                    'Station_Long' : [32, 48, 87, 62],
                    'Station':['ABC', 'DEF','GHI','JKL']})

# creating a 'key' for a cartesian product
df1['key'] = 1
df2['key'] = 1

# Creating the cartesian Join
df3 = pd.merge(df1, df2, on='key')

# some distance function that returns True or False
# assuming the distance function I want is +/- 1 of two values
def some_distance_func(x,y):
    return x-y >= -1 and x-y <= 1

# applying the function to a column using vectorized approach
# https://stackoverflow.com/questions/52673285/performance-of-pandas-apply-vs-np-vectorize-to-create-new-column-from-existing-c
df3['t_or_f'] =  list(map(some_distance_func,df3['Lat'],df3['Station_Lat']))

# result
print(df3.loc[df3['t_or_f']][['Lat','Long','Station_Lat','Station_Long','Station']].reset_index(drop=True))

我还尝试了使用iterrows()的循环方法,但这比交叉连接方法慢。是否有一种更为通灵/高效的方式来实现我所追求的目标?

共有3个答案

鲜于德泽
2023-03-14

来一杯lambda怎么样?

df3[df3.apply(lambda x, col1='Lat', col2='Station_Lat': x[col1]-x[col2] >= -1 and x[col1]-x[col2] <= 1, axis=1)]['Station']

输出:

0     ABC
15    JKL

编辑:这是第二个解决方案。(注意:这也使用abs(),因为

for i in df1.index:
    for j in df2.index:
        if abs(df1.loc[i, 'Lat'] - df2.loc[j, 'Station_Lat']) <=1:
            print(df2.loc[j, 'Station'])

或者,以列表理解的形式:

df2.loc[[i for i in df1.index for j in df2.index if abs(df1.loc[i, 'Lat'] - df2.loc[j, 'Station_Lat']) <=1], 'Station']

输出:

ABC
JKL
娄弘
2023-03-14

也许它更快:

df2= df2.sort_values("Station_Lat")

排序后,您可以使用“searchsorted”:

df1["idx"]=df2.Station_Lat.searchsorted(df1.Lat)

"idx"是最近的站点latt. index,或者idx 1是这个。也许您需要复制df2中的最后一行(请参阅搜索排序文档),以避免过度索引它。使用“应用”这个自定义函数:

def dist(row): 
    if  abs(row.Lat-df2.loc[row.idx].Station_Lat)<=1: 
            return df2.loc[row.idx].Station 
    elif abs(row.Lat-df2.loc[row.idx+1].Station_Lat)<=1: 
            return df2.loc[row.idx+1].Station 

    return False 

df1.apply(dist,axis=1)                                                                                               

0      ABC
1    False
2    False
3      JKL
dtype: object

编辑:因为在dist()中,假设df2.index是有序的和单调递增的(参见:roww.idx1),所以必须更正第一行代码:

df2= df2.sort_values("Station_Lat").reset_index(drop=True)

dist()在这方面要快一些(但不优于笛卡尔乘积法):

def dist(row):  
          idx=row.idx 
          lat1,lat2= df2.loc[idx:idx+1,"Station_Lat"] 
          if  abs(row.Lat-lat1)<=1:  
                 return df2.loc[idx,"Station"] 
          elif abs(row.Lat-lat2)<=1:  
                 return df2.loc[idx+1,"Station"] 
          return False 
丁高峯
2023-03-14

你可以用pd。cut函数指定包含纬度的适当间隔,并简单地合并两个数据帧以获得结果:

bins = [(i-1,i+1) for i in df1['Lat']]
bins = [item for subbins in bins for item in subbins]

df1['Interval'] = pd.cut(df1['Lat'], bins=bins)
df2['Interval'] = pd.cut(df2['Station_Lat'], bins=bins)

pd.merge(df1,df2)

此解决方案比您的略快<代码>每环路10.2毫秒±201微秒与每环路12.2毫秒±1.34毫秒相比。

 类似资料:
  • 我想使用返回元组的函数将两列添加到数据帧

  • 我有以下数据帧: 我需要删除等于的行。最有效的方法是什么?

  • 我有这样一个数据帧: 我如何摆脱第四行,因为它有sq_resid的最大值?注意:最大值将从一个数据集更改到另一个数据集,所以仅仅删除第4行是不够的。 我已经尝试了一些方法,比如我可以删除像下面这样留下数据帧的最大值,但是无法删除整行。

  • 我有两个熊猫数据框 步骤2:对于flag=1的行,AA_new将计算为var1(来自df2)*组“A”和val“AA”的df1的'cal1'值*组“A”和val“AA”的df1的'cal2'值,类似地,AB_new将计算为var1(来自df2)*组“A”和val“AB”的df1的'cal1'值*组“A”和val“AB”的df1的'cal2'值 我的预期输出如下所示: 以下基于其他stackflow

  • 我有这个熊猫数据框 这就给了我: 我该怎么办 做一个新的人物, 将标题添加到图"标题这里" 以某种方式创建一个映射,这样标签不是29,30等,而是“29周”,“30周”等。 将图表的较大版本保存到我的计算机(例如10 x 10英寸) 这件事我已经琢磨了一个小时了!

  • 我有两个数据帧,其中一列名为。数据帧是从两名参与者同时录制的两个视频中提取的数据。由于跟踪失败,数据缺少一些帧(每个视频不同)。我想根据帧整数值取一个交点。 这里发布了一个类似的问题:熊猫——基于列条目的两个数据帧的交集,但接受的答案是连接,而不是交集。 已删除的行不在和 (我可以重置索引后,我完成处理) 我想首先得到两个数据帧的帧列的交集: 错误: 在获得两个数据帧中的帧索引后,我考虑执行以下操