【问题标题】:How to vectorize dynamically sized numpy arrays in pandas如何在熊猫中对动态大小的numpy数组进行矢量化
【发布时间】:2020-09-04 13:29:03
【问题描述】:

目前,我在我的数据框上使用apply 方法来创建一个包含可变大小列表的计算列(取决于length 列中的值)。

有没有办法使用 pandas 更有效地创建包含可变大小列表的列?

import pandas as pd
import numpy as np

df = pd.DataFrame({'a': [1, 2, 3, 4, 5], 'b': [
                  6, 7, 8, 9, 0], 'length': [3, 5, 7, 9, 3]})
df['computed'] = df.apply(
    lambda x: np.array([x['a'], x['b']] + [x['b'] + i for i in range(1, x['length'] - 1)]), axis=1)

所需的输出(适用于上面的代码,但速度很慢):

   a  b  length                            computed
0  1  6       3                           [1, 6, 7]
1  2  7       5                    [2, 7, 8, 9, 10]
2  3  8       7           [3, 8, 9, 10, 11, 12, 13]
3  4  9       9  [4, 9, 10, 11, 12, 13, 14, 15, 16]
4  5  0       3                           [5, 0, 1]

【问题讨论】:

  • 我认为我们没有更好的方法来创建列表类型列..
  • 在 a 和 b 中它们都是正数吗?
  • @Divakar 不一定。那会有什么不同吗?长度至少为 2,因为模式是 [a, b, b+1, ..., b + length - 2]。
  • 当我看到长度不同的列表时,我认为是 Python 迭代,而不是“矢量化”。真正的numpy 向量化适用于矩形数组,而不是参差不齐的数组(或列表数组)。

标签: python pandas numpy dataframe apply


【解决方案1】:

试试这个,

df['computed']= [[a]+[b]+list(np.arange(b+1, length)) for a, b, length in zip(df.a, df.b, (df.b) + df.length-1)]

o/p:

   a  b  length                            computed
0  1  6       3                           [1, 6, 7]
1  2  7       5                    [2, 7, 8, 9, 10]
2  3  8       7           [3, 8, 9, 10, 11, 12, 13]
3  4  9       9  [4, 9, 10, 11, 12, 13, 14, 15, 16]
4  5  0       3                           [5, 0, 1]

【讨论】:

  • 这可行,但仍有一个 for 循环,这是我尽可能避免的。感谢您的帮助。
  • 这是一个列表理解。它提高了性能并且比 for 循环更好。
【解决方案2】:

不确定这是否是您要找的,但如果速度太慢,您可以随时尝试多处理:

import pandas as pd
import numpy as np
from multiprocessing import Pool

def parallelize(df, func, n_cores=4):
    df_split = np.array_split(df, n_cores)
    pool = Pool(n_cores)
    df = pd.concat(pool.map(func, df_split))
    pool.close()
    pool.join()
    return df

def func(df):
    df['computed'] = df.apply(lambda x: np.array([x['a'], x['b']] + [x['b'] + i for i in range(1, x['length'] - 1)]), axis=1)
    return df

df = pd.DataFrame({'a': [1, 2, 3, 4, 5], 'b': [6, 7, 8, 9, 0], 'length': [3, 5, 7, 9, 3]})
df = parallelize(df, func)

(对于较小的 length 值,它的效率将低于您的原始代码)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    相关资源
    最近更新 更多