#python #r #pandas #dataframe
Вопрос:
Я знаю, что панды обеспечивают:
.ix
— смешанная индексация меток и позиций (в первую очередь меток), если индекс является целочисленным — он будет интерпретироваться как метка.loc
— явная индексация по метке.iloc
— явная индексация по позициям
Это круто.
Каков был бы правильный способ индексировать столбцы по метке (ala .loc
) и строки по позиции (ala .iloc
) за один раз, чтобы избежать цепного назначения? Желательно, чтобы этого избегали reset_index()
.
Чтобы привести пример, предположим, что следующий кадр данных df
:
col1 col2 col3 3 1 4 2 2 2 3 3 4 3 2 1 1 4 1 4
Есть ли у панд что-то подобное some_indexer
, что ведет себя следующим образом?
In[2]: df.some_indexer[2,'col2':'col3'] Out[2]: col2 2 col3 1 Name: 4, dtype: object
Спасибо!
Комментарии:
1. Это не сработает , потому что у вас неоднозначный индекс, поэтому, например, это не делает то, что вы хотите:
df.ix[2, 'col2':'col3']
, вы могли бы сделать только этоdf.iloc[2]['col2','col3']
, но это цепная индексация, если бы ваш индекс был переиндексирован, поэтому, начиная с0
или str, тогдаdf.ix[2, 'col2':'col3']
это сработало бы2. @MaximHaytovich операция запрашивает i-ю строку, в данном случае 2, а затем только этот диапазон столбцов, поэтому в данном случае это будет 3-я строка, так как это строка(2), поскольку индексы основаны на 0
3. @EdChum
df.ix[2, 'col2':'col3']
не «потерпел бы неудачу», он просто не вернул бы то, что я хочу 🙂 Покаreset_index()
что это кажется наиболее разумным.4. Я обновил свой комментарий, но вы поняли мою точку зрения о неоднозначном поведении, я могу опубликовать ответ, чтобы показать, как это может сработать
Ответ №1:
Я знаю, что это старый вопрос, но это действительно можно сделать без цепной индексации или использования reset_index()
. Вам просто нужно использовать df.index[2]
внутри .loc
индексатора.
df.loc[df.index[2],'col2':'col3']
Это также будет корректно работать с заданиями.
Ответ №2:
Обычно мы бы так и сделали df.ix[2, 'col2':'col3']
, но поскольку ваш индекс неоднозначен, вы получаете 2-ю, а не 3-ю строку, 2
которая отображается в качестве значения в индексе в позиции 1, поэтому выбор метки завершается успешно, ix
сначала выполняется выбор метки, а затем выбор позиции.
Из документов:
.ix поддерживает смешанный доступ на основе целых чисел и меток. В основном он основан на метках, но будет возвращен к целочисленному позиционному доступу, если только соответствующая ось не имеет целочисленного типа. .ix является наиболее общим и будет поддерживать любые входные данные в .loc и .iloc. .ix также поддерживает схемы меток с плавающей запятой. .ix исключительно полезен при работе со смешанными иерархическими индексами на основе позиций и меток.
In [246]: df.ix[2,'col2':'col3'] Out[246]: col2 3 col3 3 Name: 2, dtype: int64
Следующее будет работать, но это цепной вызов, и назначения, скорее всего, будут работать с копией и выдадут предупреждение:
In [247]: df.iloc[2][['col2','col3']] Out[247]: col2 2 col3 1 Name: 4, dtype: int64
Проще всего было бы сбросить индекс , а затем вы можете позвонить ix
, нам нужно снова сбросить индекс, так как он вставлен в виде столбца:
In [250]: df = df.reset_index().drop('index',axis=1) df Out[250]: col1 col2 col3 0 1 4 2 1 2 3 3 2 3 2 1 3 4 1 4 In [251]: df.ix[2,'col2':'col3'] Out[251]: col2 2 col3 1 Name: 2, dtype: int64
Комментарии:
1. Согласованный. Было интересно, можно ли это сделать без
reset_index()
посторонней помощи .2. Вы можете переназначить индекс, который будет меньше печатать, например
df.index = np.arange(len(df))
3. Кроме того, цепной вызов завершится ошибкой при назначении [‘a’,’b’], например. Т. е. он будет назначен копии.