Изоляция нескольких строк в фрейме данных Pandas на основе итеративных правил - PullRequest
0 голосов
/ 12 ноября 2019

Предположим, у меня есть фрейм данных в форме

  X Y
0 1 1
1 1 2
2 1 3
3 2 4
4 2 5
5 2 6
6 3 7
7 3 8
8 3 9

. Я хочу, чтобы мой новый фрейм данных был таким, чтобы для каждого уникального значения X, то есть 1, 2 и 3, я выделял строку, в которой Yна своем минимуме. Поэтому я хочу, чтобы мой последний DataFrame выглядел следующим образом:

  X Y
0 1 1
1 2 4
2 3 7

Я знаком с тем, как получить каждое уникальное значение X. Это будет df['X'].unique(). Поэтому мой наивный подход изначально заключался в простом выполнении:

X_list = []
for i in df['X'].unique():
    i_df = df.loc[df['X'] == i]
    X_list.append(i_df.loc[i_df['Y'].idxmin()])
new_df = pd.DataFrame(X_list)

Однако это вызывает проблемы, потому что индексы запутываются, если вы пытаетесь просто объединить эти изолированные строки, создав из них новый DataFrame. ,А именно, я получаю KeyError, предполагающую, что строки такого индекса не существует, если я пытаюсь получить доступ к этим строкам в новом DataFrame по их исходному индексу из старого DataFrame. Сначала я пытался решить эту проблему с помощью функции reset_index, но это тоже не сработало.

Поэтому я хотел бы знать, есть ли какой-нибудь чистый способ запросить это из исходного DataFrame или естьдополнение к моему решению, которое заставляет его работать так, как вы ожидаете от DataFrame, без странных проблем с индексацией. Я подозреваю, что, возможно, есть какой-то способ сделать это с помощью функции groupby, но я не могу придумать, как это сделать.

Ответы [ 3 ]

1 голос
/ 12 ноября 2019

Использование GroupBy.min:

df.groupby('X')['Y'].min().reset_index()
0 голосов
/ 12 ноября 2019

Вот то, что может работать. В вашем случае установите find_max=False.

import pandas
import operator

def filter_df(df=None, col=None, find_max=True):
    """
    Serializes one column by optimizing another.  Returns
    another dataframe.  Serialized column may not be sorted.
    """
    if not df or not col: pass
    if find_max: evaluate = operator.ge
    if not find_max: evaluate = operator.le
    d = {}
    for row in df.items:
        if row not in d.keys():
            d[row] = df.loc[row]
        elif evaluate(df.loc[row][col], d[row][col]):
            d[row] = df.loc[row]
    return pandas.DataFrame(d)
0 голосов
/ 12 ноября 2019

Вы правы, считая групповой подход подходом. df.groupby(['X']).min() Вы можете заменить min другими функциями агрегирования, такими как count, max, sum. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...