Как мне правильно приписать эти значения NaN режимам другого столбца?

Я учусь обрабатывать пропущенные значения в наборе данных. У меня есть таблица с ~ 1 миллионом записей. Я пытаюсь справиться с небольшим количеством пропущенных значений.

Мои данные касаются системы проката велосипедов, а недостающие значения — это начальное и конечное местоположения.

Данные: отсутствуют начальные станции, всего 7 значений

Как мне правильно приписать эти значения NaN режимам другого столбца?

Данные: отсутствует конечная станция, всего 24 значения

Как мне правильно приписать эти значения NaN режимам другого столбца?

Хочу заполнить NaN в обоих случаях режимом "встречной" станции. Например, для start_station==21 я хочу увидеть, что является наиболее распространенным end_station, и использовать это, чтобы заполнить мое отсутствующее значение. Например. df.loc[df['start_station'] == 21].end_station.mode()

Я попытался добиться этого с помощью функции:

def inpute_end_station(df):
    for index, row in df.iterrows():    
        if pd.isnull(df.loc[index, 'end_station']):

            start_st = df.loc[index, 'start_station']
            mode = df.loc[df['start_station'] == start_st].end_station.mode()
            df.loc[index, 'end_station'].fillna(mode, inplace=True)

В последней строке выбрасывается AttributeError: 'numpy.float64' object has no attribute 'fillna'. Если вместо этого я просто использую df.loc[index, 'end_station'] = mode, я получаю ValueError: Incompatible indexer with Series.

Правильно ли я подхожу к этому? Я понимаю, что изменять что-то, что вы повторяете, в пандах — плохая практика, так как же правильно изменить столбцы start_station и end_station и заменить NaN соответствующим режимом дополнительной станции?

Похоже на этот вопрос, заданный вчера: stackoverflow.com/questions/55562696/…. Должна быть возможность использовать ту же функцию (только с другими именами столбцов), а затем отображать результат.

ALollz 10.04.2019 03:06

@ALollz решение работает с вспомогательной функцией, но я получаю SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead. Это действительно лучший способ?

Bn.F76 10.04.2019 03:17

Эта ошибка, вероятно, не связана с этим и связана с предыдущей операцией среза, которая создала копию. Вы можете прочитать это для получения дополнительной информации в stackoverflow.com/questions/20625582/…, но временное исправление TLDR заключается в том, что вам, вероятно, следует просто выполнить df = df.copy() до того, какая строка кода выдаст это предупреждение. На самом деле вам следует зафиксировать операцию среза в другом месте, что, вероятно, потребует .copy() после некоторого шага маскирования или переписать код без цепочечного присваивания.

ALollz 10.04.2019 03:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
872
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На мой взгляд, когда вы хотите перебирать столбец в пандах, как это, лучше всего использовать функцию apply().

Для этого конкретного случая я бы предложил следующий подход, который показан ниже на моем образце данных. У меня нет большого опыта использования метода mode(), поэтому я использовал метод value_counts() в сочетании с методом first_valid_index() для определения значения моды.

# import pandas
import pandas as pd

# make a sample data
list_of_rows = [
  {'start_station': 1, 'end_station': 1},
  {'start_station': None, 'end_station': 1},
  {'start_station': 1, 'end_station': 2},
  {'start_station': 1, 'end_station': 3},
  {'start_station': 2, 'end_station': None},
  {'start_station': 2, 'end_station': 3},
  {'start_station': 2, 'end_station': 3},
]

# make a pandas data frame
df = pd.DataFrame(list_of_rows)

# define a function
def fill_NaNs_in_end_station(row):
    if pd.isnull(row['end_station']):
        start_station = row['start_station']
        return df[df['start_station']==start_station].end_station.value_counts().first_valid_index()
    return row['end_station']

# apply function to dataframe
df['end_station'] = df.apply(lambda row: fill_NaNs_in_end_station(row), axis=1)

Другие вопросы по теме