比较两个数据框之间的元素,并在相等的情况下添加列

时间:2019-11-21 22:19:15

标签: python pandas

考虑以下两个数据帧:

import pandas as pd

df_rp = pd.DataFrame({'id':[1,2,3,4,5,6,7,8], 'res': ['a','b','c','d','e','f','g','h']})

df_cdr = pd.DataFrame({'id':[1,2,5,6,7,1,2,3,8,9,3,4,8], 
                       'LATITUDE':[-22.98, -22.97, -22.92, -22.87, -22.89, -22.84, -22.98, 
                                   -22.14, -22.28, -22.42, -22.56, -22.70, -22.13], 
                       'LONGITUDE':[-43.19, -43.39, -43.24, -43.28, -43.67, -43.11, -43.22,
                                   -43.33, -43.44, -43.55, -43.66, -43.77, -43.88]})

我该做什么:

  • 将每个df_rp['id']元素与每个df_cdr['id']元素进行比较;
  • 如果它们相同,则需要在数据结构(列表,序列等)中添加与id相同的纬度和经度,而无需重复id。

以下是我如何将数据分组的示例:

1:[-22.98,-43.19],[-22.84,-43.11] 
2:[-22.97,-43.39],[-22.98,-43.22]
3:[-22.14,-43.33],[-22.56,-43.66]
4:[-22.70,-43.77]
5:[-22.92,-43.24]
6:[-22.87,-43.28]
7:[-22.89,-43.67]
8:[-22.28,-43.44],[-22.13,-43.88]

我很难选择哪种数据结构最适合这种情况(就像我在示例中所做的一样,看起来像一个字典,但是会有几个字典),以及如何在不重复输入的情况下将纬度和对数添加到对中ID。感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

我们需要agg的第二个df,然后reindex将其分配回

df_rp['L$L']=df_cdr.drop('id',1).apply(tuple,1).groupby(df_cdr.id).agg(list).reindex(df_rp.id).to_numpy()
df_rp
Out[59]: 
   id res                                   L$L
0   1   a  [(-22.98, -43.19), (-22.84, -43.11)]
1   2   b  [(-22.97, -43.39), (-22.98, -43.22)]
2   3   c  [(-22.14, -43.33), (-22.56, -43.66)]
3   4   d                     [(-22.7, -43.77)]
4   5   e                    [(-22.92, -43.24)]
5   6   f                    [(-22.87, -43.28)]
6   7   g                    [(-22.89, -43.67)]
7   8   h  [(-22.28, -43.44), (-22.13, -43.88)]

答案 1 :(得分:2)

df_cdr['lat_long'] = df_cdr.apply(lambda x: list([x['LATITUDE'],x['LONGITUDE']]),axis=1)

df_cdr = df_cdr.drop(columns=['LATITUDE' , 'LONGITUDE'],axis=1)

df_cdr = df_cdr.groupby('id').agg(lambda x: x.tolist())

输出

                                lat_long
id                                      
1   [[-22.98, -43.19], [-22.84, -43.11]]
2   [[-22.97, -43.39], [-22.98, -43.22]]
3   [[-22.14, -43.33], [-22.56, -43.66]]
4                      [[-22.7, -43.77]]
5                     [[-22.92, -43.24]]
6                     [[-22.87, -43.28]]
7                     [[-22.89, -43.67]]
8   [[-22.28, -43.44], [-22.13, -43.88]]
9                     [[-22.42, -43.55]]

答案 2 :(得分:1)

假设df_rp.id是唯一的,并且按照示例中的顺序进行排序。我提出了使用set_indexloc来过滤id中的df_cdr而不是df_rp中的s = (df_cdr.set_index('id').loc[df_rp.id].groupby(level=0). apply(lambda x: x.to_numpy())) Out[709]: id 1 [[-22.98, -43.19], [-22.84, -43.11]] 2 [[-22.97, -43.39], [-22.98, -43.22]] 3 [[-22.14, -43.33], [-22.56, -43.66]] 4 [[-22.7, -43.77]] 5 [[-22.92, -43.24]] 6 [[-22.87, -43.28]] 7 [[-22.89, -43.67]] 8 [[-22.28, -43.44], [-22.13, -43.88]] dtype: object 的解决方案。接下来,使用lambda调用groupby返回数组

<%= link_to 'Function Chart', new_function_chart_path(sensors_ids: @sensors.map(&:id)) %>