2017-01-11 2 views
2

Пусть у меня есть панд dataframe с 16 колоннами и приблизительно 1000 строк, формат, как этосоздать новую панд dataframe, принимая значения из другого dataframe и perforing некоторых математических операций на нем

date_time sec01 sec02 sec03 sec04 sec05 sec06 sec07 sec08 sec09 sec10 sec11 sec12 sec13 sec14 sec15 sec16 

1970-01-01 05:54:17 8.50 8.62 8.53 8.45 8.50 8.62 8.53 8.45 8.42 8.39 8.39 8.40 8.47 8.54 8.65 8.70 
1970-01-01 05:56:55 8.43 8.62 8.55 8.45 8.43 8.62 8.55 8.45 8.42 8.39 8.39 8.40 8.46 8.53 8.65 8.71 

и Теперь нужно сделать еще панд dataframe с 32 столбцами:

x_sec01 y_sec01 x_sec02 y_sec02 x_sec03 y_sec03 x_sec04 y_sec04 x_sec05 y_sec05 x_sec06 y_sec06 x_sec07 ... 

где значения каждого столбца необходимо умножить с определенной математической константой, которая зависит от числа столбцов (номер сектора):

x = sec_data * (math.cos(math.radians(1.40625*(sector_number)))) 
y = sec_data * (math.sin(math.radians(1.40625*(sector_number)))) 

Таким образом, каждый из столбцов в исходной пандами dataframe (sec01-sec16) должен быть преобразован в две колонки (x_sec01, y_sec01) и фактор, по которому он должен быть умножен зависит от значения sector_number.

В настоящее время я использую эту функцию и вызываю ее для каждой строки в цикле for, которая занимает слишком много времени.

def sec_to_xy(sec_no,sec_data): #function to convert sector data to xy coordinate system 
    for sec_convno in range(0,32,2): 
     sector_number = (77-(sec_no-1)*2) #goes from 79 till 49 
     x = sec_data * (math.cos(math.radians(1.40625*(sector_number)))) 
     y = sec_data * (math.sin(math.radians(1.40625*(sector_number)))) 
    return(x,y) 

ответ

2

Общая идея состоит в том, чтобы складывать ваши значения, чтобы вы могли применять быстрые, векторизованные функции numpy.

# stack the dataframe 
df2 = df.stack().reset_index(level=1) 
df2.columns = ['sec', 'value'] 
# extract the sector number 
df2['sec_no'] = df2['sec'].str.slice(-2).astype(int) 

# apply numpy's vectorized functions 
import numpy as np 
df2['x'] = df2['value'] * (np.cos(np.radians(1.40625*(df2['sec_no'])))) 
df2['y'] = df2['value'] * (np.sin(np.radians(1.40625*(df2['sec_no'])))) 

На данном этапе, вот что df2 выглядит следующим образом:

     sec value sec_no   x   y 
1970-01-01 05:54:17 sec01 8.50  1 8.497440 0.208600 
1970-01-01 05:54:17 sec02 8.62  2 8.609617 0.422963 
1970-01-01 05:54:17 sec03 8.53  3 8.506888 0.627506 
1970-01-01 05:54:17 sec04 8.45  4 8.409311 0.828245 
1970-01-01 05:54:17 sec05 8.50  5 8.436076 1.040491 

Теперь поворота стола, чтобы вернуться к первоначальной форме:

df2[['sec', 'x', 'y']].pivot(columns='sec') 

Все, что осталось сделать, это переименовать столбцы.

+0

я понял первую часть, но не кажется, вторая часть это будет работать я получаю это «не может индексировать этикетка с нулевым ключом» ошибки – thirteenmac

+0

Вы имеете в виду, что стержень не работает? – IanS

+0

да, я смотрю на это прямо сейчас, извините, я очень новичок в программировании – thirteenmac

2

Вот подход с NumPy -

# Extract as float array 
a = df.values # Extract all 16 columns 
m,n = a.shape 

# Scaling array 
s = np.radians(1.40625*(np.arange(79,47,-2))) 

# Initialize output array and set cosine and sine values 
out = np.zeros((m,n,2)) 
out[:,:,0] = a*np.cos(s) 
out[:,:,1] = a*np.sin(s) 

# Transfer to a dataframe output 
df_out = pd.DataFrame(out.reshape(-1,n*2),index=df.index) 

Пожалуйста, обратите внимание, что если есть на самом деле 17 столбцов с первым столбцом, date_time, то мы должны пропустить первый столбец. Так, в самом начале, получить a со следующим шагом вместо -

a = df.ix[:,1:].values