Панды: Как искать по списку значений и возвращать в том же порядке? - PullRequest
0 голосов
/ 29 ноября 2018

Простите, если это дурак, я искал все утро и только нашел кусочки пазлов и не смог собрать все вместе.

Мой квест:

Iесть простой DataFrame, где я хочу извлечь представление путем поиска list searches в том же порядке, что и list.Пример:

import pandas as pd
data = {k: [v+str(i) for i in range(10)] for k, v in zip(('OrderNo','Name', 'Useless','Description'),('1000','Product ', 'Junk ','Short Desc '))}
df = pd.DataFrame(data)
df.loc[2:6, ('Useless',)] = pd.np.nan
# to mock some nan data in my real one.

Результирующий df:

  OrderNo       Name Useless   Description
0   10000  Product 0  Junk 0  Short Desc 0
1   10001  Product 1  Junk 1  Short Desc 1
2   10002  Product 2     Nan  Short Desc 2
3   10003  Product 3     Nan  Short Desc 3
4   10004  Product 4     Nan  Short Desc 4
5   10005  Product 5     Nan  Short Desc 5
6   10006  Product 6     Nan  Short Desc 6
7   10007  Product 7  Junk 7  Short Desc 7
8   10008  Product 8  Junk 8  Short Desc 8
9   10009  Product 9  Junk 9  Short Desc 9

Теперь я хочу выполнить поиск по list из OrderNos следующим образом:

searches = ['10005','10009','10003','10000']

Я пытаюсь получить вид, подобный следующему:

  OrderNo       Name Useless   Description
5   10005  Product 5     Nan  Short Desc 5
9   10009  Product 9  Junk 9  Short Desc 9
3   10003  Product 3     Nan  Short Desc 3
0   10000  Product 0  Junk 0  Short Desc 0

Таким образом, я наконец-то могу перенести вид в это (заметьте, я опустил какой-то бесполезный столбец):

                        0             1             2             3
OrderNo             10005         10009         10003         10000
Name            Product 5     Product 9     Product 3     Product 0
Description  Short Desc 5  Short Desc 9  Short Desc 3  Short Desc 0

Что я пробовал:

Этот замечательный вопрос / ответ помог мне выполнить поиск по searches, но возвращенное представление не в моем порядке:

found = df.loc[df['OrderNo'].isin(searches)]

  OrderNo       Name Useless   Description
0   10000  Product 0  Junk 0  Short Desc 0
3   10003  Product 3     Nan  Short Desc 3
5   10005  Product 5     Nan  Short Desc 5
9   10009  Product 9  Junk 9  Short Desc 9

Я попытался добавить столбец ['my_sort'] к found, чтобы я мог изменить порядок на основе списка:

found['my_sort'] = found['OrderNo'].apply(lambda x: searches.index(x))
found.sort_values(by='my_sort', inplace=True)
# For now assume index will always be matched and ValueError will be handled.
# This detail is not critical

Пока это вроде работает, pandasбросает SettingWithCopyWarning повсюду, подсказывая мне использовать .loc[row_indexer,col_indexer] = ... вместо этого.Я тоже это попробовал, и это все еще выдает мне то же самое предупреждение.На самом деле кажется, что все, что я пытаюсь назначить под found, выдает то же самое, поэтому я подозревал, что проблема возникла в результате поиска.В итоге я обернул его как новый DataFrame, чтобы больше не видеть предупреждение:

found = pd.DataFrame(df.loc[df['OrderNo'].isin(searches)])
found['my_sort'] = found['OrderNo'].apply(lambda x: searches.index(x))
found = found[columns].T

Хотя это работает, я не могу помочь, но чувствую, что это очень запутанно и не очень эффективно, поскольку мне пришлосьввести новый столбец только для сортировки, а затем снова удалить.Я просмотрел несколько релевантных функций, таких как reindex или комбинацию из where и dropna (не работает, потому что в моих реальных данных есть другие nan объекты), но ни одна из них, похоже, не отвечает моей цели.

Есть ли лучший способ приблизиться к этому?

1 Ответ

0 голосов
/ 29 ноября 2018

set_index + loc + T

Вы можете использовать возможности индексации Pandas:

df = df.set_index('OrderNo')

searches = ['10005','10009','10003','10000']

df_search = df.loc[searches]

print(df_search)

          Description       Name Useless
OrderNo                                 
10005    Short Desc 5  Product 5     NaN
10009    Short Desc 9  Product 9  Junk 9
10003    Short Desc 3  Product 3     NaN
10000    Short Desc 0  Product 0  Junk 0

res = df_search.T

print(res)

OrderNo             10005         10009         10003         10000
Description  Short Desc 5  Short Desc 9  Short Desc 3  Short Desc 0
Name            Product 5     Product 9     Product 3     Product 0
Useless               NaN        Junk 9           NaN        Junk 0

Если вам требуются пронумерованные метки столбцов:

print(df_search.reset_index().T)

                        0             1             2             3
OrderNo             10005         10009         10003         10000
Description  Short Desc 5  Short Desc 9  Short Desc 3  Short Desc 0
Name            Product 5     Product 9     Product 3     Product 0
Useless               NaN        Junk 9           NaN        Junk 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...