如何自定义匹配大熊猫数据框?

时间:2020-05-11 01:57:08

标签: python-3.x pandas

我有两个大的pandas DataFrame df1(按paper排序):

reference                     paper
10.1103/PhysRevB.1.3614       10.1103/PhysRev.91.174           (*)
10.1103/PhysRev.92.1367       10.1103/PhysRev.91.174
10.1103/RevModPhys.62.251     10.1103/PhysRev.91.174
10.1103/PhysRevA.10.1494      10.1103/PhysRev.91.174
10.1103/PhysRevD.74.085005    10.1103/PhysRev.91.174
10.1103/PhysRevB.7.3541       10.1103/PhysRev.113.115
10.1103/PhysRevB.1.2088       10.1103/PhysRev.113.115
10.1103/PhysRevB.1.3614       10.1103/PhysRev.113.115          (**)
10.1103/RevModPhys.57.1055    10.1103/PhysRevLett.10.486
10.1103/PhysRevB.76.064524    10.1103/PhysRevLett.10.486
...

df2(按自定义排序):

pair1                         pair2
10.1103/PhysRevA.30.336       10.1103/PhysRevA.34.1617
10.1103/PhysRevA.30.336       10.1103/PhysRevA.34.4472
10.1103/PhysRevA.30.336       10.1103/PhysRevA.41.784
10.1103/PhysRevA.34.4472      10.1103/PhysRevA.41.784   
10.1103/PhysRevA.36.4950      10.1103/PhysRevA.41.784   
10.1103/PhysRevA.38.3688      10.1103/PhysRevA.41.784   
10.1103/PhysRevA.41.3081      10.1103/PhysRevA.41.784   
10.1103/PhysRevA.30.336       10.1103/PhysRevA.45.5469  
10.1103/PhysRevA.34.4472      10.1103/PhysRevA.45.5469  
10.1103/PhysRev.91.174        10.1103/PhysRev.113.115          (#)
...

我想将两个数据框匹配为一个看起来像这样的单个数据框df

reference                     pair1                     pair2
10.1103/PhysRevB.1.3614       10.1103/PhysRev.91.174    10.1103/PhysRev.113.115   (*)(**)(#)
...

(为了更有用的理解,我标记了指标(*) (**) (#)

匹配条件为:

    reference中的
  1. pair1df必须与reference中的paperdf1相对应。 (*)

  2. reference中的
  3. pair2df必须与reference中的paperdf1相对应。 (**)

  4. pair1中的
  5. pair2df必须与pair1中的pair2df2相对应。 (#)

因此,reference必须在pair1中同时引用 pair2 paper作为df1即可在df中注册为数据点。


我尝试将df1df2合并两次:

df = df1.merge(df2, left_on='paper', right_on='pair1', how='inner')
df = df.merge(df2, left_on='paper', right_on='pair2', how='inner')
df = df.drop(['paper'], axis=1)

,但失败,因为这会产生不正确的数据点,例如reference仅引用pair1中的pair2df1中的一个,但仍在df中注册。 (更不用说由于过多的运行时间而使RAM崩溃)

我也曾尝试将DataFrames放入列表并匹配查询:

list1 = df1.values.tolist()
list2 = df2.values.tolist()

citlist = []
p1list = []
p2list = []

sublist = []
matches = []
citname = '10.1103/PhysRevB.1.3614'

for i in list1:
    # First data point
    if i[0] == citname:
        sublist.append(i[1])
    # For all data points
    if i[0] != citname:
        # Find matches
        for j in list2:
            if j[0] in sublist and j[1] in sublist:
                matches.append(j)
        for h in matches:
            citlist.append(citname)
            p1list.append(h[0])
            p2list.append(h[1])
        sublist = []
        matches = []
        citname = i[0]
        sublist.append(i[1])
    # Last data point
    if citname == '10.1103/PhysRevE.80.061802':
        for j in list2:
            if j[0] in sublist and j[1] in sublist:
                matches.append(j)
        for h in matches:
            citlist.append(citname)
            p1list.append(h[0])
            p2list.append(h[1])

但是后来我遇到了一个问题,即无法以某种方式在df1df2之间不产生任何匹配的查询。 (此方法还需要21个小时才能运行)

对这种自定义匹配有何见解?

1 个答案:

答案 0 :(得分:0)

如果我正确地理解了示例,那么所有数据都位于DF1中,我认为您不需要两个DF:

updateSurv().then( (result) {
if(json.decode(result.body)["result"] == "Success"){

    print("success");
    Navigator.of(context).pop();

  }

});

Future<dynamic> updateSurv() async{

try{
  result = await http.put(
    "http://10.0.2.2:8000/emergencies/${widget.id}/put",
    body: {

      "title" : titleController.text,
      "Content" : contentController.text,

    }
  );

 return result;
}
catch(e){
 throw e;
}

}