如何遍历数据框中的列并同时更新两个新列?

时间:2016-07-20 18:29:53

标签: python numpy pandas dataframe multiple-columns

我知道我可以在数据框中添加一列,并将其值更新为函数返回的值,如下所示:

df=pd.DataFrame({'x':[1,2,3,4]})

def square(x):
    return x*x

df['x_squared'] = [square(i) for i in df['x']]

但是,我遇到的问题是实际函数返回两个项目,我想将这两个项目放在两个不同的新列中。我在这里写了一个伪代码来更清楚地描述我的问题:

df=pd.DataFrame({'x':[1,2,3,4]})

def squareAndCube(x):
    return x*x, x*x*x

#below is a pseudo-code
df['x_squared'], df['x_cubed'] = [squareAndCube(i) for i in df['x']]

上面的代码给出了一条错误消息,说明"太多的值无法打开"。 那么,我该如何解决这个问题呢?

3 个答案:

答案 0 :(得分:3)

您可以采用矢量化方式,如此 -

df['x_squared'], df['x_cubed'] = df.x**2,df.x**3

或者使用那个自定义函数,就像这样 -

df['x_squared'], df['x_cubed'] = squareAndCube(df.x)

回到你的循环案例,在作业的右侧,你有:

In [101]: [squareAndCube(i) for i in df['x']]
Out[101]: [(1, 1), (4, 8), (9, 27), (16, 64)]

现在,在左侧,您有df['x_squared'], df['x_cubed'] =。因此,它期望所有行的平方数作为第一个输入赋值。从上面显示的列表中,第一个元素不是,它实际上是第一行的正方形和立方体。因此,解决方法是转换"转置"列表并指定为新列。因此,修复将是 -

In [102]: L = [squareAndCube(i) for i in df['x']]

In [103]: map(list, zip(*L))  # Transposed list
Out[103]: [[1, 4, 9, 16], [1, 8, 27, 64]]

In [104]: df['x_squared'], df['x_cubed'] = map(list, zip(*L))

热爱NumPy broadcasting

df['x_squared'], df['x_cubed'] = (df.x.values[:,None]**[2,3]).T

答案 1 :(得分:1)

这适用于正数。思考如何概括,但这种解决方案的简洁让我心烦意乱。

df = pd.DataFrame(range(1, 10))
a = np.arange(1, 4).reshape(1, -1)

np.exp(np.log(df).dot(a))

enter image description here

答案 2 :(得分:0)

如何使用df.loc这样:

df=pd.DataFrame({'x':[1,2,3,4]})

def square(x):
    return x*x

df['x_squared'] = df['x_cubed'] = None
df.loc[:, ['x_squared', 'x_cubed']] = [squareAndCube(i) for i in df['x']]

给出

   x  x_squared  x_cubed
0  1          1        1
1  2          4        8
2  3          9       27
3  4         16       64

非常接近您所拥有的内容,但df.loc需要存在列才能生效。

对于没有经验的人,df.loc有两个参数,一个你想要处理的行列表 - 在这种情况下:表示所有这些参数,列表列为['x_squared', 'x_cubed']