社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何在python中用mean(基于类别的mean)替换nan值[duplicate]

Raj • 5 年前 • 2106 次点击  

这应该很简单,但我发现最接近的是这篇文章: pandas: Filling missing values within a group ,我仍然无法解决我的问题…

假设我有以下数据帧

df = pd.DataFrame({'value': [1, np.nan, np.nan, 2, 3, 1, 3, np.nan, 3], 'name': ['A','A', 'B','B','B','B', 'C','C','C']})

  name  value
0    A      1
1    A    NaN
2    B    NaN
3    B      2
4    B      3
5    B      1
6    C      3
7    C    NaN
8    C      3

我想在“nan”中填入每个“name”组的平均值,即

      name  value
0    A      1
1    A      1
2    B      2
3    B      2
4    B      3
5    B      1
6    C      3
7    C      3
8    C      3

我不知道该去哪里:

grouped = df.groupby('name').mean()

多谢。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/42973
 
2106 次点击  
文章 [ 8 ]  |  最新文章 5 年前
keith singleton
Reply   •   1 楼
keith singleton    7 年前

我刚做了这个

df.fillna(df.mean(), inplace=True)

数据框中所有缺少的值都将平均填充。如果这就是你要找的。这对我有效。很简单,就能完成任务。

Paul Roub Prateek Deshmukh
Reply   •   2 楼
Paul Roub Prateek Deshmukh    6 年前
df.fillna(df.groupby(['name'], as_index=False).mean(), inplace=True)
Prajit Patil
Reply   •   3 楼
Prajit Patil    9 年前
def groupMeanValue(group):
    group['value'] = group['value'].fillna(group['value'].mean())
    return group

dft = df.groupby("name").transform(groupMeanValue)
Philipp Schwarz
Reply   •   4 楼
Philipp Schwarz    8 年前

特色的高排名答案只适用于只有两列的熊猫数据框。如果有更多列的情况,请使用:

df['Crude_Birth_rate'] = df.groupby("continent").Crude_Birth_rate.transform(
    lambda x: x.fillna(x.mean()))
jpp
Reply   •   5 楼
jpp    6 年前

fillna + groupby + transform + mean

这似乎很直观:

df['value'] = df['value'].fillna(df.groupby('name')['value'].transform('mean'))

这个 子句 + 转型 语法将GroupWise平均值映射到原始数据帧的索引。这大致相当于 @DSM's solution ,但不需要定义匿名 lambda 功能。

IanS WeNYoBen
Reply   •   6 楼
IanS WeNYoBen    7 年前

我会这样做的

df.loc[df.value.isnull(), 'value'] = df.groupby('group').value.transform('mean')
André C. Andersen
Reply   •   7 楼
André C. Andersen    7 年前

@DSM让IMO给出了正确的答案,但我想分享我对这个问题的概括和优化:要分组的多个列以及具有多个值列:

df = pd.DataFrame(
    {
        'category': ['X', 'X', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
        'name': ['A','A', 'B','B','B','B', 'C','C','C'],
        'other_value': [10, np.nan, np.nan, 20, 30, 10, 30, np.nan, 30],
        'value': [1, np.nan, np.nan, 2, 3, 1, 3, np.nan, 3],
    }
)

…给予。。。

  category name  other_value value
0        X    A         10.0   1.0
1        X    A          NaN   NaN
2        X    B          NaN   NaN
3        X    B         20.0   2.0
4        X    B         30.0   3.0
5        X    B         10.0   1.0
6        Y    C         30.0   3.0
7        Y    C          NaN   NaN
8        Y    C         30.0   3.0

在一般情况下,我们希望 category name ,并且仅在 value .

解决方法如下:

df['value'] = df.groupby(['category', 'name'])['value']\
    .transform(lambda x: x.fillna(x.mean()))

注意group by子句中的列列表,我们选择 价值 列在“分组依据”之后。这使得转换只能在该特定列上运行。您可以将它添加到末尾,但随后您将对所有列运行它,只会在末尾抛出除一个度量值列以外的所有列。一个标准的sql查询规划器可能已经能够优化这一点,但是pandas(0.19.2)似乎没有做到这一点。

通过增加数据集进行性能测试…

big_df = None
for _ in range(10000):
    if big_df is None:
        big_df = df.copy()
    else:
        big_df = pd.concat([big_df, df])
df = big_df

…确认这会增加速度,速度与不需要计算的列数成正比:

import pandas as pd
from datetime import datetime

def generate_data():
    ...

t = datetime.now()
df = generate_data()
df['value'] = df.groupby(['category', 'name'])['value']\
    .transform(lambda x: x.fillna(x.mean()))
print(datetime.now()-t)

# 0:00:00.016012

t = datetime.now()
df = generate_data()
df["value"] = df.groupby(['category', 'name'])\
    .transform(lambda x: x.fillna(x.mean()))['value']
print(datetime.now()-t)

# 0:00:00.030022

最后一点,如果你想计算多个列,但不是所有列,你可以进一步概括:

df[['value', 'other_value']] = df.groupby(['category', 'name'])['value', 'other_value']\
    .transform(lambda x: x.fillna(x.mean()))
DSM
Reply   •   8 楼
DSM    11 年前

一种方法是 transform :

>>> df
  name  value
0    A      1
1    A    NaN
2    B    NaN
3    B      2
4    B      3
5    B      1
6    C      3
7    C    NaN
8    C      3
>>> df["value"] = df.groupby("name").transform(lambda x: x.fillna(x.mean()))
>>> df
  name  value
0    A      1
1    A      1
2    B      2
3    B      2
4    B      3
5    B      1
6    C      3
7    C      3
8    C      3