根据mulitindex级别在DataFrame上运行函数,并将其附加到新列

时间:2019-03-28 11:21:04

标签: python-3.x pandas

我有一个来自不同位置的不同质量液滴的时间历史数据集。 我加载了数据,并根据质量和位置通过多个索引对数据进行了结构化。 现在,我想进行傅立叶变换,并将幅度和频率附加到新的列中。

就目前而言,我找不到如何针对每个质量分离运行FFT方法

我试图调用一列并将其放在我的函数中。 结果将显示在新列中。

现在出现两个问题:

1。)函数的结果与时间信号的长度不同,我想用Nan填充其余部分。

2。)如果我得到的结果具有相同的长度,则它似乎来自整列,而不是分别来自每个('loc','mass')

import pandas as pd
import numpy as np

def fft(a,n):
    b =[]
    for i in range(len(a)//2):
        b.append(a[i]+a[-i])
    return b,n

def fft_two(a,n):
    b = sum(a)
    return a*n+b,n    

col = ['loc', 'mass', 'time', 'signal']

loc = ['loc1'] * 10+['loc2'] * 10
mass = (['10kg']*5+['20kg']*5)*2
time = list(range(0,5))*4
ampl = list(np.random.rand(5))*4

a= [loc,mass,time,ampl]
pf = pd.DataFrame(a, index=col).T

pfi=pf.set_index(['loc','mass'])

pfi['ampl'], pfi['freq']= fft_two(pfi['signal'],n=4)

现在我知道了

        time    signal      ampl        freq
loc mass                
loc1    10kg    0   0.781256    14.0339     4
    10kg    1   0.553895    13.1244     4
    10kg    2   0.154589    11.5272     4
    10kg    3   0.546888    13.0964     4
    10kg    4   0.690581    13.6712     4
    20kg    0   0.781256    14.0339     4
    20kg    1   0.553895    13.1244     4
    20kg    2   0.154589    11.5272     4
    20kg    3   0.546888    13.0964     4
    20kg    4   0.690581    13.6712     4
loc2    10kg    0   0.781256    14.0339     4
    10kg    1   0.553895    13.1244     4
    10kg    2   0.154589    11.5272     4
    10kg    3   0.546888    13.0964     4
    10kg    4   0.690581    13.6712     4
    20kg    0   0.781256    14.0339     4
    20kg    1   0.553895    13.1244     4
    20kg    2   0.154589    11.5272     4
    20kg    3   0.546888    13.0964     4
    20kg    4   0.690581    13.6712     4

我想要一个针对每个特定位置和质量的结果:

        time    signal      ampl        freq
loc mass                
loc1    10kg    0   0.781256    ampl1       freq1
        10kg    1   0.553895    ampl1       freq1
        10kg    2   0.154589    ampl1       freq1
        10kg    3   0.546888    nan         nan
        10kg    4   0.690581    nan         nan
        20kg    0   0.781256    ampl2       freq2
        20kg    1   0.553895    ampl2       freq24
        20kg    2   0.154589    ampl2       freq2
        20kg    3   0.546888    nan         nan
        20kg    4   0.690581    nan         nan
loc2    10kg    0   0.781256    ampl3       freq3
        10kg    1   0.553895    ampl3       freq3
        10kg    2   0.154589    ampl3       freq3
        10kg    3   0.546888    nan         nan
        10kg    4   0.690581    nan         nan
        20kg    0   0.781256    ampl4       freq4
        20kg    1   0.553895    ampl4       freq4
        20kg    2   0.154589    ampl4       freq4
        20kg    3   0.546888    nan         nan
        20kg    4   0.690581    Nan         nan

1 个答案:

答案 0 :(得分:0)

您需要对根据pf构建的多索引进行分组。

pfi=pf.set_index(['loc','mass'])
for grp in pfi.groupby(["loc", "mass"]):
    print("group {} {}".format(*grp[0]))
    print("{}".format(grp[1]))

分组后,就可以apply()将功能加入这些分组了。

pfi.groupby(["loc", "mass"])["signal"].apply(fft_two)

但是您希望参数化fft_two,为此,您可以重新定义fft_two以接受来自apply()调用的参数。

def fft_two(a,args):
    n = args[0]
    b = sum(a)
    return a*n+b,n
pfi.groupby(["loc", "mass"])["signal"].apply(fft_two,args=(4,))

fft_two()内,您将得到Seriesn的4,然后可以根据需要更改fft函数的实现。

可以将fft_two()的返回值分配给pfi的新列,也可以基于返回的DataFrame键元组和序列创建新的groupby()