Skip to content

Instantly share code, notes, and snippets.

@haje01
Last active March 8, 2018 04:25
Show Gist options
  • Save haje01/00711b0e0604332ad2c2afd1c49a487c to your computer and use it in GitHub Desktop.
Save haje01/00711b0e0604332ad2c2afd1c49a487c to your computer and use it in GitHub Desktop.
Pandas 예제
def do_group(gdf):
"""각 그룹별 처리."""
# 대상 그룹이 아니면 그대로
if gdf.group.iloc[0] not in groups_need_change:
return gdf
# value가 없는 인덱스
nidx = gdf.value.isna()
# value가 있는 인덱스
pidx = ~nidx
# 모든 value가 있으면 그대로
if pidx.all():
return gdf
# 모든 value가 nan이면 rate로 설정
elif nidx.all():
gdf['value_new'] = gdf['rate']
return gdf
# value가 없는 행의 rate들
nrates = gdf[nidx].rate.unique()
# rate 별 value 평균
rate_meanv = gdf.groupby('rate').value.mean()
# value가 없는 행의 rate과 같고 value가 있는 행의 인덱스
psrate_idx = gdf.rate.isin(nrates) & pidx
# psrate 행의 rate들
psrates = gdf[psrate_idx].rate.unique()
# value가 없는 행들 중 psrate이 존재하는 행의 인덱스
srval_idx = gdf[nidx].rate.isin(psrates) & nidx
# 그들에 대해 rate이 같은 행들의 평균 value 설정
gdf.loc[srval_idx, 'value_new'] = gdf[srval_idx].rate.map(rate_meanv)
# 유니크하고 소팅된 rate 들
rates = sorted(gdf.rate.unique())
def before_rate(rate, rates):
bidx = rates.index(rate) - 1
return rates[bidx] if bidx >= 0 else np.NaN
def after_rate(rate, rates):
aidx = rates.index(rate) + 1
return rates[aidx] if len(rates) > aidx else np.NaN
# value가 없는 행의 rate보다 다음으로 작은 rate
gdf.loc[nidx, 'brate'] = gdf[nidx].rate.apply(before_rate,
args=(rates,))
# value가 없는 행의 rate보다 다음으로 큰 rate
gdf.loc[nidx, 'arate'] = gdf[nidx].rate.apply(after_rate,
args=(rates,))
# value가 없는 행들 중 srval이 없고 다음으로 큰 rate도 없는 행의 인덱스
narate_idx = nidx & ~srval_idx & gdf.arate.isna()
# 에 대해 다음으로 작은 rate을 갖는 행의 value의 평균의 역으로 설정
gdf.loc[narate_idx, 'value_new'] = \
1 / gdf[narate_idx].brate.map(rate_meanv)
# 다음 큰 rate이 있는 경우는 구현이 되어있지 않아 생략
return gdf
# 그룹별 처리
df = df.groupby('group').apply(do_group)
# 임시 컬럼 제거
df = df.drop(['arate', 'brate'], axis=1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment