Skip to content

Instantly share code, notes, and snippets.

@DevStarSJ
Last active March 8, 2018 08:01
Show Gist options
  • Save DevStarSJ/0c4064b6ce73d1d32426e74a5524219d to your computer and use it in GitHub Desktop.
Save DevStarSJ/0c4064b6ce73d1d32426e74a5524219d to your computer and use it in GitHub Desktop.
"""
index : (group, id) 이며 group : id 는 1 : m
value : 0 ~ 1 사이의 값이며 group 내에서 각 객체 간의 상대적인 비율값
- id의 value가 1 이면 group 내에서 가장 큰 값
- id의 value가 0.5이면 group내에서 가장 큰 값의 0.5배에 해당하는 값
value에 nan 값이 있는데 이것에 적절한 값을 넣어야 함. 그냥 삭제처리 할 경우 전체적인 데이터가 원하는데로 안나옴
rate에는 nan 값이 없으며 group 내에서 0 ~ 1 사이에 값을 가짐. value와는 다른 기준으로 작성된 데이터
value에 nan인 것에 대해서는 그 앞 뒤의 value의 비율만큼의 rate 값의 비율을 이용해서 채워넣을 전략
새로만든 value는 데이터 검증을 위해서 value_new로 저장
------------------
7만개 정도의 row를 한번 돌리는데 2 ~ 3시간이 걸림
.loc[(df['group'] == group_id) & ... 등으로 df를 검색하는 것에서 큰 시간이 걸리는 것으로 예상됨
혹시 더 빠르게 적용할 수 있는 방법이 있을까 ?
group내에서의 연산은 group 안의 row에 있는 값만으로 계산이 가능
값을 대입하는 곳을 df subset을 만들어놓고 원래 df에 저장할 수 있는 기능이 있다면 best 일거라 생각됨.
그게 안되면 계산 중간값으로 저장하는 scalar값에라도 df subset을 이용해서 검색 시간을 줄이는게 의미가 있을지...
"""
for group_id in groups_need_change:
# value 값이 모두 nan이면 rate로 설정
if df.loc[(df['group']== group_id) & ~np.isnan(df['value'])].shape[0] == 0:
df['value_new'].loc[df['group'] == group_id] = df['rate']
continue
for a, b in df.loc[(df['group'] == group_id) & np.isnan(df['value'])].iterrows():
rate = b['rate']
id = b['id']
# 같은 rate이면서 value에 값이 있는 row가 존재한다면 그 값들의 평균으로 설정
value_of_same_rate = df['rate'].loc[(df['group'] == group_id) & ~np.isnan(df['value']) & (df['rate'] == rate)].mean()
if ~np.isnan(value_of_same_rate):
df['value_new'].loc[(df['group'] == group_id) & (df['id'] == id)] = value_of_same_rate
continue
before_rate = df['rate'].loc[(df['group'] == group_id) & (df['rate'] < rate)].max()
next_rate = df['rate'].loc[(df['group'] == group_id) & (df['rate'] > rate)].min()
# 구해야할 value의 rate == 1 인 경우 : 바로 앞의 비율의 역수로 설정
if np.isnan(next_rate):
df['value_new'].loc[(df['group'] == group_id) & (df['id'] == id)] = \
1 / df['value'].loc[(df['group'] == group_id)& ~np.isnan(df['value']) & (df['rate'] == before_rate)].mean()
else:
# 구해야할 value 앞뒤로 value에 값이 있는 id들이 존재할 경우 : rate와의 비율만큼 value의 상대 비율로 설정
before_value = df['value'].loc[(df['group'] == group_id)& ~np.isnan(df['value']) & (df['rate'] == before_rate)].mean()
gap_value = df['value'].loc[(df['group'] == group_id)& ~np.isnan(df['value']) & (df['rate'] == next_rate)].mean() - before_value
gap_rate = next_rate - before_rate
gap_before_rate = rate - before_rate
new_gap_from_before_value = gap_value * gap_before_rate / gap_rate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment