@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)
t = datetime.now()
df = generate_data()
df["value"] = df.groupby(['category', 'name'])\
.transform(lambda x: x.fillna(x.mean()))['value']
print(datetime.now()-t)
마지막 메모에서 모두는 아니지만 둘 이상의 열을 대치하려는 경우 더욱 일반화 할 수 있습니다.
df[['value', 'other_value']] = df.groupby(['category', 'name'])['value', 'other_value']\
.transform(lambda x: x.fillna(x.mean()))
groupby
섹션 에서 다룹니다 . 기억해야 할 것이 너무 많지만 "변환은 원래 프레임과 같이 인덱싱하려는 그룹 별 작업을위한 것입니다"등과 같은 규칙을 선택합니다.