我正在尝试组合两组数据,但是我无法弄清楚哪个方法最合适(加入,合并,连接等)这个应用程序,并且文档没有没有任何例子可以做我需要做的事情。
我有两组数据,结构如下:
>>> 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
您会注意到它没有将行与共享的“时间”值组合在一起。
我也试过合并一个la 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)
,但结果没有合并。我只是得到了两个DataFrame的串联,如下所示:
>>> 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
我一直在搜索文档,并在这里尝试找出merge
和join
之间的确切差异,但从我收集的内容来看,它们非常相似。尽管如此,我还没有找到任何具体回答“如何合并共享相同键/索引的行”的问题。任何人都可以告诉我如何做到这一点?我只有几天的熊猫经验!
答案 0 :(得分:6)
<强> 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
答案 1 :(得分:2)
如果Time
列在两个DF中具有相同的dtype,它应该可以正常工作:
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
答案 2 :(得分:0)
找到解决方案 根据下面的建议,我必须在合并它们之前对“时间”列中的数字进行舍入,尽管事实上它们都是相同的dtype(float64)。建议是这样回合:
A = A.assign(A.Time = A.Time.round(4))
但在我的实际情况中,该列被标记为“时间,(秒)”(标点符号与作业相符。所以我使用以下行来围绕它:
A['Time, (sec)'] = A['Time, (sec)'].round(4)
它就像一个魅力。这样做有什么问题吗?