Выберите конкретную строку и столбец, напрямую проиндексировав данные - PullRequest
0 голосов
/ 19 декабря 2018
d = {'col1': [33,34,35], 'col2': [5,6,8], 'col3': [7,8,9]}
df = pd.DataFrame(data=d)
df[['col1','col3']].head()

С кодом выше, я могу выбрать col1 и col3, но если я хочу выбрать только строку 1 и строку 3 (со значением [33,35] и [7,9]) без использованиялюбая функция (например, loc, iloc, at, iat и т. д.) - просто использование индексации на фрейме данных, например, df[..,..], есть ли способ достичь этого?

Ответы [ 4 ]

0 голосов
/ 21 декабря 2018

Как уже отмечалось, есть несколько подходов к этому.Необходимо учитывать два момента: что имеет смысл с точки зрения читабельности / Pythonic / Idiomatic и что имеет смысл с точки зрения производительности.Мои возможные решения не соответствуют полной спецификации OP, чтобы избежать функций, но я предложу их для рассмотрения и сравнения.

Давайте рассмотрим три подхода и рассмотрим их с обеих точек зрения.

ВВ этом случае, чтобы помочь нам более четко увидеть некоторые аспекты производительности путем синхронизации выполнения кода, мы увеличили размер DataFrame, повторив сохраненные значения в 100 000 раз.

import pandas as pd
df = pd.DataFrame({'col1':[32, 33, 34] * 100000,
                   'col2':[1, 2, 3] * 100000,
                   'col3':[1, 2, 3] * 100000,
                  })

ПОДХОД 1

В этом подходе используется процесс, описанный @ U9-Forward, то есть индексирование по столбцам, транспонирование строк и столбцов, чтобы вы могли затем индексировать нужные строки и транспонировать DataFrame обратно в исходную ориентацию.

Используя %timeit в Jupyter, мы видим, сколько времени занимает обработка этого подхода:

[1]: %timeit df[['col1', 'col3']].T[[0, 2]].T
     3.02 ms ± 16.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

ПОДХОД 2

Этот подход создаетМаска на основе списка желаемых строк и индекса и фильтрует DataFrame на основе этой маски, а затем выбирает только желаемый столбецнс.Это имеет некоторое сходство с подходом @ jpp, но не использует .loc.

Аналогично, используя %timeit ... мы видим, что этот подход занимает вдвое меньше, чем подход 1.

[2]: %timeit df[df.index.isin([0, 2])][['col1', 'col3']]
     1.61 ms ± 31.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

ПОДХОД 3

Третий подход использует метод .take() для выбора определенных строк в DataFrame, а затем индексации для нужных столбцов.

СноваИспользуя %timeit, мы видим, что этот подход в втрое быстрее , чем в подходе 2, и в шесть раз быстрее , чем в подходе 1.

[1]: %timeit df.take([0, 2])[['col1','col3']]
     507 µs ± 5.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

ЭтоТакже можно утверждать, что этот подход потенциально легче читать, чем первые два подхода.

0 голосов
/ 19 декабря 2018

Будет ли это удовлетворить то, что вы ищете?:

df[['col1','col3']][::2]

Здесь я воспользовался тем, что заданные вами индексы строк (0 и 2) могут быть выражены в виде среза.Для произвольного набора индексов строк, тем не менее, может быть невозможно сделать его простым

0 голосов
/ 19 декабря 2018

Использование iloc или loc

Вы хотите объединить целочисленное позиционное индексирование с на основе меток индексация.Это часто громоздко, но здесь вы можете использовать тот факт, что iloc поддерживает целочисленную позиционную и индексацию логического массива:

d = {'col1': [33,34,35], 'col2': [5,6,8], 'col3': [7,8,9]}
df = pd.DataFrame(data=d)

res = df.iloc[[0, 2], df.columns.isin(['col1', 'col3'])]

print(res)

   col1  col3
0    33     7
2    35     9

Индексирование в Python начинается с 0, поэтому первыйи третьи строки представлены [0, 2].

Альтернативой является использование loc с логическим индексированием для строк:

res = df.loc[df.index.isin([0, 2]), ['col1', 'col3']]

Поскольку обычно число строк превышаетЧисло столбцов, а также потому, что целочисленная позиционная индексация, естественно, более эффективна, чем на основе меток, вы можете предпочесть iloc, чем loc.

0 голосов
/ 19 декабря 2018

Использовать индексирование, индексировать второй элемент по 1, использовать 1, так как индексирование в python начинается с 0:

print(df['col1'][1])

Обновление получить столбцы транспонировать данные-кадр, затем получить столбцы 0 и 2, после транспонирования, затем транспонировать обратно:

print(df[['col1','col3']].T[[0,2]].T)

Или:

print(df[df.index.isin([0,2])][['col1','col3']])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...