我有一个包含以下信息的数据框:
filename val1 val2
t
1 file1.csv 5 10
2 file1.csv NaN NaN
3 file1.csv 15 20
6 file2.csv NaN NaN
7 file2.csv 10 20
8 file2.csv 12 15
我想根据索引插入数据框中的值,但仅限于每个文件组。
要进行插值,我通常会这样做
df = df.interpolate(method="index")
分组,我做
grouped = df.groupby("filename")
我希望插值数据框看起来像这样:
filename val1 val2
t
1 file1.csv 5 10
2 file1.csv 10 15
3 file1.csv 15 20
6 file2.csv NaN NaN
7 file2.csv 10 20
8 file2.csv 12 15
NaN在t = 6时仍然存在,因为它们是file2组中的第一项。
我怀疑我需要使用"申请"但是还没有能够弄清楚到底是怎么...
grouped.apply(interp1d)
...
TypeError: __init__() takes at least 3 arguments (2 given)
任何帮助都将不胜感激。
答案 0 :(得分:8)
>>> df.groupby('filename').apply(lambda group: group.interpolate(method='index'))
filename val1 val2
t
1 file1.csv 5 10
2 file1.csv 10 15
3 file1.csv 15 20
6 file2.csv NaN NaN
7 file2.csv 10 20
8 file2.csv 12 15
答案 1 :(得分:1)
我也碰到了这个。您可以使用apply
,而不是使用transform
,如果您拥有1000个组,则可以将运行时间减少25%以上:
import numpy as np
import pandas as pd
np.random.seed(500)
test_df = pd.DataFrame({
'a': np.random.randint(low=0, high=1000, size=10000),
'b': np.random.choice([1, 2, 4, 7, np.nan], size=10000, p=([0.2475]*4 + [0.01]))
})
试验:
%timeit test_df.groupby('a').transform(pd.DataFrame.interpolate)
输出:566 ms ± 27.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit test_df.groupby('a').apply(pd.DataFrame.interpolate)
输出:788 ms ± 10.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit test_df.groupby('a').apply(lambda group: group.interpolate())
输出:787 ms ± 17.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit test_df.interpolate()
输出:918 µs ± 16.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
与完整数据框架上interpolate
的完全向量化调用相比,您仍会看到运行时间显着增加,但我不认为您可以在pandas中做得更好。
答案 2 :(得分:0)
考虑到上述方法的运行时间较长,我建议使用for循环和interpolate(),它不超过几行代码,但速度要快得多。
for i in range(len(df.filename.unique())):
mask = df.loc[:,'filename']==df.filename.unique()[i]
df[mask]=dfs[mask].interpolate(method='index')