заменить нулевые значения с помощью функции - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть фрейм данных, похожий на этот:

import pandas as pd
import numpy as np

d = {'category': [1, 1, 2, 1, 3, 2], 'cost': [33, 33, 18, np.nan, 8, np.nan]}
df = pd.DataFrame(data=d)

 category cost
0   1   33.0
1   1   33.0
2   2   18.0
3   1   NaN
4   3   8.0
5   2   NaN

Я хотел бы заменить NaN в столбце стоимости на основе медианы, сгруппированной по категориям (df[['cost', 'category']].groupby(['category']).median()).Таким образом, в примере первый NaN (строка 3) будет заменен на 33, а второй (строка 5) будет заменен на 18.

Так что сделайте что-то вроде этого:

df['field'] = df.apply(lambda row: get_median(row), axis=1)

Нотолько для значений nan

Ответы [ 3 ]

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

Вот возможный подход,

In [82]: df
Out[82]:
   category  cost
0         1  33.0
1         1  33.0
2         2  18.0
3         1   NaN
4         3   8.0
5         2   NaN

In [83]: df.groupby('category').apply(lambda x: x.cost.fillna(x.cost.median())).reset_index(level=0)
Out[83]:
   category  cost
0         1  33.0
1         1  33.0
3         1  33.0
2         2  18.0
5         2  18.0
4         3   8.0
0 голосов
/ 06 декабря 2018

Настройка

df.set_index('category', inplace=True)

Series.update

df.cost.update(df.groupby('category').cost.median())
df

          cost
category      
1         33.0
1         33.0
2         18.0
1         33.0
3          8.0

Series.combine_first

df['cost'] = (
   df.cost.combine_first(df.groupby('category').cost.median()))
df

          cost
category      
1         33.0
1         33.0
2         18.0
1         33.0
3          8.0

Сдела говорят громче слов:

a = np.random.randint(1, 1000, 100000)
b = np.random.choice((1, 2, 3, np.nan), 100000)
df = pd.DataFrame({'category': a, 'cost': b})

%%timeit 
(df.groupby('category')
   .apply(lambda x: x.cost.fillna(x.cost.median()))
   .reset_index(level=0))

%%timeit
df2 = df.set_index('category')
df2.cost.update(df.groupby('category').cost.median())
df2.reset_index()

%%timeit
df2 = df.set_index('category')
df2['cost'] = (
   df.cost.combine_first(df.groupby('category').cost.median()))
df2.reset_index()

664 ms ± 24.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
10 ms ± 107 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
17.1 ms ± 305 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
0 голосов
/ 06 декабря 2018

Вот один из подходов.

df = df.replace(np.nan, df.groupby("category").transform("median"))

Вы можете передать Series в качестве второго аргумента replace.Используя groupby + transform, мы можем убедиться, что медианы группы выровнены с соответствующими строками группы.

   category  cost
0         1  33.0
1         1  33.0
2         2  18.0
3         1  33.0
4         3   8.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...