我在pandas中有两个DataFrame,尝试合并它们。但是熊猫不断改变秩序。我已经尝试设置索引,重置它们,无论我做什么,我都无法获得返回的输出以使行具有相同的顺序。有诀窍吗? 请注意,我们从贷款订单'a,b,c'开始,但合并后,它是“a,c,b”。
import pandas
loans = [ 'a', 'b', 'c' ]
states = [ 'OR', 'CA', 'OR' ]
x = pandas.DataFrame({ 'loan' : loans, 'state' : states })
y = pandas.DataFrame({ 'state' : [ 'CA', 'OR' ], 'value' : [ 1, 2]})
z = x.merge(y, how='left', on='state')
但现在订单不再是原来的'a,b,c'。有任何想法吗?我正在使用熊猫版本11。
答案 0 :(得分:16)
希望有人会提供更好的答案,但如果没有人这样做,这肯定会有效,所以......
Zeroth,我假设您不想最终按loan
排序,而是保留 {/ 1>}中的原始订单,可能是可能与x
列的顺序无关。 (否则,问题会更容易,而且不那么有趣。)
首先,您要求它根据连接键进行排序。正如the docs解释的那样,当你没有传递loan
参数时,这是默认值。
其次,如果不基于连接键进行排序,则行最终会组合在一起,这样从同一源行合并的两行最终会彼此相邻,这意味着你仍然会得到sort
,a
,c
。
您可以解决这个问题,方法是将行按照它们在原始b
中显示的顺序组合在一起,只需再次与x
合并(在任何一方,这并不重要),或者,如果您愿意,可以根据x
重新编制索引。像这样:
x
或者,您可以使用x.merge(x.merge(y, how='left', on='state', sort=False))
填充x-index,然后对其进行排序,如下所示:
reset_index
答案 1 :(得分:5)
Pandas v0.8.0引入了新的合并功能,需要考虑顺序 - ordered_merge
,因此您的解决方案现在就像:
z = pandas.ordered_merge(x, y, on='state')
答案 2 :(得分:3)
我发现合并和恢复顺序的最快方法 - 如果要合并“left” - 是在合并之前将原始订单作为列包含在左数据框中,然后使用它在合并后恢复订单:
import pandas
loans = [ 'a', 'b', 'c' ]
states = [ 'OR', 'CA', 'OR' ]
x = pandas.DataFrame({ 'loan' : loans, 'state' : states })
y = pandas.DataFrame({ 'state' : [ 'CA', 'OR' ], 'value' : [ 1, 2]})
import numpy as np
x["Order"] = np.arange(len(x))
z = x.merge(y, how='left', on='state').set_index("Order").ix[np.arange(len(x)), :]
此方法比排序更快。这是一个功能:
def mergeLeftInOrder(x, y, on=None):
x = x.copy()
x["Order"] = np.arange(len(x))
z = x.merge(y, how='left', on=on).set_index("Order").ix[np.arange(len(x)), :]
return z
答案 3 :(得分:0)
使用pd.merge_ordered()
,文档here。
例如,
z = pd.merge_ordered(x, y, how='left', on='state')
编辑:只是想指出此函数的默认行为是外部合并,与更常见的.merge()
答案 4 :(得分:0)
我可能有一个更简单的解决方案:
df_z = df_x.join(df_y.set_index('state'), on = 'state')
希望有帮助