繁体   English   中英

有没有更快的方法来生成这个 pandas dataframe?

[英]Is there a faster way to generate this pandas dataframe?

我有两个数据帧ssk大约有1M元素,我需要从中生成一个新的 dataframe df

df.iloc[i] = s.iloc[f(i)] / sk.iloc[g(i)] 

其中fg是返回整数的函数。

目前我正在做:

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 个float列)。

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

编辑

fg是简单的函数,类似于

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

您的函数很容易矢量化。


def f_vec(i):
    return np.ceil(i / 23).astype(int)

def g_vec(i):
    return (np.ceil(i / 23) + ((i - 1) % 23)).astype(int)

正如@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()

索引 alignment 在这里也对您不利。 如果您真的想要两个结果的元素除法,请在除法之前下拉到numpy

s.iloc[f_vec(idx)].to_numpy() / sk.iloc[g_vec(idx)].to_numpy()

现在来测试一下速度。

设置

a = np.random.randint(1, 10, (1_000_000, 10))
s = pd.DataFrame(a)
sk = pd.DataFrame(a)
idx = np.arange(1_000_000)

表现

%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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM