python-3.x - 基于多索引级别在 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
解决方案
您需要对从 构建的多索引进行分组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()
会得到一个Series
和n
4,然后可以根据需要改变你的 fft 函数的实现。
的返回值fft_two()
可以分配给一个新的列,pfi
或者DataFrame
可以基于groupby()
返回的键元组和系列创建一个新的列。
推荐阅读
- wordpress - Wordpress 文件正在自动删除
- ios - SceneKit unproject 一个点给出了奇怪的结果
- amazon-ec2 - 使用 ansible playbook 运行 EC2 实例
- html - Angular 6 groupBy 嵌套组件
- mysql - 计算 MySQL JSON 字段中项目的出现次数
- python - 在 Django 值错误中发布数据
- php - PHP 将特殊字符输出为十六进制
- amazon-web-services - 我已经创建了 reusable-delegation-set 并希望通过 CloudFormation 将其与 HostedZone 相关联
- amazon-web-services - 收集 AWS Lambda 执行数据
- angular - 需要重新加载浏览器才能看到通知长度