2017-04-10 6 views
1

DataFrame의 'ID'그룹에 적용된 기능으로 상당한 정리가 필요한 pandas DataFrame에 데이터가 있습니다. Pandas DataFrame 그룹을 조작하기 위해 임의의 함수를 어떻게 적용합니까? DataFrame의 간략화 된 예는 아래와 같다 :Python Pandas DataFrame 그룹을 조작하는 기능 적용

import pandas as pd 
import numpy as np 

waypoint_time_string = ['0.5&3.0&6.0' for x in range(10)] 
moving_string = ['0 0 0&0 0.1 0&1 1 1.2' for x in range(10)] 

df = pd.DataFrame({'ID':[1,1,1,1,1,2,2,2,2,2], 'time':[1,2,3,4,5,1,2,3,4,5], 
     'X':[0,0,0,0,0,1,1,1,1,1],'Y':[0,0,0,0,0,1,1,1,1,1],'Z':[0,0,0,0,0,1,1,1,1,1], 
     'waypoint_times':waypoint_time_string, 
     'moving':moving_string}) 
제가 df 각각 'ID'그룹 (아래 정의 됨) 함수 set_group_positions 적용하고자

. 나는 DataFrame을 통해서만 성공적으로 루핑했다. 이 작업을 수행하는 데있어 'Pandas.groupby'방법이 더 많이 필요합니다.

sub_frames = [] 
unique_IDs = df['ID'].unique() 
for unique_ID in unique_IDs: 
    working_df = df.loc[df['ID']==unique_ID] 
    working_df = set_group_positions(working_df) 
    sub_frames.append(working_df) 

final_df = pd.concat(sub_frames) 

그리고 작업 예제를 완료하려면, 여기에 추가 도우미 기능 : 여기에 내가 대체 할 찾고 있어요 내 구현의 예를 들어 내 현재의 구현에, 작동하지만

def set_x_vel(row): 
    return(row['X'] + row['x_movement']) 
def set_y_vel(row): 
    return(row['Y'] + row['y_movement']) 
def set_z_vel(row): 
    return(row['Z'] + row['z_movement']) 

output_time_list = df['time'].unique().tolist() 

#main function to apply to each ID group in the data frame: 
def set_group_positions(df): #pass the combined df here 
    working_df = df 
    times_string = working_df['waypoint_times'].iloc[0] 
    times_list = times_string.split('&') 
    times_list = [float(x) for x in times_list] 
    points_string = working_df['moving'] 
    points_string = points_string.iloc[0] 
    points_list = points_string.split('&') 
    points_x = [] 
    points_y = [] 
    points_z = [] 
    for point in points_list: 
     point_list = point.split(' ') 
     points_x.append(point_list[0]) 
     points_y.append(point_list[1]) 
     points_z.append(point_list[2]) 

    #get corresponding positions for HPAC times, 
    #since there could be mismatches 

    points_x = np.cumsum([float(x) for x in points_x]) 
    points_y = np.cumsum([float(x) for x in points_x]) 
    points_z = np.cumsum([float(x) for x in points_x]) 

    x_interp = np.interp(output_time_list,times_list,points_x).tolist() 
    y_interp = np.interp(output_time_list,times_list,points_y).tolist() 
    z_interp = np.interp(output_time_list,times_list,points_z).tolist() 

    working_df.loc[:,('x_movement')] = x_interp 
    working_df.loc[:,('y_movement')] = y_interp 
    working_df.loc[:,('z_movement')] = z_interp 

    working_df.loc[:,'x_pos'] = working_df.apply(set_x_vel, axis = 1) 
    working_df.loc[:,'y_pos'] = working_df.apply(set_y_vel, axis = 1) 
    working_df.loc[:,'z_pos'] = working_df.apply(set_z_vel, axis = 1) 

    return(working_df) 

내 실제 데이터 세트를 실행하는 데는 약 20 분이 걸립니다. DataFrame에서 간단하게 groupby.apply 람다 호출을하면 단 몇 초만 걸립니다. 대신 루프의

답변

1

, 당신은 groupby 및 함수 호출로 apply를 사용할 수 있습니다

df = df.groupby('ID').apply(set_group_positions) 
+0

도현은 ... 이것이 내가 시도한 최초의 일이라고 맹세 한 수 :) 감사합니다. – Docuemada

+0

괜찮습니다! 다행히 도울 수있어. – ASGM

관련 문제