Python 是否有更快的方法生成此数据帧?

Python 是否有更快的方法生成此数据帧?,python,pandas,Python,Pandas,我有两个数据帧s和sk,大约有1M个元素,我需要从中生成一个新的数据帧df,其中: df.iloc[i] = s.iloc[f(i)] / sk.iloc[g(i)] 其中f和g是返回整数的函数 目前我正在做: data = [] for i in range(s.shape[0])): data.append(s.iloc[f(i)] / sk.iloc[g(i)]) df = pd.DataFrame(data, columns=s.columns) 但这似乎很慢。大约需要5

我有两个数据帧s和sk,大约有1M个元素,我需要从中生成一个新的数据帧df,其中:

df.iloc[i] = s.iloc[f(i)] / sk.iloc[g(i)] 
其中f和g是返回整数的函数

目前我正在做:

data = []
for i in range(s.shape[0])):
    data.append(s.iloc[f(i)] / sk.iloc[g(i)])

df = pd.DataFrame(data, columns=s.columns)
但这似乎很慢。大约需要5分钟,数据帧有9个浮点列

只有100万个分区,所以5分钟似乎低于标准。所有的时间似乎都花在迭代s和sk上,所以我想知道是否有一种快速构建s[f]和sk[g]的方法

编辑

f和g是与之类似的简单函数

def f(i): return math.ceil(i / 23)
def g(i): return math.ceil(i / 23) + ((i - 1) % 23)

你的函数很容易矢量化

正如@Wen所指出的,我们可以通过编写一个只计算一次上限的包装来进一步优化这一点

def wrapper(i, a, b):
    cache_ceil = np.ceil(i / 23).astype(int)
    fidx = cache_ceil
    gidx = cache_ceil + ((i - 1) % 23)
    return a.iloc[fidx].to_numpy() / b.iloc[gidx].to_numpy()
索引对齐在这里也不利于您。如果您确实希望对两个结果进行元素分割,请在分割前下拉到numpy:

s.iloc[f_vec(idx)].to_numpy() / sk.iloc[g_vec(idx)].to_numpy()
现在来测试一下速度

设置

演出


你的函数很容易矢量化

正如@Wen所指出的,我们可以通过编写一个只计算一次上限的包装来进一步优化这一点

def wrapper(i, a, b):
    cache_ceil = np.ceil(i / 23).astype(int)
    fidx = cache_ceil
    gidx = cache_ceil + ((i - 1) % 23)
    return a.iloc[fidx].to_numpy() / b.iloc[gidx].to_numpy()
索引对齐在这里也不利于您。如果您确实希望对两个结果进行元素分割,请在分割前下拉到numpy:

s.iloc[f_vec(idx)].to_numpy() / sk.iloc[g_vec(idx)].to_numpy()
现在来测试一下速度

设置

演出


fi返回什么?f和g是什么?尝试将f和g矢量化,您的问题就可以很容易地解决。请参见上文,我已经更新了问题:是什么让您认为只有10万行输出?索引对齐将破坏您的输出。fi返回什么?f和g是什么?尝试将f和g矢量化,您的问题将很容易解决。请参见上文,我更新了问题是什么让您认为只有1000万行输出?索引对齐会弄乱您的输出。一个小小的增强,因为f和g共享同一部分np.ceili/23.astypeint,我们可以调用它一次吗?只是为了完美!你花了5分钟到5秒。谢谢。@WeNYoBen说得很好,更新了答案,添加了一个包装器,只计算了一次。@user3483203很好的一个:-一个小增强,因为f和g共享同一部分np.ceili/23.astypeint,我们能称它一次吗?只是为了完美!你花了5分钟到5秒。谢谢。@WeNYoBen说得好,更新了答案,添加了一个包装器,只计算一次。@user3483203很好:-
%timeit s.iloc[f_vec(idx)].to_numpy() / sk.iloc[g_vec(idx)].to_numpy()
265 ms ± 5.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit wrapper(idx, s, sk)
200 ms ± 3.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)