pandas - python - 在pandas数据框中选择行时如何维护顺序?

我想按列表中给出的特定顺序选择行。例如

dataframe


a=[['car',1],['bike',3],['jewel',2],['tv',5],['phone',6]]



df=pd.DataFrame(a,columns=['items','quantity'])



>>> df


 items quantity


0 car 1


1 bike 3


2 jewel 2


3 tv 5


4 phone 6



我想用这个顺序['tv','car','phone'],第一行tv,然后是car,然后是phone。 我试过这个方法,但它并不维持顺序。


arr=['tv','car','phone']



df.loc[df['items'].isin(arr)]



 items quantity


0 car 1


3 tv 5


4 phone 6



时间:

下面是使用Index.get_indexer的非侵入性解决方案,它不涉及设置索引:


df.iloc[pd.Index(df['items']).get_indexer(['tv','car','phone'])]



 items quantity


3 tv 5


0 car 1


4 phone 6




df2 = df.set_index('items')


df2.loc[['tv','car','phone']] 



 quantity


items 


tv 5


car 1


phone 6



IIUC Categorical


df=df.loc[df['items'].isin(arr)]


df.iloc[pd.Categorical(df['items'],categories=arr,ordered=True).argsort()]


Out[157]: 


 items quantity


3 tv 5


0 car 1


4 phone 6



reindex :只有这样不会保存透明索引,如果原始索引有问题,你应该使用Categorical (如果在项目中,reindex将失败),


df.set_index('items').reindex(arr).reset_index()


Out[160]: 


 items quantity


0 tv 5


1 car 1


2 phone 6



或通过arr循环


pd.concat([df[df['items']==x] for x in arr])


Out[171]: 


 items quantity


3 tv 5


0 car 1


4 phone 6




(pd.DataFrame({'items':['tv','car','phone']})


 .merge(df, on='items')


)



输出:


 items quantity


0 tv 5


1 car 1


2 phone 6



我会从arr创建一个字典并将它mapitemsdropnasort_values


d = dict(zip(arr, range(len(arr))))



Out[684]: {'car': 1, 'phone': 2, 'tv': 0}



df.loc[df['items'].map(d).dropna().sort_values().index]



Out[693]:


 items quantity


3 tv 5


0 car 1


4 phone 6



这是另一个使用.loc的变种。


# Move items to the index, select, then reset.


df.set_index("items").loc[arr].reset_index()



不改变索引的另一个方法。


df.loc[df.reset_index().set_index("items").loc[arr]["index"]]



对于输入df中存在的所有要选择的项目,这个是经过搜索排序的项目,并且应该表现出色-,


In [43]: sidx = df['items'].argsort()



In [44]: df.iloc[sidx[df['items'].searchsorted(['tv','car','phone'],sorter=sidx)]]


Out[44]: 


 items quantity


3 tv 5


0 car 1


4 phone 6




>>> df.iloc[df.loc[df['items'].isin(arr), 'items'].apply(arr.index).sort_values().index]


 items quantity


3 tv 5


0 car 1


4 phone 6


>>> 



为什么不搜索索引,过滤器并重新排序:


df['new_order'] = df['items'].apply(lambda x: arr.index(x) if x in arr else -1)



df_new = df[df['new_order']>=0].sort_values('new_order')



 items quantity new_order


3 tv 5 0


0 car 1 1


4 phone 6 2




...