在熊猫数据框中选择行时如何保持顺序?

时间:2019-06-19 00:48:10

标签: python pandas

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

此数据框

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']获取行,即第一行电视,然后是汽车,然后打电话。我尝试了这种方法,但是它不能保持顺序

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

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

   items  quantity
0    car         1
3     tv         5
4  phone         6

8 个答案:

答案 0 :(得分:10)

这是一个使用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

答案 1 :(得分: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(由Andy L提及,如果项中有重复项, 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

答案 2 :(得分:3)

merge进行救援:

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

输出:

   items  quantity
0     tv         5
1    car         1
2  phone         6

答案 3 :(得分:3)

对于输入df中存在的所有要选择的项目,这里是searchsorted的项目,应该表现出色-

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

答案 4 :(得分:2)

这是另一个使用.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"]]

答案 5 :(得分:2)

我将从arrmapitemsdropnasort_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

答案 6 :(得分:0)

为什么不呢?

>>> 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
>>> 

答案 7 :(得分:0)

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

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