Last active
March 8, 2018 08:01
-
-
Save DevStarSJ/0c4064b6ce73d1d32426e74a5524219d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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