Как преобразовать комплексные числа в амплитуду и угол с несколькими столбцами в панде dataframe, Python3? - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть фрейм данных df1

import pandas as pd

df1 = {'f': [1e-6, 2],
       'I1': [1.+0j, 2+1j],
       'U2': [50.+0j, 40+4j]}
df1 = pd.DataFrame(df1).set_index('f')

Я хочу преобразовать его в df2, где 2 столбца 'I1' и 'U2' станут 4 столбцами: 'I1_abs', 'I1_angle', 'U2_abs' и 'U2_angle'.

В моем реальном приложении количество столбцов в кадре данных может быть различным для разных сценариев.Не могли бы вы показать мне, как это сделать быстро?Спасибо.

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

Использование numpy.abs и numpy.imag работа с 2d arrays - циклы не нужны:

arr = df1.values
df1 = pd.DataFrame(np.abs(arr), 
                   columns=df1.columns, 
                   index=df1.index).add_suffix('_abs')
df2 = pd.DataFrame(np.angle(arr), 
                   columns=df1.columns, 
                   index=df1.index).add_suffix('_angle')

df = pd.concat([df1, df2], axis=1)
print (df)
            I1_abs     U2_abs  I1_abs_angle  U2_abs_angle
f                                                        
0.000001  1.000000  50.000000      0.000000      0.000000
2.000000  2.236068  40.199502      0.463648      0.099669

Более быстрое решение должно быть объединение массивов вnumpy:

arr = df1.values
a = np.hstack((np.abs(arr), np.angle(arr)))
cols = np.concatenate((df1.columns + '_abs', df1.columns + '_angle')) 
df2 = pd.DataFrame(a, columns=cols, index=df1.index)
print (df2)
            I1_abs     U2_abs  I1_angle  U2_angle
f                                                
0.000001  1.000000  50.000000  0.000000  0.000000
2.000000  2.236068  40.199502  0.463648  0.099669

Производительность :

#sample - (20000 rows, 20 columns)
df1 = pd.concat([df1] * 10, ignore_index=True, axis=1)
df1 = pd.concat([df1] * 10000, ignore_index=True)

In [177]: %%timeit
     ...: arr = df1.values
     ...: df = pd.concat([pd.DataFrame(np.abs(arr),columns=df1.columns,index=df1.index).add_suffix('_abs'), pd.DataFrame(np.angle(arr), columns=df1.columns, index=df1.index).add_suffix('_angle')], axis=1)
     ...: 
26.8 ms ± 893 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [178]: %%timeit
     ...: arr = df1.values
     ...: a = np.hstack((np.abs(arr), np.angle(arr)))
     ...: df1.columns = df1.columns.astype(str)
     ...: cols = np.concatenate((df1.columns + '_abs', df1.columns + '_angle')) 
     ...: df2 = pd.DataFrame(a, columns=cols, index=df1.index)
     ...: 
21.5 ms ± 172 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [179]: %%timeit
     ...: result = pd.concat([df1.applymap(abs).add_suffix('_abs'),df1.applymap(np.angle).add_suffix('_angle')], axis=1)
     ...: 
2.24 s ± 59.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
0 голосов
/ 08 декабря 2018

IIUC

result = pd.concat([
             df1.applymap(abs).add_suffix('_abs'),
             df1.applymap(np.angle).add_suffix('_angle')
             ], axis=1)

даст вам

>>> result
            I1_abs     U2_abs  I1_angle  U2_angle
f                                                
0.000001  1.000000  50.000000  0.000000  0.000000
2.000000  2.236068  40.199502  0.463648  0.099669
0 голосов
/ 08 декабря 2018

Вы можете использовать np.absolute и np.angle для этого:

df1[['I1_abs', 'U2_abs']] = df1[['I1', 'U2']].apply(lambda x: np.absolute(x))
df1[['I1_img', 'U2_img']] = df1[['I1', 'U2']].apply(lambda x: np.imag(x))

df1
              I1      U2         I1_abs      U2_abs   I1_img    U2_img
f                       
0.000001    (1+0j)  (50+0j)     1.000000    50.000000   0.0     0.0
2.000000    (2+1j)  (40+4j)     2.236068    40.199502   1.0     4.0

Если вы хотите новый фрейм данных:

df2 = pd.DataFrame(index = df1.index)
df2[['I1_abs', 'U2_abs']] = np.absolute(df1[['I1', 'U2']])
df2['I1_angle'] = np.angle(df1['I1'])
df2['U2_angle'] = np.angle(df1['U2'])
df2

             I1_abs      U2_abs     I1_angle    U2_angle
f               
0.000001    1.000000    50.000000   0.000000    0.000000
2.000000    2.236068    40.199502   0.463648    0.099669
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...