이것은 간단해야하지만 내가 찾은 가장 가까운 것은이 게시물입니다 :
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 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()
무리 감사.
답변
한 가지 방법은 다음을 사용하는 것입니다 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
답변
답변
@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 절의 열 목록을 확인하고 value
바로 뒤에 열 . 이렇게하면 해당 특정 열에서만 변환이 실행됩니다. 끝에 추가 할 수 있지만 모든 열에 대해서만 실행하여 끝에 측정 열을 하나만 제외하고 모두 버립니다. 표준 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()))
답변
나는 이런 식으로 할거야
df.loc[df.value.isnull(), 'value'] = df.groupby('group').value.transform('mean')
답변
위 답변의 대부분은 누락 된 값을 채우기 위해 “groupby”및 “transform”을 사용하는 것과 관련이 있습니다.
그러나 나는 나에게 더 직관적 인 결 측값을 채우기 위해 “apply”와 함께 “groupby”를 사용하는 것을 선호합니다.
>>> df['value']=df.groupby('name')['value'].apply(lambda x:x.fillna(x.mean()))
>>> df.isnull().sum().sum()
0
지름길: Groupby + Apply / Lambda + Fillna + Mean
이 솔루션은 누락 된 값을 대체하기 위해 여러 열로 그룹화하려는 경우에도 작동합니다.
>>> df = pd.DataFrame({'value': [1, np.nan, np.nan, 2, 3, np.nan,np.nan, 4, 3],
'name': ['A','A', 'B','B','B','B', 'C','C','C'],'class':list('ppqqrrsss')})
>>> df
value name class
0 1.0 A p
1 NaN A p
2 NaN B q
3 2.0 B q
4 3.0 B r
5 NaN B r
6 NaN C s
7 4.0 C s
8 3.0 C s
>>> df['value']=df.groupby(['name','class'])['value'].apply(lambda x:x.fillna(x.mean()))
>>> df
value name class
0 1.0 A p
1 1.0 A p
2 2.0 B q
3 2.0 B q
4 3.0 B r
5 3.0 B r
6 3.5 C s
7 4.0 C s
8 3.0 C s
답변
추천 높은 순위 답변은 열이 두 개 뿐인 pandas Dataframe에서만 작동합니다. 더 많은 열이있는 경우 대신 사용하십시오.
df['Crude_Birth_rate'] = df.groupby("continent").Crude_Birth_rate.transform(
lambda x: x.fillna(x.mean()))
답변
def groupMeanValue(group):
group['value'] = group['value'].fillna(group['value'].mean())
return group
dft = df.groupby("name").transform(groupMeanValue)