Pandas Apply Function返回两个新列

时间:2017-12-25 15:00:30

标签: python python-2.7 pandas

我有一个pandas数据框,我想使用apply函数根据现有数据生成两个新列。我收到此错误: ValueError: Wrong number of items passed 2, placement implies 1

import pandas as pd
import numpy as np

def myfunc1(row):
    C = row['A'] + 10
    D = row['A'] + 50
    return [C, D]

df = pd.DataFrame(np.random.randint(0,10,size=(2, 2)), columns=list('AB'))

df['C', 'D'] = df.apply(myfunc1 ,axis=1)

启动DF:

   A  B
0  6  1
1  8  4

期望的DF:

   A  B  C   D
0  6  1  16  56
1  8  4  18  58

6 个答案:

答案 0 :(得分:3)

根据您的最新错误,您可以通过将新列作为系列

返回来避免错误
type

答案 1 :(得分:2)

df['C','D']被视为1列而不是2.因此,对于2列,您需要切片数据框,因此请使用df[['C','D']]

df[['C', 'D']] = df.apply(myfunc1 ,axis=1)

    A  B   C   D
0  4  6  14  54
1  5  1  15  55

或者您可以使用链分配,即

df['C'], df['D'] = df.apply(myfunc1 ,axis=1)

答案 2 :(得分:1)

查询多列时添加额外的括号。

import pandas as pd
import numpy as np

def myfunc1(row):
    C = row['A'] + 10
    D = row['A'] + 50
    return [C, D]

df = pd.DataFrame(np.random.randint(0,10,size=(2, 2)), columns=list('AB'))

df[['C', 'D']] = df.apply(myfunc1 ,axis=1)

答案 3 :(得分:1)

它对我有用:

def myfunc1(row):
    C = row['A'] + 10
    D = row['A'] + 50
    return C, D

df = pd.DataFrame(np.random.randint(0,10,size=(2, 2)), columns=list('AB'))

df[['C', 'D']] = df.apply(myfunc1, axis=1, result_type='expand')
df

添加:==>> result_type='expand',

问候!

答案 4 :(得分:0)

请注意,已接受的答案https://ys-l.github.io/posts/2015/08/28/how-not-to-use-pandas-apply/的内存消耗巨大且速度很慢!

使用此处显示的建议,正确答案如下:

gradle.properties

答案 5 :(得分:0)

我相信可以在不使用 for 循环的情况下获得与 @Federico Dorato 答案相似的结果。返回一个列表而不是一个系列,并使用 lambda-apply + to_list() 来扩展结果。

它是更简洁的代码,并且在 10,000,000 行的随机 df 上执行得同样或更快。

费德里科的代码

run_time = []

for i in range(0,25):
    df = pd.DataFrame(np.random.randint(0,10000000,size=(2, 2)), columns=list('AB'))
    def run_loopy(df):
        Cs, Ds = [], []
        for _, row in df.iterrows():
            c, d, = myfunc1(row['A'])
            Cs.append(c)
            Ds.append(d)
        return pd.Series({'C': Cs,
                        'D': Ds})

    def myfunc1(a):
        c = a / 10
        d = a + 50
        return c, d

    start = time.time()
    df[['C', 'D']] = run_loopy(df)
    end = time.time()

    run_time.append(end-start) 
print(np.average(run_time)) # 0.001240386962890625

使用 lambda 和 to_list

run_time = []

for i in range(0,25):
    df = pd.DataFrame(np.random.randint(0,10000000,size=(2, 2)), columns=list('AB'))

    def myfunc1(a):
        c = a / 10
        d = a + 50
        return [c, d]

    start = time.time()
    df[['C', 'D']] = df['A'].apply(lambda x: myfunc1(x)).to_list()
    end = time.time()
run_time.append(end-start)
print(np.average(run_time)) #output 0.0009996891021728516