更快地遍历一个 DataFrame 的行以将列添加到第二个 DataFrame

如何解决更快地遍历一个 DataFrame 的行以将列添加到第二个 DataFrame

我正在尝试找到一种更快的方法,将函数多次应用于 DataFrame 中的一组数据。

我有两个数据帧:

  1. Parameters:函数的每个参数有一列,每一行是一个特定的参数集。还有一列为每个集合提供了唯一的名称
  2. 原始数据:将原始数据放在一列中

对于每组参数,我想用“func”的结果向原始DataFrame添加一列,并将列名设置为参数集名称

目前我正在遍历参数 DataFrame 的行,但我觉得有更好的方法来做到这一点。

我正在尝试查看是否有矢量化解决方案,但到目前为止,我使用两个 DataFrame 都没有成功。

我已经尝试在这文章中遵循 cs95 的回答,但几乎所有矢量化或列表推导式的示例都只处理单个 DataFrame: How to iterate over rows in a DataFrame in Pandas

有没有更好的方法来做到这一点?

我觉得我可能遗漏了一些明显的东西。

import pandas as pd

def func(data,a,b,c):
    return data["original"] + a + b * c


parameters = pd.DataFrame(
    {
        "name": ["set_1","set_2","set_3"],"a": [1,2,3],"b": [4,5,6],"c": [7,8,9],}
)

data = pd.DataFrame({"original": [10,11,12,13,14,15]})

for i,row in parameters.iterrows():
    data[row["name"]] = func(data,row["a"],row["b"],row["c"])

    Inputs:
    
Parameters DataFrame:
    name  a  b  c
0  set_1  1  4  7
1  set_2  2  5  8
2  set_3  3  6  9
    
Original Data DataFrame:
       original
    0        10
    1        11
    2        12
    3        13
    4        14
    5        15
    

    Output:
    
       original  set_1  set_2  set_3
    0        10     39     52     67
    2        12     41     54     69
    3        13     42     55     70
    4        14     43     56     71
    5        15     44     57     72

解决方法

不直接使用循环(apply() 中隐含)

  • 使用笛卡尔积将数据合并在一起
  • 使用 apply() 进行计算
  • 使用 pivot() 将其重塑为您想要的输出结构
df = pd.read_csv(io.StringIO("""       original
    0        10
    1        11
    2        12
    3        13
    4        14
    5        15"""),sep="\s+")

dfp = pd.read_csv(io.StringIO("""    name  a  b  c
0  set_1  1  4  7
1  set_2  2  5  8
2  set_3  3  6  9"""),sep="\s+")

# catesian product data with params
dfm = df.assign(foo=1).merge(dfp.assign(foo=1),on="foo")
# do the calc
dfm = dfm.assign(calc=dfm.apply(lambda x: x.original + x.a + x.b * x.c,axis=1))
# reshape
dfm = dfm.pivot(index="original",columns="name",values="calc").reset_index()
原文 set_1 set_2 set_3
0 10 39 52 67
1 11 40 53 68
2 12 41 54 69
3 13 42 55 70
4 14 43 56 71
5 15 44 57 72
,

您可以修改下面的代码以满足您的期望,我将第 1 行(原始 = 11)留在那里;应该很容易修改。

下面的代码避免了迭代,因为它可能很慢。它所做的是首先从参数中获取值,然后对每一列与 data['original'] 进行乘法以得到最终输出:

def func(left_df,right_df):
    right_df = right_df.copy()
    new_headers = right_df["name"].array
    right_df = (right_df["a"] + right_df["b"] * right_df["c"]).array
    right_df = dict(zip(new_headers,new))
    return left_df.assign(
        **{key: left_df["original"] + value for key,value in right_df.items()}
    )


data.pipe(func,parameters)


    original    set_1   set_2   set_3
0        10       39      52    67
1        11       40      53    68
2        12       41      54    69
3        13       42      55    70
4        14       43      56    71
5        15       44      57    72
,

按如下方式定义您的函数:

def func2(dataCol,a,b,c):
    return dataCol[:,np.newaxis] + a[np.newaxis,:] + b[np.newaxis,:] * c[np.newaxis,:]

差异:

  • 第一个参数是源数据列,而不是整个DataFrame,
  • 其余 3 个参数也是 (取自 parameters), 而不是单个值。

然后,要获得结果,请按以下方式调用:

data[parameters.name.tolist()] = func2(data.original,parameters.a,parameters.b,parameters.c)

使用 %timeit 我检查了你和我的代码的执行时间。 我的代码执行时间约为您代码的 60%。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?