首页 > 解决方案 > 基于多索引级别在 DataFrame 上运行函数并将其附加到新列

问题描述

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

现在我找不到如何为每个质量分离运行 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

标签: python-3.xpandas

解决方案


您需要对从 构建的多索引进行分组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()会得到一个Seriesn4,然后可以根据需要改变你的 fft 函数的实现。

的返回值fft_two()可以分配给一个新的列,pfi或者DataFrame可以基于groupby()返回的键元组和系列创建一个新的列。


推荐阅读