熊猫-具有重复值的列的外部联接

时间:2018-07-06 15:04:02

标签: python pandas numpy dataframe outer-join

这是我关于Stack Overflow的第一个问题,如果我的问题不清楚,请告诉我。

目标:使用Python和Pandas进行外部联接(或合并)包含不同实验试验的数据集,其中每个试验的“ x”轴极为相似,但有一些偏差。最重要的是,“ x”轴增加,达到最大值然后减小,通常与以前存在的“ x”点重叠。

问题:当我去联接/合并“ x”上的数据集时,“ x”列被排序,弄乱了收集到的数据的顺序,使得无法正确绘制它。

这是我要做的事的一个小例子:

因为我是新来的,所以不允许我添加图片。这是生成这些示例数据集的代码。

数据集:

Example - Trial 1 Data

Example - Trial 2 Data

导入:

import numpy as np
import pandas as pd
import random as rand

代码:

T1 = {'x':np.array([1,1.5,2,2.5,3,3.5,4,5,2,1]),'y':np.array([10000,8500,7400,6450,5670,5100,4600,4500,8400,9000]),'z':np.array(rand.sample(range(0,10000),10))}'

T2 = {'x':np.array([1,2,3,4,5,6,7,2,1.5,1]),'y':np.array([10500,7700,5500,4560,4300,3900,3800,5400,8400,8800]),'z':np.array(rand.sample(range(0,10000),10))}
Trial1 = pd.DataFrame(T1)
Trial2 = pd.DataFrame(T2)

尝试合并/加入:

WomboCombo  = Trial1.join(Trial2,how='outer',lsuffix=1,rsuffix=2, on='x')
WomboCombo2 = pd.merge(left=Trial1, right= Trial2, how = 'outer', left

试图分为两部分,增加和减少部分(通常会发现数据“ x”开始减少的行号):

Trial1Inc = Trial1[0:8]
Trial2Inc = Trial2[0:7]

结果-合并效果很好,将“ x”列混为一谈,不确定原因:

Trial1Inc.merge(Trial2Inc,on='x',how='outer', suffixes=[1,2])

Incrementing section Merge Result

Trial1Inc.join(Trial2Inc,on='x',how='outer', lsuffix=1,rsuffix=2)

Incrementing section Join Result 希望我的例子很清楚,试验1中的“ x”列增加到5,然后又减小回到0。在试验2中,我对测试进行了一些更改,因为我注意到我需要稍高的“ x”值数据。试用2增加到7,然后迅速减少回到0。

我的最终目标是将所有y值(试验之间存在重叠)的平均值与相应的x值作图。

如果有重叠,我可以添加误差线。 Pandas几乎是我想要做的事情的完美选择,因为外部联接会在没有重叠的地方添加空值,并且能够在重叠时将两个试验水平连接。

现在剩下的就是弄清楚如何在“ x”列上进行联接,但要保持其值递增和递减的顺序。对我来说很重要的原因是先增加“ x”然后再减小它是因为当查看“ y”值时,似乎给定“ x”处的初始“ y”值大于“ y” “ x”减小时的值“(当x = 1,y = 10000时,试验1中的EG,但是,稍后,当我们回到x = 1,y = 9000时,此趋势很重要。当Pandas对合并前的第一个列,而不是出现一条清晰的曲线,该曲线显示“ y”随着“ x”的增加而减小,然后反之,在连接数据的任何点都有垂直向下的跳动。

我非常感谢您提供的任何帮助:

A)一个完美的解决方案,当“ x”包含重复项时,我可以加入“ x”

B)一种有效的方式将数据集分为“ x”和“ x”,以便我可以分别合并每个试验的递增和递减部分,然后垂直合并它们。

希望我做得很好,可以解释我要解决的问题。请让我知道是否可以澄清任何事情,

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

我认为@xyzjayne拆分数据帧的想法是一个好主意。

拆分Trial1和Trial2:

# index of max x value in Trial2
t2_max_index = Trial2.index[Trial2['x'] == Trial2['x'].max()].tolist()
# split Trial2 by max value
trial2_high = Trial2.loc[:t2_max_index[0]].set_index('x')
trial2_low = Trial2.loc[t2_max_index[0]+1:].set_index('x')

# index of max x value in Trial1
t1_max_index = Trial1.index[Trial1['x'] == Trial1['x'].max()].tolist()
# split Trial1 by max vlaue
trial1_high = Trial1.loc[:t1_max_index[0]].set_index('x')
trial1_low = Trial1.loc[t1_max_index[0]+1:].set_index('x')

一旦我们拆分了数据帧,我们就将higherlowers连接在一起了:

WomboCombo_high = trial1_high.join(trial2_high, how='outer', lsuffix='1', rsuffix='2', on='x').reset_index()
WomboCombo_low = trial1_low.join(trial2_low, how='outer', lsuffix='1', rsuffix='2', on='x').reset_index()

我们现在将它们组合在一起,以获得一个数据帧WomboCombo

WomboCombo = WomboCombo_high.append(WomboCombo_low)

输出:

    x   y1      z1      y2       z2
0   1.0 10000.0 3425.0  10500.0 3061.0
1   1.5 8500.0  5059.0  NaN     NaN
2   2.0 7400.0  2739.0  7700.0  7090.0
3   2.5 6450.0  9912.0  NaN     NaN
4   3.0 5670.0  2099.0  5500.0  1140.0
5   3.5 5100.0  9637.0  NaN     NaN
6   4.0 4600.0  7581.0  4560.0  9584.0
7   5.0 4500.0  8616.0  4300.0  3940.0
8   6.0 NaN     NaN     3900.0  5896.0
9   7.0 NaN     NaN     3800.0  6211.0
0   2.0 8400.0  3181.0  5400.0  9529.0
2   1.5 NaN     NaN     8400.0  3260.0
1   1.0 9000.0  4280.0  8800.0  8303.0

答案 1 :(得分:0)

一种可能的解决方案是为您提供特定于试用行的ID,然后合并这些ID。应避免对x值进行排序。

答案 2 :(得分:0)

这是我正在尝试的方法,但是它不能解决数量可变的数据点。我喜欢Gym-hh的答案,尽管我不清楚您是否想要两对y,z对。因此,您可以结合他的想法和这段代码来获得所需的内容。

Trial1['index1'] = Trial1.index
Trial2['index1'] = Trial2.index
WomboCombo = Trial1.append(Trial2)
WomboCombo.sort_values(by=['index1'],inplace=True) 
WomboCombo

输出:

    x   y   z   index1
0   1.0 10000   7148    0
0   1.0 10500   2745    0
1   1.5 8500    248 1
1   2.0 7700    9505    1
2   2.0 7400    6380    2
2   3.0 5500    3401    2
3   2.5 6450    6183    3
3   4.0 4560    5281    3
4   3.0 5670    99  4
4   5.0 4300    8864    4
5   3.5 5100    5132    5
5   6.0 3900    7570    5
6   4.0 4600    9951    6
6   7.0 3800    7447    6
7   2.0 5400    3713    7
7   5.0 4500    3863    7
8   1.5 8400    8776    8
8   2.0 8400    1592    8
9   1.0 9000    2167    9
9   1.0 8800    782 9