Python 熊猫如何维持秩序?

Python 熊猫如何维持秩序?,python,pandas,Python,Pandas,我在pandas中有两个数据帧,试图合并它们。但是熊猫一直在改变顺序。我尝试过设置索引,重置它们,无论我做什么,我都无法使返回的输出中的行具有相同的顺序。有把戏吗? 请注意,我们从贷款订单“a,b,c”开始,但合并后是“a,c,b” 但现在的顺序不再是原来的“a,b,c”。有什么想法吗?我正在使用pandas版本11。希望有人能提供更好的答案,但如果没有人这样做,这肯定会奏效,所以 第零,我假设您不希望只在贷款上排序,而是保留x中的原始顺序,这可能与贷款列的顺序有关,也可能与此无关。(否则,问题

我在pandas中有两个数据帧,试图合并它们。但是熊猫一直在改变顺序。我尝试过设置索引,重置它们,无论我做什么,我都无法使返回的输出中的行具有相同的顺序。有把戏吗? 请注意,我们从贷款订单“a,b,c”开始,但合并后是“a,c,b”


但现在的顺序不再是原来的“a,b,c”。有什么想法吗?我正在使用pandas版本11。

希望有人能提供更好的答案,但如果没有人这样做,这肯定会奏效,所以

第零,我假设您不希望只在
贷款
上排序,而是保留
x
中的原始顺序,这可能与
贷款
列的顺序有关,也可能与此无关。(否则,问题更容易,也不那么有趣。)

首先,您要求它根据连接键进行排序。如前所述,当您不传递
sort
参数时,这是默认设置


其次,如果不根据连接键进行排序,则行最终将分组在一起,这样从同一源行合并的两行将彼此相邻,这意味着您仍将得到
a
c
b

您可以通过将行按它们在原始
x
中的显示顺序分组来解决此问题,只需再次与
x
合并(在任何一侧,这都不重要),或者根据
x
重新编制索引(如果您愿意)。像这样:

x.merge(x.merge(y, how='left', on='state', sort=False))

或者,您可以使用
reset\u index
在其中填充一个x索引,然后对其进行排序,如下所示:

x.reset_index().merge(y, how='left', on='state', sort=False).sort('index')


无论哪种方式显然都有点浪费和笨拙……所以,正如我所说的,希望有一个更好的答案,而我目前还没有看到。但如果没有,那就行了。

我发现的合并和恢复顺序的最快方法——如果您合并的是“左”数据框,则在合并前将原始顺序作为列包含在左数据框中,然后在合并后使用该列恢复顺序:

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
Pandas有一个函数,因此您的解决方案现在非常简单:

z = pd.merge_ordered(x, y, on='state')
使用
pd.merge\u ordered()
,文档

以你为例,

z=pd.merge_顺序(x,y,how='left',on='state')


编辑:只是想指出此函数的默认行为是外部合并,不同于更常见的
的默认行为。merge()

我可能有一个更简单的解决方案:

df_z = df_x.join(df_y.set_index('state'), on = 'state')

希望它有帮助

首先,您需要传递
sort=False
,否则它将在join键上排序,这是您不想要的。但这还不足以解决问题;未排序的顺序仍然将来自同一源行的所有行组合在一起。一个简单的解决方法是执行
x.merge(x.merge(y,how='left',on='state',sort=False))
,它将
x
中的每一行与合并中相应的for合并,从而恢复
x
的原始顺序。但我希望有一个更好的解决方案正在我的脑海中闪现。@abarnert,我认为我们可以使用
.join()
.update()
,它们(出于某种原因)确实保持了秩序。是的,这似乎有效。看起来很浪费,但确实有效。谢谢。@韦斯·麦金尼:我还没有找到一个解释来解释为什么索引会被重新排序。这是相当令人沮丧的,因为我整个下午都在处理这个问题,认为这是我代码中的一个bug。任何解释都将不胜感激@谢谢。这是否也适用于非
合并?对于
pd.merge(x,y)
default是
sort=True
,但是对于
x.merge(y)
,缺省值是
sort=False
,而对于
x.merge(y)
,缺省值是
sort=False
,我需要的是sort\u index(),而不是.sort('index')在最新版本的Pandaseven中(稍微)更快、可读性更强:“def mergeLeftInOrder2(x,y,on=None):x=x.copy()x[“Order”]=np.arange(len(x))z=x.merge(y,how='left',on=on)。排序(“Order”)返回z.drop(“Order”,1)“``实际上我甚至不能再重新创建OP的问题了-在熊猫0.15.2上似乎不是问题,所以所有的时间问题似乎都没有意义。我想我也不得不使用.loc而不是.ix-疏忽。当我最初提出这个解决方案时(很久以前)我有一个不同版本的pandas,所以我想我会让它保持原样。我可以通过稍微更改输入来重新创建问题。请参见下文。这里的函数(mergeLeftInOrder)修复了它。import pandas loans=['a','b','c','d']state=['CA','IL','CA','或']x=pandas.DataFrame({'loan':loans loans,'state':state})数据帧({'state':['OR','CA'],'value':[1,2]})z=x.merge(y,how='left',on='state')不保留原始数据帧的顺序,但它只是对输出数据帧进行排序。如果
y
数据帧中的
state
是一种索引(或与数据库表等效的主键)您试图使用此索引将
添加到每个
贷款
,状态为
y
,则此解决方案是最合适的解决方案。是的,状态是唯一且存在的(键)对于我的示例中的df_y,顺序将与df_x相同,而不考虑df_y的顺序,这是用于时间序列的。
df_z = df_x.join(df_y.set_index('state'), on = 'state')