2017-05-31 100 views
3

我试图结合两组数据,但我想不通哪种方法最合适(加入,合并,concat,等等),并且该文档没有任何可以做我需要做的事情的例子。熊猫加入/合并/ concat两个数据帧和组合行的相同的密钥/索引

我有两组数据,结构类似这样:

>>> A 
Time  Voltage 
1.0  5.1 
2.0  5.5 
3.0  5.3 
4.0  5.4 
5.0  5.0 

>>> B 
Time  Current 
-1.0  0.5 
0.0  0.6 
1.0  0.3 
2.0  0.4 
3.0  0.7 

我想数据列结合和“时间”列合并在一起,这样我得到如下:

>>> AB 
Time  Voltage  Current 
-1.0     0.5 
0.0     0.6 
1.0  5.1   0.3 
2.0  5.5   0.4 
3.0  5.3   0.7 
4.0  5.4    
5.0  5.0    

我试过AB = merge_ordered(A, B, on='Time', how='outer'),而它成功地结合了数据,就输出一个类似于:

>>> AB 
Time  Voltage  Current 
-1.0     0.5 
0.0     0.6 
1.0  5.1    
1.0     0.3 
2.0  5.5    
2.0     0.4 
3.0  5.3    
3.0     0.7 
4.0  5.4    
5.0  5.0    

您会注意到它没有将行与共享的“时间”值组合在一起。

我也试图合并一拉AB = A.merge(B, on='Time', how='outer'),但输出的东西结合起来,但没有排序,像这样:

>>> AB 
Time  Voltage  Current 
-1.0     0.5 
0.0     0.6 
1.0  5.1    
2.0  5.5    
3.0  5.3   0.7 
4.0  5.4    
5.0  5.0    
1.0     0.3 
2.0     0.4 

...它基本上是跳过一些在“当前”数据和将其附加到底部,但它不一致。而且,它不会将行合并在一起。

我有尝试AB = pandas.concat(A, B, axis=1),但结果不合并。我简单地得到,那么,这两个DataFrames的级联,像这样:

>>> AB 
Time  Voltage  Time  Current 
1.0  5.1   -1.0  0.5 
2.0  5.5   0.0  0.6 
3.0  5.3   1.0  0.3 
4.0  5.4   2.0  0.4 
5.0  5.0   3.0  0.7 

我一直精练的文档和这里揣摩mergejoin之间的确切差别,但是从我收集他们非常相似。尽管如此,我还没有找到任何具体回答“如何合并具有相同关键字/索引的行”的问题。任何人都可以启发我如何做到这一点?我只有几天的大熊猫经验!

+0

确保'Time'列在这两个的DF – MaxU

+0

相同的D型你移动你的?请解答一个答案框?我们不会在这里提出解决方案你想问问这是否是一个很好的解决方案,你可以问问有其他答案的人。 – halfer

+0

@halfer看起来像你为我编辑我的帖子。我还需要做什么?恐怕我不知道你指的是什么答案框...... –

回答

3

merge
merge结合了列。默认情况下,它采用所有通常命名的列。否则,您可以指定要组合的列。在这个例子中,我选择了Time

A.merge(B, 'outer', 'Time') 

    Time Voltage Current 
0 1.0  5.1  0.3 
1 2.0  5.5  0.4 
2 3.0  5.3  0.7 
3 4.0  5.4  NaN 
4 5.0  5.0  NaN 
5 -1.0  NaN  0.5 
6 0.0  NaN  0.6 

join
join结合了索引值,除非您指定左侧的列来代替。这就是为什么我设置右侧的索引并为左侧指定一个列Time

A.join(B.set_index('Time'), 'Time', 'outer') 

    Time Voltage Current 
0 1.0  5.1  0.3 
1 2.0  5.5  0.4 
2 3.0  5.3  0.7 
3 4.0  5.4  NaN 
4 5.0  5.0  NaN 
4 -1.0  NaN  0.5 
4 0.0  NaN  0.6 ​ 

pd.concat
concat结合了指数值...所以我创建了一个列表理解,其中我遍历了每个要合并的数据帧[A, B]。在理解中,每个数据框都假定名称为d,因此为for d in [A, B]axis=1表示将它们并排组合使用,因此使用索引作为连接特征。

pd.concat([d.set_index('Time') for d in [A, B]], axis=1).reset_index() 

    Time Voltage Current 
0 -1.0  NaN  0.5 
1 0.0  NaN  0.6 
2 1.0  5.1  0.3 
3 2.0  5.5  0.4 
4 3.0  5.3  0.7 
5 4.0  5.4  NaN 
6 5.0  5.0  NaN 

combine_first

A.set_index('Time').combine_first(B.set_index('Time')).reset_index() 

    Time Current Voltage 
0 -1.0  0.5  NaN 
1 0.0  0.6  NaN 
2 1.0  0.3  5.1 
3 2.0  0.4  5.5 
4 3.0  0.7  5.3 
5 4.0  NaN  5.4 
6 5.0  NaN  5.0 
+0

那么在'join'和'merge'的确有什么区别?有趣。通过你的例子,看起来'concat'的结果正是我所期望的,尽管有一些我不明白其功能的论点。你能解释那里发生了什么? 'd'从哪里来? 'reset_index'的目的是什么? (我以为'时间'_was是我的索引?) –

+0

为了在这种情况下扩展'concat'的用法:我试图按照你写的那样实现它,但是导致与'merge'类似的输出。也就是说:如我所希望的那样,将数据合并为_mostly_,但每个第N行都不合并,如我原来的帖子所示。 考虑到多种方法产生相同的结果,在我看来,问题不一定是方法,而是我的数据。这是否与尺寸有关?速度?什么会导致它经常跳过组合行? –

+1

我认为@MaxU正在识别你的问题。在加入之前尝试'A = A.astype.float()'和'B = B.astype(float)'。 – piRSquared

2

应该正常工作,如果Time列在两个话语结构相同的D型细胞:

In [192]: A.merge(B, how='outer').sort_values('Time') 
Out[192]: 
    Time Voltage Current 
5 -1.0  NaN  0.5 
6 0.0  NaN  0.6 
0 1.0  5.1  0.3 
1 2.0  5.5  0.4 
2 3.0  5.3  0.7 
3 4.0  5.4  NaN 
4 5.0  5.0  NaN 

In [193]: A.dtypes 
Out[193]: 
Time  float64 
Voltage float64 
dtype: object 

In [194]: B.dtypes 
Out[194]: 
Time  float64 
Current float64 
dtype: object 

再现您的问题:

In [198]: A.merge(B.assign(Time=B.Time.astype(str)), how='outer').sort_values('Time') 
Out[198]: 
    Time Voltage Current 
5 -1.0  NaN  0.5 
6 0.0  NaN  0.6 
0 1.0  5.1  NaN 
7 1.0  NaN  0.3 
1 2.0  5.5  NaN 
8 2.0  NaN  0.4 
2 3.0  5.3  NaN 
9 3.0  NaN  0.7 
3 4.0  5.4  NaN 
4 5.0  5.0  NaN 

In [199]: B.assign(Time=B.Time.astype(str)).dtypes 
Out[199]: 
Time  object # <------ NOTE 
Current float64 
dtype: object 

视觉上很难区分:

In [200]: B.assign(Time=B.Time.astype(str)) 
Out[200]: 
    Time Current 
0 -1.0  0.5 
1 0.0  0.6 
2 1.0  0.3 
3 2.0  0.4 
4 3.0  0.7 

In [201]: B 
Out[201]: 
    Time Current 
0 -1.0  0.5 
1 0.0  0.6 
2 1.0  0.3 
3 2.0  0.4 
4 3.0  0.7 
+0

我已经验证了这两个DF中的'时间'列的数据类型是相同的(float64)。按照您的建议使用merge方法会导致类似的不一致的合并,类似于我的初始文章中的A.merge的示例。在这种情况下,数据将被排序,但每第N行不会组合。我希望我可以包括一个例子,但字符数太低... –

+0

@ J.Day,试试这个:'pd.merge_ordered(A.assign(Time = A.Time.round(4)),B.assign (时间= B.Time.round(4)))' – MaxU

+0

我想我明白这是怎么回事。唯一需要注意的是我的实际数据列名是'Time,(sec)',而不仅仅是'Time'(为了简洁起见我简化了我的第一个例子)。我如何写这行以适应名字中的额外标点符号? –

0

发现的解决方案 按照下面的建议,我曾在之前的合并他们的“时间”栏,圆的数字尽管他们都是相同的dtype(float64)。该建议是圆像这样:

A = A.assign(A.Time = A.Time.round(4)) 

但是在我的实际情况,该列被打成“时间(秒)”(有标点符号与分配拧所以不是我用以下行。围着它

A['Time, (sec)'] = A['Time, (sec)'].round(4) 

和它的工作就像一个魅力是否有任何问题做这样的