我想按列表中给定的特定顺序选择行。例如
此数据框
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
答案 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)
我将从arr
和map
到items
和dropna
,sort_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