通过从不同的数据帧中获取值并对其执行一些数学运算来创建新的pandas数据帧

时间:2017-01-11 12:28:20

标签: python pandas dataframe

假设我有一个包含16列和大约1000行的pandas数据帧, 格式是这样的

$scope.starttime = new Date(1970, 0, 1, 0, 0, 0);
$scope.starttime = '00:00;
$scope.starttime[1] = new Date(1970, 0, 1, 0, 0, 0);

现在我需要制作另一个包含32列的pandas数据帧:

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

其中每列的值需要乘以一个特定的数学常数,该常数取决于列号(扇区号):

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 ...

因此,原始pandas数据帧(sec01-sec16)中的每一列都需要转换为两列(x_sec01,y_sec01),并且必须乘以它的因子取决于sector_number值。

目前我正在使用此函数并为for循环中的每一行调用此函数,这需要花费太多时间。

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

2 个答案:

答案 0 :(得分: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')

剩下要做的就是重命名列。

答案 1 :(得分: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