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

Eka*_*Eka 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
Run Code Online (Sandbox Code Playgroud)

我想按此顺序获取行['tv','car','phone'],即第一行电视,然后是汽车,然后是电话。我尝试过这种方法,但不能维持秩序

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

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

   items  quantity
0    car         1
3     tv         5
4  phone         6
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 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
Run Code Online (Sandbox Code Playgroud)

请注意,如果这将成为常见的事情(按某种意思,我的意思是在列上使用列表进行“索引编制”),则最好不要将该列变成索引。如果对它进行排序,将获得加分。

df2 = df.set_index('items')
df2.loc[['tv','car','phone']]  

       quantity
items          
tv            5
car           1
phone         6
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 6

联合会 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

或通过循环 arr

pd.concat([df[df['items']==x] for x in arr])
Out[171]: 
   items  quantity
3     tv         5
0    car         1
4  phone         6
Run Code Online (Sandbox Code Playgroud)


Qua*_*ang 5

merge救援:

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

输出:

   items  quantity
0     tv         5
1    car         1
2  phone         6
Run Code Online (Sandbox Code Playgroud)