2016-11-24 2 views
3

데이터 프레임이 df1, df2, df3 인 데이터 프레임이 3 개 있습니다. 나는 NaN 값을 df2에 포함 된 값으로 df1으로 채우려고합니다. df2에서 선택된 값은 df3에 저장된 일부 데이터를 처리하는 간단한 함수 (mul_val)의 출력에 따라 선택됩니다.다른 데이터 프레임의 데이터 프레임 값을 팬더로 바꾸기

나는 그런 결과를 얻을 수 있었지만 더 간단하고 쉬운 방법으로 더 읽기 쉬운 코드를 찾고 싶습니다. 여기

내가 지금까지 무엇을 가지고 : 모든 반복에 store_val를 인쇄하여

import pandas as pd 
import numpy as np 

# simple function 
def mul_val(a,b): 
    return a*b 

# dataframe 1 
data = {'Name':['PINO','PALO','TNCO' ,'TNTO','CUCO' ,'FIGO','ONGF','LABO'], 
     'Id' :[ 10 , 9 ,np.nan , 14 , 3 ,np.nan, 7 ,np.nan]} 
df1 = pd.DataFrame(data) 

# dataframe 2 
infos = {'Info_a':[10,20,30,40,70,80,90,50,60,80,40,50,20,30,15,11], 
     'Info_b':[10,30,30,60,10,85,99,50,70,20,30,50,20,40,16,17]} 
df2 = pd.DataFrame(infos) 

dic = {'Name': {0: 'FIGO', 1: 'TNCO'}, 
     'index': {0: [5, 6], 1: [11, 12, 13]}} 
df3 = pd.DataFrame(dic) 

#---------------Modify from here in the most efficient way!----------------- 

for idx,row in df3.iterrows(): 
    store_val = [] 
    print(row['Name']) 
    for j in row['index']: 
     store_val.append([mul_val(df2['Info_a'][j],df2['Info_b'][j]),j]) 
    store_val = np.asarray(store_val) 

    # - Identify which is the index of minimum value of the first column 
    indx_min_val = np.argmin(store_val[:,0]) 

    # - Get the value relative number contained in the second column 
    col_value = row['index'][indx_min_val] 

    # Identify value to be replaced in df1 
    value_to_be_replaced = df1['Id'][df1['Name']==row['Name']] 

    # - Replace such value into the df1 having the same row['Name'] 
    df1['Id'].replace(to_replace=value_to_be_replaced,value=col_value, inplace=True) 

은 내가 얻을 :

FIGO 
[[6800 5] 
[8910 6]] 
TNCO 
[[2500 11] 
[ 400 12] 
[1200 13]] 

는 간단한 예제를하자 : FIGO을 고려, 나는 최소한 6800를 식별 68008910 사이의 숫자입니다. 그러므로 나는 5 번호를 선택하여 df1에 배치합니다. (이 경우에 나는 단지 2 행을 가지고 있지만 그들은 더 많은 수) df3의 나머지 행에 대해 같은 작업을 반복, 최종 결과는 다음과 같이해야합니다 :

In[0]: before   In[0]: after 
Out[0]:     Out[0]: 
    Id Name    Id Name 
0 10.0 PINO   0 10.0 PINO 
1 9.0 PALO   1 9.0 PALO 
2 NaN TNCO -----> 2 12.0 TNCO 
3 14.0 TNTO   3 14.0 TNTO 
4 3.0 CUCO   4 3.0 CUCO 
5 NaN FIGO -----> 5 5.0 FIGO 
6 7.0 ONGF   6 7.0 ONGF 
7 NaN LABO   7 NaN LABO 

NORE : 당신은 또한 위해를 제거 할 수 있습니다 필요할 경우 반복하고 데이터를 저장하는 다양한 유형의 형식을 사용합니다 (목록, 배열 ...). 중요한 것은 최종 결과가 여전히 데이터 프레임이라는 것입니다.

답변

1
내가 몇 줄의 루프보다 동일한 결과를 달성 두 개의 유사한 옵션을 제공 할 수 있습니다

:

: 적용

1.Using 및 fillna() (fillna 두 가지의 요인에 의해 combine_first보다 빠르다)

df3['Id'] = df3.apply(lambda row: (df2.Info_a*df2.Info_b).loc[row['index']].argmin(), axis=1) 
    df1 = df1.set_index('Name').fillna(df3.set_index('Name')).reset_index() 

(당신이 FUNC를 적용해야하므로 람다, 할당을 지원하지 않습니다)

def f(row): 
    df1.ix[df1.Name==row['Name'], 'Id'] = (df2.Info_a*df2.Info_b).loc[row['index']].argmin() 
df3.apply(f, axis=1) 

또는 약간의 VARI을하는 기능을 2.Using 개미 글로벌 정의에 의존하지 : 솔루션은, 심지어 훨씬 더 자세한하지만, (내 모두 9.5 MS에 비해 7.5 밀리 초)이 작은 데이터 세트와 최소한의 시간이 걸릴 것입니다

def f(row, df1, df2): 
    df1.ix[df1.Name==row['Name'], 'Id'] = (df2.Info_a*df2.Info_b).loc[row['index']].argmin() 
df3.apply(f, args=(df1,df2,), axis=1) 

참고. 두 경우 모두 행의 반복 문제이므로 df3

의 속도가 유사 할 것입니다.
관련 문제