当前位置: 首页 > 知识库问答 >
问题:

如何使用apply一次创建多个列?

祁均
2023-03-14

考虑这个例子

import pandas as pd
import numpy as np

df = pd.DataFrame({'var1' : [1,2,3,4],
                   'var2' : ['a','b','c','d']})
df
Out[100]: 
   var1 var2
0     1    a
1     2    b
2     3    c
3     4    d

我有一个函数,它以var1作为输入,并返回三个值,我想存储到三个不同的变量。下面的似乎工作正确

    def myfunc(var):
        return [['small list'], var + 2, ['another list']]
    
    df.var1.apply(lambda x: myfunc(x))
    Out[101]: 
    0    [[small list], 3, [another list]]
    1    [[small list], 4, [another list]]
    2    [[small list], 5, [another list]]
    3    [[small list], 6, [another list]]
    Name: var1, dtype: object

然而,当我试图创建相应的变量时,我得到了一个错误

df[['my small list', 'my numeric', 'other list']]  = df.var1.apply(lambda x: myfunc(x))
ValueError: Must have equal len keys and value when setting with an iterable

你怎么认为?

我曾经在pandas apply()的返回多列中使用伟大的zip解决方案,但在当前的pandas1.2中,此解决方案不再有效

谢谢!

共有3个答案

黄涵畅
2023-03-14

使用这个stackoverflow问题中的方法,您只需要拆分来自df的pandas系列对象。var1。将(myfunc)应用到列中。

我所做的是:

df[['out1','out2','out3']]=pd。数据帧(df['var1'].apply(myfunc).to_list())

如您所见,这不会覆盖DataFrame,只是将结果列分配给DataFrame中的新列。

应用方法后的数据帧:

   var1 var2          out1  out2            out3
0     1    a  [small_list]     3  [another_list]
1     2    b  [small_list]     4  [another_list]
2     3    c  [small_list]     5  [another_list]
3     4    d  [small_list]     6  [another_list]
郑星雨
2023-03-14

zip方法似乎仍然可以正常工作:

import pandas as pd
import numpy as np

df = pd.DataFrame({'var1' : [1,2,3,4],
                   'var2' : ['a','b','c','d']})

def myfunc(var):
    return [['small list'], var + 2, ['another list']]

df['my small list'], df['my numeric'], df['other list'] = zip(*df.var1.apply(lambda x: myfunc(x)))

从应用()返回多个列

真正奇怪的是内部列表是如何被强制转换成元组的。从实验来看,外部类型是list类型似乎很重要。

要强制内部列表保留列表,我必须执行以下操作:

df['my small list'], df['my numeric'], df['other list'] = (list(row) for row in zip(*df.var1.apply(lambda x: myfunc(x))))
堵昊焱
2023-03-14

返回序列可能是最可读的解决方案。

def myfunc(var):
    return pd.Series([['small list'], var + 2, ['another list']])

df[['my small list', 'my numeric', 'other list']]  = df.var1.apply(lambda x: myfunc(x))

但是,对于较大的数据帧,您应该选择zip或数据帧方法。

import pandas as pd # 1.2.2
import perfplot

def setup(n):
    return pd.DataFrame(dict(
        var1=list(range(n))
    ))
 
def with_series(df):
    def myfunc(var):
        return pd.Series([['small list'], var + 2, ['other list']])
    out = pd.DataFrame()
    out[['small list', 'numeric', 'other list']] = df.var1.apply(lambda x: myfunc(x))

def with_zip(df):
    def myfunc(var):
        return [['small list'], var + 2, ['other list']]
    out = pd.DataFrame()
    out['small list'], out['numeric'], out['other list'] = list(zip(*df.var1.apply(lambda x: myfunc(x))))

def with_dataframe(df):
    def myfunc(var):
        return [['small list'], var + 2, ['other list']]
    out = pd.DataFrame()
    out[['small list', 'numeric', 'other list']] = pd.DataFrame(df.var1.apply(myfunc).to_list())


perfplot.show(
    setup=setup,
    kernels=[
        with_series,
        with_zip,
        with_dataframe,
    ],
    labels=["series", "zip", "df"],
    n_range=[2 ** k for k in range(20)],
    xlabel="len(df)",
    equality_check=None,
)
 类似资料:
  • 我在代理“客户”群体中用Anylogic创建了一个时间表,客户必须创建订单并将其发送到“终端”。每天,每个客户必须发送到终端的订单量都是不同的。我想一次创建多个订单(每天,即计划中的开始列),我想创建的金额是计划中的值列。如何做到这一点? 正如您在下面看到的,现在每天只创建一个订单(以金额为参数),但我想在那一天/那一刻创建这个订单量。谢谢您的帮助! 日程数据如下所示:

  • 问题内容: 下面的代码通过SSH在一台计算机上运行grep并打印结果: 我如何一次将5台机器全部置入grep(这样就不会造成重大延迟),而不是将所有这些都放入5个变量中并全部打印出来。 问题答案: 您需要将调用放在单独的线程(或进程中,但这可能会过大),这反过来又要求代码位于函数中(无论如何,这是一个好主意:模块的顶部没有大量代码水平)。 例如: If you had many more than

  • 问题内容: 我需要一次创建多个表。我很难找出正确的方法来完成此任务。目前,我的脚本如下所示: 显然,这是行不通的,并且不会创建任何表。有一种简单的方法可以一次创建多个表吗? 问题答案: MySQL变得令人困惑,因为您没有划定查询范围。在第一条语句后添加分号: 另外,根据Heredoc文档,请确保位于行的开头, 没有其他字符,除了分号外 。 鉴于上述方法似乎无效,请尝试以下代码: 您 可以 使用(M

  • 问题内容: 我有这个,在设定的总数时我得到一个错误。为什么我不能多次访问CTE? 问题答案: A基本上是一次性视图。它只保留一个语句,然后自动消失。 您的选择包括: 重新定义第二次。从定义的末尾到您的之前,这就像复制粘贴一样简单。 将结果放入表格或变量中 将结果具体化为真实表并引用 稍微更改一下即可,只需从您的CTE: 。

  • 我想创建单独的日志文件,一个用于信息,另一个用于调试,我正在使用下面的log4j.property文件,请建议如何修改不同文件中的两级日志记录, 我想请求请发送我更新的属性文件而不是给我搜索或探索的指针,因为我已经花了3-4个小时在Google和StackOverflow上搜索这个解决方案, 提前道谢。

  • 问题内容: 我有两列的熊猫数据框。我需要在不影响第二列的情况下更改第一列的值,并只更改第一列的值即可获取整个数据帧。如何使用大熊猫应用程序? 问题答案: 给定一个示例数据框为: 您想要的是: 返回: